APIs & services / portfolio-service

Upload an ATM photo or ATM KML geofence.

Endpointtoday's app
Call
POST /gateway/portfolio-service/api/v1/farming-model/attachment/custom
Service
portfolio-service
Features
ATM model (Anytime Money plot), Geofencing
When
Queued sync (IE_ATM SYNC_POST_IMAGE / SYNC_POST_GEOFENCING)
Auth
X-SESSIONID stamped when queued (CoreAPI dooWithRetry); X-REQUESTID idempotency key
In the App Service

Use case

Queued multipart upload for a farming model: the ATM photo (SYNC_POST_IMAGE -> ATMPicRH, ids as query params) or the ATM geofence KML (SYNC_POST_GEOFENCING -> FarmingModelGeofencingPostRH, ids and saveFileContent=true as form fields). On success the attachment id is saved as imageAttachmentId or geoFencingFileId (with attachmentDateTime). Photo failures rewrite the params with the latest ids and retry.

Headers

HeaderValueNotes
X-SESSIONID<session token>Stamped when queued (dooWithRetry); refreshed on 401.
X-ACK-REQUESTID<X-REQUESTID of an earlier completed op>Added by SyncQueueProcessor for POST/PUT. X-REQUESTID is removed for multipart requests by CoreAPIDefaultImpl.processOperation.
Content-Typemultipart/form-data; boundary=<generated>Multipart because the op has a File param.

Parameters

ParamInRequiredExampleNotes
farmingModelIdqueryYes5501Query param for photos; multipart form field for geofence.
farmingModelUUIDqueryYesfm-0000-4000-8000-000000000501Query for photos; form field for geofence.
appCreatedAtqueryYes1780000000000Query for photos; form field for geofence.

Request

Example request body (synthetic data)
{
  "file": "<multipart part: atm_5501.jpg or geofence.kml>",
  "farmingModelId": 5501,
  "farmingModelUUID": "fm-0000-4000-8000-000000000501",
  "saveFileContent": true,
  "appCreatedAt": "1780000000000"
}
FieldTypeRequiredNotes
filebinaryYesATM photo or KML from the geofencing screen.
farmingModelId / farmingModelUUID / appCreatedAtform fieldsNoSent as form fields only in the geofence variant.
saveFileContentboolean (form field)NoGeofence variant only.

Response

Example response body (synthetic data)
{
  "attachmentDateTime": "2026-07-01T10:15:00.000+05:30",
  "fileName": "geofence_tile_0001.kml",
  "attachmentKind": "ATTACHMENT_KIND.GEOFENCE",
  "attachmentKindMetaData": "<?xml version=\"1.0\"?><kml>...polygon...</kml>",
  "attachmentKindIdentifier": 6001,
  "attachmentUUID": "a1b2c3d4-0000-4000-8000-000000000401",
  "id": 88002,
  "uuid": "a1b2c3d4-0000-4000-8000-000000000402",
  "tempAttachmentURL": "https://<storage-host>/signed/geofence_tile_0001.kml?sig=<redacted>",
  "appCreatedAt": "1780000000000"
}
FieldTypeRequiredNotes
idintegerAttachment id; highest id per type wins. Stored as imageAttachmentId / geoFenceAttachments / geoFencingFileId.
attachmentDateTimestringSaved as geoFencingCreatedOn.

Errors

StatusWhenWhat the app does
401Session token expired or invalidCoreAPI invalidates the session id and retries once immediately; if still failing the op stays in the queue (TryAgain.LATER).
500Server error on a /gateway URLBaseResponseHandler fetches a new session id (first 5 attempts) and returns TryAgain.LATER; retried per RetryScheduler policy (retry threshold/delay come from app config).
503Service unavailableCoreAPI retries once immediately, then the op is retried later by the sync queue.
any non-2xxAny other failureHandler onError -> TryAgain.LATER (op stays queued and is visible in Pending Sync); a row is written to the local error_log table (Sync Error Log screen) with URL, body, headers and raw response; every 10th attempt the op is mirrored to Firestore for support.

Source

  • data/src/main/java/org/mindtree/app/agricultor/data/sync/work/ATMWorker.kt
  • data/src/main/java/org/mindtree/app/agricultor/data/sync/rh/ATMPicRH.kt
  • data/src/main/java/org/mindtree/app/agricultor/data/sync/rh/FarmingModelGeofencingPostRH.kt
  • data/src/main/java/org/mindtree/app/agricultor/data/manager/CoreAPIManager.kt
  • data/src/main/java/org/mindtree/app/agricultor/data/sync/rh/BaseResponseHandler.kt
  • offline-core/src/main/java/com/mindtree/bridge/coreapi/offline/SyncQueueProcessor.java
  • offline-core/src/main/java/com/mindtree/bridge/coreapi/offline/manager/OperationManagerImpl.java
  • core-api/src/main/java/com/mindtree/bridge/coreapi/impl/CoreAPIDefaultImpl.java