Endpointtoday's app
Call PATCH /gateway/portfolio-service/api/v1/portfolios/Service portfolio-service Features Crop Actual (portfolio) , Crop Plan When Queued sync (IE_PORTFOLIO PATCH) Auth X-SESSIONID stamped when queued (CoreAPI dooWithRetry); X-REQUESTID idempotency key In the App Service Use case Queued update of a crop plan portfolio (IE_PORTFOLIO PATCH) - e.g. adding another line item to an existing portfolio. Sends a list with one portfolio. IEPortfolioPatchRH maps returned PLI ids by uuid and clears sync errors; error handling matches the POST (asset refresh worker, body fix-up, retry later).
Headers Header Value Notes X-SESSIONID<session token> Stamped when the operation is queued (dooWithRetry) and re-set by CoreAPI at send time; refreshed on 401. X-REQUESTID<uuid v4> Idempotency key generated by OperationManagerImpl.createOperation for POST/PUT/PATCH when the op enters the offline queue. X-ACK-REQUESTID<X-REQUESTID of an earlier completed op> Added by SyncQueueProcessor for POST/PUT/PATCH: acknowledges a request id the device already saw succeed. Content-Typeapplication/json Added by CoreAPI.
Request Example request body (synthetic data) [
{
"owningEntityId": "40001",
"id": 5001,
"uuid": "3a9d0000-0000-4000-8000-000000000101",
"ownerEntityType": {
"code": "ENTITY_TYPE.IE",
"refClass": {
"code": "CLASS.ENTITY_TYPE"
}
},
"appMillMetadata": {
"ie_appId": "ie-alias-0001"
},
"actor": {
"actorId": "40001",
"id": 0,
"actorType": "ACTOR_TYPE.IE"
},
"portfolioLineItemList": [
{
"portfolioId": "3a9d0000-0000-4000-8000-000000000101",
"id": 6001,
"asset": "ASSET-CODE-0001",
"uuid": "5f6c1d2e-0000-4000-8000-00000000a001",
"practiceMasterCodes": [
"PRACTICE.MULCHING",
"PRACTICE.SEED_TREATMENT"
],
"portfolioLineItemType": "PORTFOLIO_LINE_ITEM_TYPE.ACTUAL",
"imageUrl": "/data/user/0/<app>/files/pli_6001.jpg",
"isActive": true,
"currentSeason": "KHARIF_2026",
"methodMaster": {
"id": 3,
"uuid": "m-0003",
"methodCode": "METHOD.PMDS"
},
"practiceMaster": {
"practiceCode": "PRACTICE.MULCHING",
"id": 4,
"uuid": "p-0004"
},
"appCreatedAt": "1780000000000",
"appLastModifiedAt": "1780000000000",
"createdAt": null,
"lastModifiedAt": null,
"titleId": "TILE-0001",
"assetId": 9001,
"assetCheckSum": "<asset checksum>",
"hasSyncError": false,
"syncErrorId": null,
"compactBlockId": null,
"isLinkedToCompactBlock": false,
"createdByApp": 109,
"lastModifiedByApp": 109,
"createdFromDevice": "<device id>",
"lastUpdatedFromDevice": "<device id>",
"geoFencingFileName": null,
"geoFencingCreatedOn": null,
"geoFencingFilePath": null,
"geoFenceAttachments": null,
"isEditable": true,
"imageAttachmentId": null,
"imageCreatedAt": null,
"changeLog": null,
"cropSeason": "KHARIF",
"isAttachmentFetched": false,
"portfolioProductLineItemList": [
{
"portfolioLineItemId": "5f6c1d2e-0000-4000-8000-00000000a001",
"id": 7001,
"uuid": "7b1e0000-0000-4000-8000-000000000201",
"genericProduct": "PRODUCT.PADDY",
"plannedStartDate": "2026-06-01",
"plannedEndDate": "2026-10-31",
"actualStartDate": "2026-06-05",
"actualEndDate": null,
"cropChangeReason": null,
"assetProportion": {
"id": 0,
"uoM": {
"code": "UOM.ACRE",
"description": "Acre",
"measurementType": {
"code": "MEASUREMENT_TYPE.AREA",
"description": "Area",
"globalRefClass": {
"code": "GREF.MEASUREMENT_TYPE",
"description": "",
"name": "Measurement type"
},
"name": "Area"
},
"name": "Acre",
"symbol": "ac"
},
"value": 0.5
},
"isMajorCrop": true,
"cropType": "CROP_TYPE.MAIN",
"harvestStatus": "HARVEST_STATUS.PENDING",
"harvestStartDateTime": null,
"harvestCompleteDateTime": null,
"appCreatedAt": "1780000000000",
"appLastModifiedAt": "1780000000000",
"createdAt": null,
"lastModifiedAt": null,
"ppliCropType": "PPLI_CROP_TYPE.PMDS",
"expectedHarvestDate": "2026-10-15",
"seedSource": "SEED_SOURCE.OWN",
"seedVariety": "Variety A",
"interestedInCropMarketing": false,
"sowingDate": "2026-06-05",
"appId": "7b1e0000-0000-4000-8000-000000000201",
"syncStatus": "SYNC_PENDING"
}
],
"portfolioLineItemQuestionResponses": [
{
"portfolioLineItemAppId": "5f6c1d2e-0000-4000-8000-00000000a001",
"id": 0,
"uuid": "8c2f0000-0000-4000-8000-000000000301",
"questionId": 12,
"category": "PMDS",
"subCategory": "SEED_TREATMENT",
"questionType": "SINGLE_SELECT",
"questionCode": "Q_SEED_TREATMENT",
"questionLabel": "Seed treated?",
"answerLanguageCode": "en",
"answerValue": "YES",
"answerLabel": "Yes",
"answerText": null,
"appCreatedAt": "1780000000000",
"appLastModifiedAt": "1780000000000"
}
],
"isSelected": false,
"isPresentInDifferentCB": false,
"appId": "5f6c1d2e-0000-4000-8000-00000000a001",
"syncStatus": "SYNC_PENDING"
}
],
"appId": "3a9d0000-0000-4000-8000-000000000101",
"syncStatus": "SYNC_PENDING"
}
]Field Type Required Notes [] (array of one Portfolio)array Yes Same shape as the line-items/v2 POST body. [0].portfolioLineItemList[].idinteger No Server PLI id (0/null on first create). Column portfolio_portfoliolineitem.id. [0].portfolioLineItemList[].uuidstring Yes Client UUID; server echoes it so the RH can map ids back. [0].portfolioLineItemList[].asset / assetId / assetCheckSumstring / integer / string Yes Land (asset) code, server asset id and checksum from the Land Assets table. Checksum mismatch -> ERR_PLATFORM_ASSET_CHECKSUM_MISMATCH. [0].portfolioLineItemList[].titleIdstring No Land tile id used to match geofence files and compact blocks. [0].portfolioLineItemList[].portfolioLineItemTypestring Yes PLAN vs ACTUAL (crop plan / crop actual screen). [0].portfolioLineItemList[].currentSeason / cropSeasonstring No From app config CURRENT_SEASON. [0].portfolioLineItemList[].practiceMasterCodesstring[] No Practices ticked on the crop actual screen (practicemaster table). [0].portfolioLineItemList[].methodMaster / practiceMasterobject No Method (PMDS/RDS) and practice selected. [0].portfolioLineItemList[].portfolioProductLineItemList[]array Yes One entry per crop on the land: genericProduct, cropType, ppliCropType, assetProportion (area value + UoM), planned/actual dates, sowingDate, seedSource, seedVariety, expectedHarvestDate, harvestStatus, isMajorCrop. [0].portfolioLineItemList[].portfolioLineItemQuestionResponses[]array No PMDS A-grade question answers (portfolio_question_response table). [0].portfolioLineItemList[].createdByApp / lastModifiedByApp / createdFromDevice / lastUpdatedFromDevicelong / string No Audit fields set by the app. [0].portfolioLineItemList[].appCreatedAt / appLastModifiedAtstring (epoch ms) No Device timestamps. [0].portfolioLineItemList[].imageUrl, geoFencing*, hasSyncError, syncErrorId, isEditable, isSelected, isPresentInDifferentCB, practices, appId, opId, syncStatusmixed No Local-only columns that Gson also serialises; the server ignores them.
Response Example response body (synthetic data) [
{
"owningEntityId": "40001",
"id": 5001,
"uuid": "3a9d0000-0000-4000-8000-000000000101",
"ownerEntityType": {
"code": "ENTITY_TYPE.IE",
"refClass": {
"code": "CLASS.ENTITY_TYPE"
}
},
"actor": {
"actorId": "40001",
"id": 0,
"actorType": "ACTOR_TYPE.IE"
},
"portfolioLineItemList": [
{
"portfolioId": "3a9d0000-0000-4000-8000-000000000101",
"id": 6001,
"asset": "ASSET-CODE-0001",
"uuid": "5f6c1d2e-0000-4000-8000-00000000a001",
"practiceMasterCodes": [
"PRACTICE.MULCHING",
"PRACTICE.SEED_TREATMENT"
],
"portfolioLineItemType": "PORTFOLIO_LINE_ITEM_TYPE.ACTUAL",
"imageUrl": "/data/user/0/<app>/files/pli_6001.jpg",
"isActive": true,
"currentSeason": "KHARIF_2026",
"methodMaster": {
"id": 3,
"uuid": "m-0003",
"methodCode": "METHOD.PMDS"
},
"practiceMaster": {
"practiceCode": "PRACTICE.MULCHING",
"id": 4,
"uuid": "p-0004"
},
"appCreatedAt": "1780000000000",
"appLastModifiedAt": "1780000000000",
"createdAt": null,
"lastModifiedAt": null,
"titleId": "TILE-0001",
"assetId": 9001,
"assetCheckSum": "<asset checksum>",
"hasSyncError": false,
"syncErrorId": null,
"compactBlockId": null,
"isLinkedToCompactBlock": false,
"createdByApp": 109,
"lastModifiedByApp": 109,
"createdFromDevice": "<device id>",
"lastUpdatedFromDevice": "<device id>",
"geoFencingFileName": null,
"geoFencingCreatedOn": null,
"geoFencingFilePath": null,
"geoFenceAttachments": null,
"isEditable": true,
"imageAttachmentId": null,
"imageCreatedAt": null,
"changeLog": null,
"cropSeason": "KHARIF",
"isAttachmentFetched": false,
"portfolioProductLineItemList": [
{
"portfolioLineItemId": "5f6c1d2e-0000-4000-8000-00000000a001",
"id": 7001,
"uuid": "7b1e0000-0000-4000-8000-000000000201",
"genericProduct": "PRODUCT.PADDY",
"plannedStartDate": "2026-06-01",
"plannedEndDate": "2026-10-31",
"actualStartDate": "2026-06-05",
"actualEndDate": null,
"cropChangeReason": null,
"assetProportion": {
"id": 0,
"uoM": {
"code": "UOM.ACRE",
"description": "Acre",
"measurementType": {
"code": "MEASUREMENT_TYPE.AREA",
"description": "Area",
"globalRefClass": {
"code": "GREF.MEASUREMENT_TYPE",
"description": "",
"name": "Measurement type"
},
"name": "Area"
},
"name": "Acre",
"symbol": "ac"
},
"value": 0.5
},
"isMajorCrop": true,
"cropType": "CROP_TYPE.MAIN",
"harvestStatus": "HARVEST_STATUS.PENDING",
"harvestStartDateTime": null,
"harvestCompleteDateTime": null,
"appCreatedAt": "1780000000000",
"appLastModifiedAt": "1780000000000",
"createdAt": null,
"lastModifiedAt": null,
"ppliCropType": "PPLI_CROP_TYPE.PMDS",
"expectedHarvestDate": "2026-10-15",
"seedSource": "SEED_SOURCE.OWN",
"seedVariety": "Variety A",
"interestedInCropMarketing": false,
"sowingDate": "2026-06-05",
"appId": "7b1e0000-0000-4000-8000-000000000201",
"syncStatus": "SYNC_PENDING"
}
],
"portfolioLineItemQuestionResponses": [
{
"portfolioLineItemAppId": "5f6c1d2e-0000-4000-8000-00000000a001",
"id": 0,
"uuid": "8c2f0000-0000-4000-8000-000000000301",
"questionId": 12,
"category": "PMDS",
"subCategory": "SEED_TREATMENT",
"questionType": "SINGLE_SELECT",
"questionCode": "Q_SEED_TREATMENT",
"questionLabel": "Seed treated?",
"answerLanguageCode": "en",
"answerValue": "YES",
"answerLabel": "Yes",
"answerText": null,
"appCreatedAt": "1780000000000",
"appLastModifiedAt": "1780000000000"
}
],
"isSelected": false,
"isPresentInDifferentCB": false,
"appId": "5f6c1d2e-0000-4000-8000-00000000a001",
"syncStatus": "SYNC_PENDING"
}
]
}
]Field Type Required Notes [].portfolioLineItemList[] ids/uuidsmixed updateOptionLineItemIds.
Errors Status When What the app does 4xx with asset errorCodeChecksum mismatch / quantity limit FetchFarmerAssetDataWorker scheduled; queued body refreshed; retried later. 401Session token expired or invalid CoreAPI invalidates the session id and retries once immediately; if still failing the op stays in the queue (TryAgain.LATER). 500Server 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). 503Service unavailable CoreAPI retries once immediately, then the op is retried later by the sync queue. any non-2xxAny 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.
Source data/src/main/java/org/mindtree/app/agricultor/data/entity/Portfolio.kt data/src/main/java/org/mindtree/app/agricultor/data/sync/work/IEPortfolioWorker.kt data/src/main/java/org/mindtree/app/agricultor/data/sync/rh/IEPortfolioPatchRH.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