Queued multipart upload for a crop line item: the crop photo (IE_PORTFOLIO_LINE_ITEM POST -> PortfolioLineItemPicRH) or the land geofence KML (SYNC_POST_GEOFENCING -> PortfolioLineItemGeofencingPostRH, with saveFileContent=true and updatePortfolioLineItemWithGeoFenceAttachment=true). An http image URL is downloaded first. On success the attachment id is saved as imageAttachmentId or added to geoFenceAttachments. On photo failures, after N attempts (config) the photo is uploaded to Firebase Storage as a fallback and the op closed; geofence failures fix the file path / refresh ids and retry.
Headers
Header
Value
Notes
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-Type
multipart/form-data; boundary=<generated>
Multipart because the op has a File param.
Parameters
Param
In
Required
Example
Notes
portfolioLineItemId
query
Yes
6001
Server PLI id.
portfolioId
query
Yes
5001
Server portfolio id (0 if unknown).
portfolioLineItemUUID
query
Yes
5f6c1d2e-0000-4000-8000-00000000a001
Client uuid.
appCreatedAt
query
Yes
1780000000000
imageCreatedAt / geoFencingCreatedOn as epoch ms (now if missing).
portfolioLineItemMonth
query
Yes
2026/06/01
First crop plannedStartDate reformatted yyyy/MM/dd.
saveFileContent
query
No
true
Geofence only.
updatePortfolioLineItemWithGeoFenceAttachment
query
No
true
Geofence only.
Request
Example request body (synthetic data)
{
"file": "<multipart part: pli_6001.jpg or geofence_tile_0001.kml>"
}
Field
Type
Required
Notes
file
binary
Yes
Local photo taken on the crop actual screen, or KML captured on the geofencing screen.
Attachment id; highest id per type wins. Stored as imageAttachmentId / geoFenceAttachments / geoFencingFileId.
attachmentDateTime
string
Saved as geoFencingCreatedOn.
other fields
mixed
Not read.
Errors
Status
When
What the app does
any, attempts >= FIREBASE_ATTACHMENT_UPLOAD_POST_FAIL_COUNT and FIREBASE_ATTACHMENT_UPLOAD_FLAG on
Photo upload keeps failing
Photo uploaded to Firebase Storage, metadata to Firestore; ledger marked done.
401
Session token expired or invalid
CoreAPI invalidates the session id and retries once immediately; if still failing the op stays in the queue (TryAgain.LATER).
500
Server error on a /gateway URL
BaseResponseHandler fetches a new session id (first 5 attempts) and returns TryAgain.LATER; retried per RetryScheduler policy (retry threshold/delay come from app config).
503
Service unavailable
CoreAPI retries once immediately, then the op is retried later by the sync queue.
any non-2xx
Any other failure
Handler 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.