Endpointtoday's app
Call PUT /gateway/portfolio-service/api/v1/portfolios/{pid}/portfolioLineItem/v2/crop-activityService portfolio-service Features Crop Actual (portfolio) , PMDS and A Grade crop details , Activity Tracker When Queued sync (IE_PORTFOLIO_LINE_ITEM PUT) Auth X-SESSIONID stamped when queued (CoreAPI dooWithRetry); X-REQUESTID idempotency key In the App Service Use case Queued edit of a crop line item (IE_PORTFOLIO_LINE_ITEM PUT via PortfolioLineItemWorker.putWithChangeLog) after the user edits a crop actual. The body wraps the PLI and its change log (crop activity entries such as crop changed, sowing date changed). The returned PLI's ids are mapped back and any sync error cleared. If the server says the PLI is part of a compact block, PortfolioLineItemUpdateWorker re-downloads the server copy and drops the op; asset errors trigger FetchFarmerAssetDataWorker; other errors retry.
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.
Parameters Param In Required Example Notes pidpath Yes 5001Server portfolio id looked up from the local portfolio.
Request Example request body (synthetic data) {
"portfolioLineItemDTO": {
"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": [
{
"remarks": null,
"changeCategory": "CROP_CHANGE",
"activityNotes": "Crop replaced after flood",
"id": 0,
"portfolioLineItemId": 6001,
"oldValue": "PRODUCT.PADDY",
"portfolioId": 5001,
"changedField": "genericProduct",
"newValue": "PRODUCT.MAIZE",
"tileId": "TILE-0001",
"assetCode": "ASSET-CODE-0001",
"assetId": 9001,
"appCreatedAt": 1780000000000
}
],
"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"
},
"portfolioCropActivityLogDTOs": [
{
"remarks": null,
"changeCategory": "CROP_CHANGE",
"activityNotes": "Crop replaced after flood",
"id": 0,
"portfolioLineItemId": 6001,
"oldValue": "PRODUCT.PADDY",
"portfolioId": 5001,
"changedField": "genericProduct",
"newValue": "PRODUCT.MAIZE",
"tileId": "TILE-0001",
"assetCode": "ASSET-CODE-0001",
"assetId": 9001,
"appCreatedAt": 1780000000000
}
]
}Field Type Required Notes portfolioLineItemDTO.idinteger No Server PLI id (0/null on first create). Column portfolio_portfoliolineitem.id. portfolioLineItemDTO.uuidstring Yes Client UUID; server echoes it so the RH can map ids back. portfolioLineItemDTO.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. portfolioLineItemDTO.titleIdstring No Land tile id used to match geofence files and compact blocks. portfolioLineItemDTO.portfolioLineItemTypestring Yes PLAN vs ACTUAL (crop plan / crop actual screen). portfolioLineItemDTO.currentSeason / cropSeasonstring No From app config CURRENT_SEASON. portfolioLineItemDTO.practiceMasterCodesstring[] No Practices ticked on the crop actual screen (practicemaster table). portfolioLineItemDTO.methodMaster / practiceMasterobject No Method (PMDS/RDS) and practice selected. portfolioLineItemDTO.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. portfolioLineItemDTO.portfolioLineItemQuestionResponses[]array No PMDS A-grade question answers (portfolio_question_response table). portfolioLineItemDTO.createdByApp / lastModifiedByApp / createdFromDevice / lastUpdatedFromDevicelong / string No Audit fields set by the app. portfolioLineItemDTO.appCreatedAt / appLastModifiedAtstring (epoch ms) No Device timestamps. portfolioLineItemDTO.imageUrl, geoFencing*, hasSyncError, syncErrorId, isEditable, isSelected, isPresentInDifferentCB, practices, appId, opId, syncStatusmixed No Local-only columns that Gson also serialises; the server ignores them. portfolioCropActivityLogDTOs[]array Yes PLI changeLog entries with id forced 0 and portfolioLineItemId, portfolioId, assetId, assetCode, tileId filled; each has changeCategory, changedField, oldValue, newValue, remarks, activityNotes, appCreatedAt.
Response Example response body (synthetic data) {
"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": null,
"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
}Field Type Required Notes id / uuid / portfolioProductLineItemList[].id / uuidmixed updateOptionLineItemIds.
Errors Status When What the app does 4xx, errorMessage contains 'is a part of compactBlock. Hence, Editing is not allowed.'PLI locked by a compact block PortfolioLineItemUpdateWorker overwrites local PLI from server, logs the error and deletes the queued op. 4xx with asset errorCodeChecksum mismatch / quantity limit FetchFarmerAssetDataWorker scheduled; body refreshed; retried. 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/PortfolioLineItem.kt data/src/main/java/org/mindtree/app/agricultor/data/sync/work/PortfolioLineItemWorker.kt data/src/main/java/org/mindtree/app/agricultor/data/sync/rh/PortfolioLineItemPutWithCropChangeRH.kt data/src/main/java/org/mindtree/app/agricultor/data/utils/PortfolioLineItemUpdateWorker.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