24 KiB
API Specification for Partner Integration
Overview
This document defines the REST API endpoints for the multi-partner integration system, including enhanced job assignment, partner management, and data synchronization capabilities.
Base URL
Production: https://api.agmission.com/v1
Staging: https://staging-api.agmission.com/v1
Development: http://localhost:3000/api
Authentication
All API endpoints require authentication using Bearer tokens:
Authorization: Bearer <jwt_token>
Partner Management APIs
List All Partners
GET /api/partners
Response:
{
"partners": [
{
"_id": "partner_id_1",
"code": "satloc",
"name": "Satloc",
"description": "Satloc partner account for managing SatLoc customer accounts",
"active": true,
"capabilities": [
"job_upload",
"data_download",
"real_time_sync"
],
"apiVersion": "v2.1",
"status": "online",
"lastHealthCheck": "2025-07-18T10:30:00Z",
"createdAt": "2025-01-15T08:00:00Z",
"updatedAt": "2025-07-18T10:30:00Z"
}
],
"total": 1
}
Get Partner Details
GET /api/partners/{id}
Path Parameters:
id(string, required): The unique identifier of the partner
Response:
{
"_id": "partner_id_1",
"code": "satloc",
"name": "Satloc",
"description": "Satloc integration for precision agriculture",
"active": true,
"capabilities": ["job_upload", "data_download", "real_time_sync"],
"apiConfig": {
"baseUrl": "https://api.satloc.com",
"version": "v2.1",
"rateLimit": {
"requestsPerSecond": 10,
"burstLimit": 50
}
},
"integrationSettings": {
"syncInterval": 60000,
"batchSize": 100,
"maxRetries": 3
},
"monitoring": {
"status": "online",
"lastHealthCheck": "2025-07-18T10:30:00Z",
"responseTime": 250,
"errorRate": 0.02
}
}
Create Partner
POST /api/partners
Request Body:
{
"name": "New Partner",
"code": "NEWPARTNER",
"description": "Integration with new partner system",
"capabilities": ["job_upload", "data_download"],
"apiConfig": {
"baseUrl": "https://api.newpartner.com",
"version": "v1.0"
}
}
Response:
{
"_id": "new_partner_id",
"name": "New Partner",
"code": "NEWPARTNER",
"description": "Integration with new partner system",
"active": true,
"capabilities": ["job_upload", "data_download"],
"createdAt": "2025-07-18T11:00:00Z",
"updatedAt": "2025-07-18T11:00:00Z"
}
Update Partner
PUT /api/partners/{id}
Path Parameters:
id(string, required): The unique identifier of the partner
Request Body (partial updates supported):
{
"name": "Updated Partner Name",
"description": "Updated partner description",
"capabilities": ["job_upload", "data_download", "real_time_sync"]
}
Response:
{
"_id": "partner_id_1",
"name": "Updated Partner Name",
"code": "SATLOC",
"description": "Updated partner description",
"active": true,
"capabilities": ["job_upload", "data_download", "real_time_sync"],
"updatedAt": "2025-07-18T11:00:00Z"
}
Delete Partner (Soft Delete)
DELETE /api/partners/{id}
Path Parameters:
id(string, required): The unique identifier of the partner
Response:
{
"ok": true
}
Note: This endpoint performs a soft delete by setting active: false. The partner record remains in the database for audit purposes and existing relationships are preserved.
Get Partner Status
POST /api/partners/getPartnerStatus
Request Body:
{
"partner": "partner_id_1"
}
Response:
{
"partner": "satloc",
"status": "online",
"lastSync": "2025-07-18T10:30:00Z",
"activeJobs": 15,
"pendingSyncs": 2,
"metrics": {
"responseTime": {
"average": 250,
"p95": 500,
"p99": 1000
},
"errorRate": 0.02,
"successRate": 0.98,
"dataVolume": {
"uploaded": "1.2GB",
"downloaded": "850MB"
}
},
"recentErrors": [
{
"timestamp": "2025-07-18T09:45:00Z",
"operation": "data_poll",
"error": "Network timeout",
"retryAttempt": 2
}
]
}
Partner System User Management APIs
List All Partner System Users
GET /api/partners/systemUsers
Query Parameters:
partner(string, optional): Filter by partner ID
Response:
[
{
"_id": "systemuser_id_1",
"username": "customer123_satloc",
"name": "Customer 123 SatLoc Integration",
"active": true,
"partner": {
"_id": "partner_id_1",
"name": "SatLoc",
"partnerCode": "SATLOC"
},
"customer": {
"_id": "customer_id_1",
"name": "John's Farm",
"username": "johnsfarm"
},
"companyId": "36c0f342-e4e2-4fcb-b219-9cd1fad2c1ff",
"apiKey": "satloc_api_key_encrypted",
"createdAt": "2025-01-15T08:00:00Z",
"updatedAt": "2025-07-18T10:30:00Z"
}
]
Create Partner System User
POST /api/partners/systemUsers
Request Body:
{
"partnerId": "partner_id_1",
"customerId": "customer_id_1",
"username": "customer123_satloc",
"password": "secure_password",
"name": "Customer 123 SatLoc Integration",
"active": true,
"companyId": "36c0f342-e4e2-4fcb-b219-9cd1fad2c1ff",
"apiKey": "partner_api_key",
"apiSecret": "partner_api_secret",
"metadata": {
"integrationVersion": "v2.1",
"capabilities": ["job_upload", "data_sync"]
}
}
Response:
{
"_id": "systemuser_id_1",
"username": "customer123_satloc",
"name": "Customer 123 SatLoc Integration",
"active": true,
"partner": "partner_id_1",
"customer": "customer_id_1",
"companyId": "36c0f342-e4e2-4fcb-b219-9cd1fad2c1ff",
"apiKey": "satloc_api_key_encrypted",
"createdAt": "2025-07-18T10:30:00Z",
"updatedAt": "2025-07-18T10:30:00Z"
}
Get Partner System User by ID
GET /api/partners/systemUsers/{id}
Path Parameters:
id(string, required): The unique identifier of the partner system user
Response:
{
"_id": "systemuser_id_1",
"username": "customer123_satloc",
"name": "Customer 123 SatLoc Integration",
"active": true,
"partner": {
"_id": "partner_id_1",
"name": "SatLoc",
"partnerCode": "SATLOC"
},
"customer": {
"_id": "customer_id_1",
"name": "John's Farm",
"username": "johnsfarm"
},
"companyId": "36c0f342-e4e2-4fcb-b219-9cd1fad2c1ff",
"apiKey": "satloc_api_key_encrypted",
"metadata": {
"integrationVersion": "v2.1",
"capabilities": ["job_upload", "data_sync"]
},
"createdAt": "2025-01-15T08:00:00Z",
"updatedAt": "2025-07-18T10:30:00Z"
}
Update Partner System User
PUT /api/partners/systemUsers/{id}
Path Parameters:
id(string, required): The unique identifier of the partner system user
Request Body (partial updates supported):
{
"name": "Updated Customer Integration Name",
"active": false,
"apiKey": "new_encrypted_api_key",
"metadata": {
"integrationVersion": "v2.2",
"capabilities": ["job_upload", "data_sync", "real_time_monitoring"]
}
}
Response:
{
"_id": "systemuser_id_1",
"username": "customer123_satloc",
"name": "Updated Customer Integration Name",
"active": false,
"partner": "partner_id_1",
"customer": "customer_id_1",
"companyId": "36c0f342-e4e2-4fcb-b219-9cd1fad2c1ff",
"apiKey": "new_encrypted_api_key",
"metadata": {
"integrationVersion": "v2.2",
"capabilities": ["job_upload", "data_sync", "real_time_monitoring"]
},
"updatedAt": "2025-07-18T11:00:00Z"
}
Delete Partner System User (Soft Delete)
DELETE /api/partners/systemUsers/{id}
Path Parameters:
id(string, required): The unique identifier of the partner system user
Response:
{
"ok": true
}
Note: This endpoint performs a soft delete by setting active: false. The record remains in the database for audit purposes.
Get Partner Customers
GET /api/partners/customers
Query Parameters:
partnerId(string, required): The unique identifier of the partner
Description: Retrieves all customers associated with a specific partner along with their subscription package information.
Response:
[
{
"_id": "customer_id_1",
"name": "John Doe",
"email": "john@example.com",
"username": "johndoe",
"contact": "+1234567890",
"active": true,
"country": "US",
"createdAt": "2025-01-15T08:00:00Z",
"updatedAt": "2025-07-18T10:30:00Z",
"packageInfo": [
{
"packageName": "price_1Qs3w1JxyI1MWs2Te7a45wBX",
"status": "active",
"startDate": "2025-01-01T00:00:00.000Z",
"endDate": "2025-12-31T23:59:59.000Z",
"recurring": true
}
]
}
]
Test Partner System User Authentication
POST /api/partners/systemUsers/testAuth
Description: Tests authentication credentials for a partner system user by calling the partner's authentication API.
Request Body:
{
"customerId": "customer_id_1",
"partnerId": "partner_id_1",
"username": "partner_username",
"password": "partner_password"
}
Response:
{
"_id": "system_user_id",
"username": "partner_username",
"active": true,
"partner": {
"_id": "partner_id_1",
"name": "Satloc",
"partnerCode": "satloc"
},
"customer": {
"_id": "customer_id_1",
"name": "John Doe",
"username": "johndoe"
},
"companyId": "123",
"lastSyncAt": "2025-07-18T10:30:00Z",
"syncStatus": "success",
"authSuccess": true,
"partnerApiResponse": {
"authenticated": true,
"userId": "partner_user_123",
"companyId": "partner_company_123",
"sessionToken": "abc123...",
"expiresAt": "2025-07-18T14:30:00Z",
"userDetails": {
"userId": "partner_user_123",
"permissions": ["read", "write"]
}
}
}
Error Response:
{
"_id": "system_user_id",
"username": "partner_username",
"active": true,
"partner": {
"_id": "partner_id_1",
"name": "Satloc",
"partnerCode": "satloc"
},
"customer": {
"_id": "customer_id_1",
"name": "John Doe",
"username": "johndoe"
},
"authSuccess": false,
"error": "Invalid credentials",
"partnerApiResponse": null
}
Enhanced Job Assignment APIs
Assign Job to Aircraft/Partners
POST /jobs/{jobId}/assign
Request Body:
{
"dlOp": {
"type": 1,
"mapOp": {
"width": 1024,
"height": 768,
"zoom": 15
}
},
"asUsers": [
{
"uid": "internal_user_id_1", // Always use internal user IDs
"partnerType": "internal"
},
{
"uid": "internal_user_id_2", // Internal user ID, not partner system user ID
"partnerType": "satloc",
"partnerConfig": {
"aircraftId": "AC001",
"priority": "high",
"syncImmediate": true,
"customFields": {
"flightAltitude": 100,
"sprayPattern": "overlap_20"
}
}
}
],
"avUsers": [
{
"uid": "internal_user_id_3", // Internal user ID
"partnerType": "dji"
}
]
}
Response:
{
"ok": true,
"assignments": [
{
"assignmentId": "assign_123",
"userId": "user_id_1",
"partnerType": "internal",
"status": "assigned",
"syncStatus": "synced"
},
{
"assignmentId": "assign_124",
"userId": "user_id_2",
"partnerType": "satloc",
"externalJobId": "satloc_job_456",
"status": "assigned",
"syncStatus": "syncing",
"estimatedSyncTime": "2025-07-18T10:35:00Z"
}
],
"errors": [],
"summary": {
"totalAssignments": 2,
"successfulAssignments": 2,
"failedAssignments": 0,
"partnerAssignments": 1,
"internalAssignments": 1
}
}
Get Job Assignments
GET /jobs/{jobId}/assignments
Response:
{
"jobId": 123,
"assignments": [
{
"assignmentId": "assign_123",
"user": {
"_id": "user_id_1",
"name": "Aircraft 001",
"username": "AC001"
},
"partnerType": "internal",
"status": 1,
"date": "2025-07-18T09:00:00Z",
"syncState": {
"jobUpload": {
"status": "synced",
"lastSuccess": "2025-07-18T09:00:00Z"
},
"dataPolling": {
"status": "idle"
}
}
},
{
"assignmentId": "assign_124",
"user": {
"_id": "user_id_2",
"name": "Satloc Aircraft 002",
"username": "SAT002"
},
"partnerType": "satloc",
"externalJobId": "satloc_job_456",
"status": 0,
"date": "2025-07-18T09:15:00Z",
"syncState": {
"jobUpload": {
"status": "synced",
"lastSuccess": "2025-07-18T09:16:00Z"
},
"dataPolling": {
"status": "polling",
"lastAttempt": "2025-07-18T10:30:00Z",
"nextPoll": "2025-07-18T10:31:00Z"
}
},
"metrics": {
"syncDuration": 1250,
"uploadTime": 800
}
}
],
"summary": {
"total": 2,
"pending": 1,
"downloaded": 0,
"completed": 1,
"byPartner": {
"internal": 1,
"satloc": 1
}
}
}
Bulk Assign Jobs
POST /jobs/bulk-assign
Request Body:
{
"jobs": [
{
"jobId": 123,
"assignments": [
{
"uid": "user_id_1",
"partnerType": "satloc"
}
]
},
{
"jobId": 124,
"assignments": [
{
"uid": "user_id_2",
"partnerType": "dji"
}
]
}
],
"options": {
"syncImmediate": false,
"validateOnly": false
}
}
Get Available and Assigned Aircraft for Job
POST /jobs/assignments
Description: Retrieves available and assigned aircraft for a specific job, including aircraft details and assignment status.
Request Body:
{
"jobId": 123
}
Response:
{
"avUsers": [
{
"uid": "aircraft_id_1",
"name": "Sprayer 001",
"username": "SPR001",
"active": true,
"pkgActive": true,
"tailNumber": "N123AB"
},
{
"uid": "aircraft_id_2",
"name": "Helicopter 002",
"username": "HELI002",
"active": true,
"pkgActive": true,
"tailNumber": "N456CD"
}
],
"asUsers": [
{
"uid": "aircraft_id_3",
"name": "Drone 003",
"username": "DRN003",
"active": true,
"pkgActive": true,
"tailNumber": "N789EF",
"assignStatus": 1
}
]
}
Field Descriptions:
avUsers: Array of available aircraft that can be assigned to the jobasUsers: Array of aircraft already assigned to the jobtailNumber: Aircraft tail number (always present, empty string if not set)assignStatus: Assignment status for assigned aircraft (0=NEW, 1=DOWNLOADED, 2=UPLOADED)
Enhanced Job Download APIs
Get Available Jobs (Enhanced)
GET /export/newJobs
Query Parameters:
partnerType(optional): Filter by partner typeincludeMetadata(optional): Include sync metadata in response
Response:
{
"internal": [
{
"assignmentId": "assign_123",
"job": {
"_id": 123,
"name": "Field A Spraying",
"startDate": "2025-07-18T08:00:00Z",
"endDate": "2025-07-18T18:00:00Z"
},
"date": "2025-07-18T09:00:00Z"
}
],
"partners": {
"satloc": [
{
"assignmentId": "assign_124",
"job": {
"_id": 124,
"name": "Field B Application",
"startDate": "2025-07-18T10:00:00Z",
"endDate": "2025-07-18T16:00:00Z"
},
"date": "2025-07-18T09:15:00Z",
"externalJobId": "satloc_job_456",
"syncStatus": "synced",
"partnerMetadata": {
"aircraftId": "SAT002",
"priority": "high"
}
}
],
"dji": []
},
"summary": {
"totalAvailable": 2,
"internal": 1,
"partners": 1,
"lastSync": "2025-07-18T10:30:00Z"
}
}
Download Job (Enhanced)
POST /export/downloadJob
Request Body:
{
"jobId": 124,
"partnerType": "satloc",
"options": {
"format": "native", // "native" or "converted"
"includeMetadata": true,
"compressionLevel": 6
}
}
Response:
- For internal jobs: Returns existing ZIP format
- For partner jobs: Returns partner-specific format or converted format
Headers:
Content-Type: application/zip
Content-Disposition: attachment; filename="job_124_satloc.zip"
X-Partner-Type: satloc
X-External-Job-Id: satloc_job_456
X-Data-Format: native
Check Job Download Status
GET /export/jobs/{jobId}/download-status?partnerType={partnerType}
Response:
{
"jobId": 124,
"partnerType": "satloc",
"status": "ready", // "pending", "syncing", "ready", "failed"
"downloadUrl": "/export/downloadJob",
"syncMetadata": {
"lastSync": "2025-07-18T10:30:00Z",
"dataSize": 1048576,
"fileCount": 3,
"format": "satloc_v2"
},
"estimatedDownloadTime": 5000 // milliseconds
}
Data Synchronization APIs
Trigger Manual Sync
POST /sync/assignments/{assignmentId}/sync
Request Body:
{
"operation": "job_upload", // "job_upload" or "data_poll"
"priority": "high", // "low", "normal", "high"
"force": false // Force sync even if recently attempted
}
Response:
{
"syncId": "sync_789",
"assignmentId": "assign_124",
"operation": "job_upload",
"status": "queued",
"estimatedCompletion": "2025-07-18T10:35:00Z",
"position": 3 // Position in queue
}
Get Sync Status
GET /sync/assignments/{assignmentId}/status
Response:
{
"assignmentId": "assign_124",
"currentOperations": [
{
"operation": "data_poll",
"status": "running",
"startTime": "2025-07-18T10:30:00Z",
"progress": 75,
"metadata": {
"filesChecked": 3,
"filesFound": 1,
"dataSize": 524288
}
}
],
"lastSync": {
"operation": "job_upload",
"status": "completed",
"duration": 1250,
"completedAt": "2025-07-18T09:16:00Z"
},
"nextScheduled": {
"operation": "data_poll",
"scheduledTime": "2025-07-18T10:31:00Z"
},
"syncHistory": [
{
"operation": "job_upload",
"status": "completed",
"startTime": "2025-07-18T09:15:00Z",
"endTime": "2025-07-18T09:16:00Z",
"duration": 1250
}
]
}
Bulk Sync Operations
POST /sync/bulk-sync
Request Body:
{
"operation": "data_poll",
"filters": {
"partnerType": "satloc",
"status": "pending",
"lastSyncBefore": "2025-07-18T08:00:00Z"
},
"options": {
"batchSize": 10,
"priority": "normal",
"maxConcurrent": 3
}
}
Response:
{
"batchId": "batch_456",
"totalAssignments": 25,
"batches": 3,
"estimatedCompletion": "2025-07-18T11:00:00Z",
"status": "queued"
}
Application Data APIs
Get Application Data with Partner Info
GET /applications/{applicationId}
Response:
{
"_id": "app_789",
"jobId": 124,
"fileName": "satloc_flight_data_001.dat",
"fileSize": 1048576,
"status": 3,
"partnerType": "satloc",
"externalJobId": "satloc_job_456",
"assignmentId": "assign_124",
"originalData": {
"format": "satloc",
"version": "2.1",
"encoding": "binary",
"checksum": "sha256:abc123..."
},
"partnerMetadata": {
"aircraftInfo": {
"id": "SAT002",
"model": "Satloc G4",
"firmware": "v3.2.1"
},
"flightInfo": {
"startTime": "2025-07-18T10:00:00Z",
"endTime": "2025-07-18T12:30:00Z",
"duration": 9000,
"altitude": {"min": 95, "max": 105, "avg": 100}
},
"dataQuality": {
"gpsAccuracy": 0.5,
"signalStrength": 98,
"dataCompleteness": 99.2
}
},
"processingStage": "completed",
"processingSteps": [
{
"step": "upload",
"status": "completed",
"duration": 200
},
{
"step": "validate",
"status": "completed",
"duration": 150
},
{
"step": "convert",
"status": "completed",
"duration": 3000
}
],
"conversionMetrics": {
"recordsInput": 15000,
"recordsOutput": 14987,
"dataLossPercentage": 0.09,
"conversionTime": 3000
},
"qualityChecks": [
{
"checkType": "gps_continuity",
"status": "passed",
"score": 98
},
{
"checkType": "spray_coverage",
"status": "passed",
"score": 95
}
]
}
Get Processing Status
GET /applications/{applicationId}/processing-status
Response:
{
"applicationId": "app_789",
"currentStage": "completed",
"progress": 100,
"totalSteps": 6,
"completedSteps": 6,
"currentStep": null,
"estimatedTimeRemaining": 0,
"processingStarted": "2025-07-18T10:35:00Z",
"processingCompleted": "2025-07-18T10:38:00Z",
"totalDuration": 180000,
"stepDetails": [
{
"step": "upload",
"status": "completed",
"progress": 100,
"duration": 200,
"startTime": "2025-07-18T10:35:00Z",
"endTime": "2025-07-18T10:35:00Z"
}
]
}
Error Handling
All API endpoints follow consistent error response format:
{
"error": {
"code": "PARTNER_SYNC_FAILED",
"message": "Failed to sync job with Satloc partner",
"details": {
"partnerId": "satloc",
"operation": "job_upload",
"cause": "Network timeout after 30s",
"retryable": true,
"nextRetry": "2025-07-18T10:40:00Z"
},
"requestId": "req_123456789",
"timestamp": "2025-07-18T10:30:00Z"
}
}
Error Codes
| Code | Description | HTTP Status | Retryable |
|---|---|---|---|
PARTNER_NOT_FOUND |
Partner configuration not found | 404 | No |
PARTNER_UNAVAILABLE |
Partner API is temporarily unavailable | 503 | Yes |
PARTNER_SYNC_FAILED |
Failed to sync with partner | 500 | Yes |
INVALID_PARTNER_CONFIG |
Partner configuration is invalid | 400 | No |
RATE_LIMIT_EXCEEDED |
Partner rate limit exceeded | 429 | Yes |
AUTHENTICATION_FAILED |
Partner authentication failed | 401 | No |
DATA_FORMAT_ERROR |
Data format conversion failed | 422 | No |
ASSIGNMENT_NOT_FOUND |
Assignment not found | 404 | No |
SYNC_IN_PROGRESS |
Sync operation already in progress | 409 | No |
Rate Limiting
API endpoints are rate limited based on the operation type:
- Job Assignment: 100 requests per minute
- Data Download: 50 requests per minute
- Sync Operations: 200 requests per minute
- Status Queries: 1000 requests per minute
Rate limit headers are included in all responses:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1642608000
X-RateLimit-Retry-After: 60
Webhooks
Partner Status Notifications
Partners can register webhooks to receive notifications:
POST /webhooks/partner-events
Request Body:
{
"url": "https://partner.example.com/webhooks/agmission",
"events": ["job_assigned", "data_processed", "sync_failed"],
"secret": "webhook_secret_key"
}
Webhook Payload Example
{
"event": "job_assigned",
"timestamp": "2025-07-18T10:30:00Z",
"data": {
"assignmentId": "assign_124",
"jobId": 124,
"partnerType": "satloc",
"externalJobId": "satloc_job_456",
"userId": "user_id_2"
},
"signature": "sha256=webhook_signature"
}
This API specification provides comprehensive coverage of all partner integration functionality while maintaining backward compatibility with existing internal workflows.