Scenario: Send many requests at once, or run long work asynchronously
Goal. Cut the number of round trips when an integration has many documents to post, and keep long-running
postings off the caller's HTTP connection. A ...Batch operation takes a list of requests in one call and
answers with one result per item. submitAsyncOperation queues one long-running operation to the batch
framework and answers at once with a tracking id, which the caller polls with getAsyncOperationStatus until
the work is done.
When to use.
- Batch operations when you have several requests for the same operation now (a day's sales orders to confirm, a set of journals to post) and each one completes in normal service time. Every item is processed independently, in the same call.
- Async operations for the long-running operations the async registry accepts: fixed asset acquisitions, disposals, depreciation proposals and transactions after acquisition, the three currency revaluations, item cost calculation and pending price activation (new standard costs), general and intercompany journal postings and journal reversals, the posting of existing ledger, inventory, project, production and trade agreement journals (Post an existing journal), and budget entries and transfers. Use it when a posting may outlast your HTTP client's timeout, or when the caller should not wait.
- For a single posting with retries, see Post a journal exactly-once.
Prerequisites
-
Security.
- A
...Batchoperation is granted by the same privilege as its single operation (for exampleMGCLatticeAccountsReceivableServiceMaintainforconfirmSalesOrderBatch). submitAsyncOperationneedsMGCLatticeAsyncOperationServiceMaintainand the privilege that grants the target operation for a direct call (MGCLatticeGeneralLedgerServiceMaintainforpostGeneralJournal;MGCLatticeFixedAssetsDisposalMaintain,MGCLatticeGeneralLedgerIntercompanyMaintain,MGCLatticeGeneralLedgerJournalReverseMaintainandMGCLatticeInventoryCostActivateMaintain, administrator role only, for disposals, intercompany journals, journal reversals and pending price activations). The operator role can submit every other async operation. Posting an existing journal asynchronously also needs the operations the journal's content requires, as for a direct call.getAsyncOperationStatusneedsMGCLatticeAsyncOperationServiceView(all three Lattice roles).
See Security model.
- A
-
For async operations: a running batch server (System administration > Setup > Server configuration, an AOS marked as batch server). Each submission schedules its own one-time batch job. As the fallback, process automation must be initialized and the Lattice Async Operation Processing background process enabled (System administration > Setup > Process automations, Background processes): every minute it runs queued operations and recovers operations a stopped batch task left processing. Failed operations are retried by the Lattice dead-letter retry background process. Both run by themselves; there is nothing to schedule (Integration operations).
-
The async pair is enabled on System administration > Setup > Lattice > Async operation registry. All nineteen shipped pairs are enabled unless an administrator switched one off.
-
The client is connected (Connect an integration client).
Steps
Send a batch
-
Build the list. Append
Batchto the operation name and send the requests in_requests. Each item is the request the single operation takes, with its ownRequestId.confirmSalesOrderBatchonMGCLatticeSalesOrderPostingService(MGCLatticeAccountsReceivableServiceGroup):POST https://<your-environment>/api/services/MGCLatticeAccountsReceivableServiceGroup/MGCLatticeSalesOrderPostingService/confirmSalesOrderBatch{"_requests": [{ "RequestId": "a1b2c3d4-0001-4000-8000-000000000001", "LegalEntityId": "USMF","SalesOrderId": "000698", "PostingDate": "2026-10-07" },{ "RequestId": "a1b2c3d4-0001-4000-8000-000000000002", "LegalEntityId": "USMF","SalesOrderId": "SO-MISSING", "PostingDate": "2026-10-07" }]}The posting and action operations have a batch variant. The status queries, the async operations, the price inquiry, database access and Data management configuration have none, and
setSalesPriceBatchanswers with its own envelope. -
Read the envelope, then each item. The answer is one
MGCLatticeBulkOperationResponseContract:{"Success": false,"Status": 6,"Message": "1 of 2 item(s) succeeded.","TotalCount": 2,"SuccessCount": 1,"FailureCount": 1,"Results": [{ "ItemIndex": 1, "RequestId": "a1b2c3d4-0001-4000-8000-000000000001", "Success": true, "Status": 3,"ErrorCode": 0, "IsRetryable": false, "DocumentId": "000698", "PostedDocumentId": "000698-1" },{ "ItemIndex": 2, "RequestId": "a1b2c3d4-0001-4000-8000-000000000002", "Success": false, "Status": 4,"ErrorCode": 2, "IsRetryable": false, "Message": "Sales order confirmation failed due to validation or business rule constraints.","Errors": ["Sales order SO-MISSING was not found."] }]}Successistrueonly when every item succeeded.Statusis3(Succeeded) when all items succeeded,4(Failed) when all failed, and6(PartialSuccess) when some did.ItemIndexis the item's one-based position in your list; match results to requests by it or byRequestId. Each item is processed on its own: a failed item rolls nothing back for the others. -
Retry only what needs it. A successful item's
RequestIdis recorded, and a failed item's is released. So you can resend the whole list unchanged: the items that succeeded replay their recorded result (sameDocumentIdandPostedDocumentId, message "Duplicate request detected...") and post nothing, and the items that failed run again. Fix the data first for an item whoseIsRetryableisfalse.
Run an operation asynchronously
-
Submit it.
submitAsyncOperationonMGCLatticeAsyncOperationService(MGCLatticeAsyncOperationServiceGroup) takes the target service and operation and, inRequestPayload, the target's own request (the object you would send as_request) serialized as a JSON string. The payload needs its ownRequestId, the posting's idempotency key, and an existingLegalEntityId; the outerRequestIdis the key of the submission.{"_request": {"RequestId": "7c9e6679-7425-40de-944b-e07fc1f90ae7","LegalEntityId": "USMF","ServiceName": "MGCLatticeGeneralLedgerJournalService","OperationName": "postGeneralJournal","RequestPayload": "{\"RequestId\":\"5143fdcf-9a1e-4b6c-8a0e-2f6d7c1b9e42\",\"LegalEntityId\":\"USMF\",\"JournalNameId\":\"GenJrn\",\"Description\":\"Month-end accruals\",\"PostingDate\":\"2026-10-07\",\"Lines\":[{\"MainAccountId\":\"110110\",\"OffsetMainAccountId\":\"110180\",\"AmountCurDebit\":1000.00,\"AmountCurCredit\":0,\"CurrencyCode\":\"USD\",\"TransDate\":\"2026-10-07\"}]}"}}It answers at once with
Successtrue, aTrackingIdandStatus1(Queued). Sending the same submission again returns the firstTrackingIdand queues nothing. -
Poll for the result.
getAsyncOperationStatuswith the tracking id:{ "_request": { "TrackingId": "e4f5a6b7-c8d9-4123-8567-89abcdef0123" } }Statusmoves from1(Queued) to2(Processing) to3(Succeeded) or4(Failed). Poll every few seconds with a back-off. An operation normally starts within seconds of the submit; allow a few minutes when the batch server is cold, for example just after a deployment. -
Use the result. On
Succeeded,DocumentIdandPostedDocumentIdcarry the target operation's result (for a general journal, the journal number) andMessageits message. OnFailed,ErrorCode,IsRetryable,MessageandErrorscarry the failure.
How to verify
- Batch:
TotalCountequals the number of items you sent andSuccessCountplusFailureCountequalsTotalCount. Each successful item's document is in Finance and Operations (for the example, the order's confirmation), and each item is a row inLatticeServiceCallLogsunder its ownRequestId. - Async:
getAsyncOperationStatusreturnsStatus3with the document id. The operation is also a row inLatticeAsyncOperationTrackingRecords(filter onTrackingId), withSubmittedBy, the timestamps and the result; the target call itself is inLatticeServiceCallLogsunder the payload'sRequestId. See Track documents and read data.
When it goes wrong
Batch operations
| What you see | Meaning and what to do |
|---|---|
Success false, Status 4, "At least one request item is required.", no Results | The _requests list was missing or empty. |
An item fails with ValidationFailed, "Request item N is empty..." | That entry of the list was empty; the other items still ran. |
| An item replays the result of another item ("Duplicate request detected...") | Two items carried the same RequestId: the second one replays the first and posts nothing. Give every item its own RequestId. |
An item fails with DuplicateRequest | The item's RequestId was already used for a different operation. Send a new one. |
An item fails with RequestInProgress, IsRetryable true | The same RequestId is running in another call. Retry once it completes. |
An item with PreviewMode true | Gets its single operation's answer: a validation-only preview for the five operations that have one, PreviewUnsupported for every other. |
Items fail with LicenseNotValid | The license was found not valid; resend unchanged once it is renewed. |
Async operations. A refused submission returns Success false, Status 4, an all-zero TrackingId and
the reason; nothing is queued.
ErrorCode | Meaning and what to do |
|---|---|
ValidationFailed | A missing member, a pair that is not supported ("The operation ... is not supported for async execution."), a payload that cannot be read as the operation's request, or a payload without RequestId or with an unknown LegalEntityId. Correct and resubmit. |
OperationDisabled | An administrator disabled the pair in the async operation registry. Call the operation directly, or ask for it to be enabled. |
AccessDenied | "You do not have access to the service operation ..." The caller lacks the target operation's privilege. |
DuplicateRequest | The submission's RequestId was used for another service operation. |
LicenseNotValid | Submissions are refused while the license is not valid; IsRetryable is true. |
- Still
Queuedafter several minutes: nothing picked the operation up. Check that the batch server is running and the Lattice Async Operation Processing background process is enabled (prerequisite 2). Failedafter it ran: the operation goes to the dead-letter queue. A failure the target operation reports as retryable (IsRetryabletrue, for exampleTransientRuntime) is retried automatically by the Lattice dead-letter retry background process; any other failure is parked there for a person. Open System administration > Inquiries > Lattice > Integration operations > Integration operations console to retry, hold, fix and resubmit, or discard it. A replay reuses the payload'sRequestId, so it never posts twice. A submitter who lost access to the target operation, or a pair disabled after the submission, also fails the operation (AccessDenied,OperationDisabled).- Unknown tracking id:
getAsyncOperationStatusreturnsSuccessfalse,Status7(NotFound) andErrorCodeDocumentNotFound. Tracking rows of finished operations are removed by the Lattice integration log cleanup background process after 30 days by default. - Never give the payload a new
RequestIdto retry a posting: if the first attempt posted, that posts it a second time. Resubmitting with a new submissionRequestIdbut the same payloadRequestIdis safe: a posting that succeeded replays its recorded result, and one that failed runs again.
Reference
- API reference, section 19 (Bulk Operations), section 21 (Async Operations) and section 23 (Process Automation).
- Endpoint payload specification: request payloads for every operation.
- Security model:
MGCLatticeAsyncOperationServiceand the target privileges. - Integration operations: the dead-letter queue, the async operation registry and the background processes.
- Post a journal exactly-once:
RequestIdand idempotency. - Track documents and read data: the monitoring entities.