Scenario: Follow a document and read data back
Goal. After a call, find out where the document stands now (a sales order delivered, a purchase order invoiced, a production order reported as finished, a journal posted, a workflow waiting for an approver) and read Finance and Operations data and Lattice's own records of your calls, without screen access and without guessing from the HTTP response alone.
When to use. Whenever the external system needs the current state of a document it created or acted on, needs to reconcile what happened to a request (did it post, which document did it produce, why did it fail), or reads master and transaction data. Event-driven designs can be told about changes instead (React to business events); use this page for pull-style reads and checks.
Prerequisites
-
Security.
- The five status queries are granted by the module View privileges in
MGCLatticeIntegrationServiceQueryDuty, which all three Lattice roles hold. - The monitoring entities (
LatticeServiceCallLogs,LatticeServiceIdempotencyLogs,LatticeAsyncOperationTrackingRecords) are granted byMGCLatticeIntegrationServiceMonitoringDuty(all three roles). - The other Lattice entities are granted by
MGCLatticeDataEntitiesView(read) andMGCLatticeDataEntitiesMaintain(write), the cross-reference entities by the cross-reference duties. - Standard Microsoft entities (
SalesOrderHeadersV2,PurchaseRequisitionHeaders, ...) need standard Finance and Operations security; the Lattice roles do not grant them.
See Security model.
- The five status queries are granted by the module View privileges in
-
Nothing here is license-gated. Status queries and entity reads keep working when the license is not valid.
-
The client is connected (Connect an integration client).
Steps
-
Pick the status query for the document.
Document Operation Service / service group DocumentIdisDocumentStatusStatusDetailsnamesSales order getSalesOrderStatusMGCLatticeSalesOrderPostingService/MGCLatticeAccountsReceivableServiceGroupthe sales order number SalesStatussymbol, for exampleBackorder,Delivered,InvoicedSalesStatus,CustAccount,ConfirmDate,PackingSlipDate,InvoiceDatePurchase order getPurchaseOrderStatusMGCLatticePurchaseOrderPostingService/MGCLatticeAccountsPayableServiceGroupthe purchase order number PurchStatussymbol, for exampleBackorder,Received,InvoicedPurchStatus,OrderAccount,ConfirmDate,ReceiptDate,InvoiceDateProduction order getProductionOrderStatusMGCLatticeProductionOrderPostingService/MGCLatticeProductionServiceGroupthe production order number ProdStatussymbol, for exampleReleased,StartedUp,ReportedFinishedProdStatus,ItemId,QtySched,QtyStartedUp,QtyReportFinished,QtyErrorCurLedger journal getJournalStatusMGCLatticeGeneralLedgerJournalService/MGCLatticeGeneralLedgerServiceGroupthe journal number (not the journal name) PostedorNotPostedPosted,JournalName,Description,NumberOfLinesWorkflow getWorkflowStatusMGCLatticeWorkflowActionService/MGCLatticeWorkflowServiceGroupthe workflow correlation id, the source record's record id, or a purchase requisition number the tracking status, for example Pending,Completed,Cancelled,FaultedTrackingStatus,WorkflowType,WorkflowCorrelationId, onePendingWorkItem_<RecId>per pending work item,FaultMessagewhen faultedThe date details appear only once the document has that posting, and are written
yyyy-MM-dd. -
Call it. Every status query takes the same request.
RequestIdis required, but a query records no claim, so a fresh GUID per call is fine:POST https://<your-environment>/api/services/MGCLatticeAccountsPayableServiceGroup/MGCLatticePurchaseOrderPostingService/getPurchaseOrderStatus{"_request": {"RequestId": "4e5f6a7b-8c9d-4e0f-a1b2-c3d4e5f6a7b8","LegalEntityId": "USMF","DocumentId": "000016"}}Instead of
DocumentId, sendExternalSystemandDocumentIdExternalKeyto name the document by your own key (Use external keys). The answer:{"Success": true,"ErrorCode": 0,"Message": "Status retrieved for purchase order 000016.","DocumentId": "000016","DocumentType": "PurchaseOrder","DocumentStatus": "Received","LastModifiedDateTimeUtc": "2026-10-07T09:12:44Z","StatusDetails": [{ "Name": "PurchStatus", "Value": "Received" },{ "Name": "OrderAccount", "Value": "US-101" },{ "Name": "ConfirmDate", "Value": "2026-10-06" },{ "Name": "ReceiptDate", "Value": "2026-10-07" }],"Errors": []}The sales, purchase, production and journal queries read the committed document, not a server's cache, so a query straight after a posting reports the new state.
-
Look up what happened to a request. Every call, including replays and refusals, is a row in the monitoring entity
LatticeServiceCallLogs. Filter on theRequestIdyou sent (GUIDs are not quoted):GET https://<your-environment>/data/LatticeServiceCallLogs?$filter=RequestId eq 9b2d5f60-1c34-4e8a-b7d2-0a4c6e8f1b23Each row carries
ServiceName,OperationName,LegalEntityId,CalledBy,Success,Status,ErrorCode,Message,DocumentId,PostedDocumentId,DurationMsandIsPreview. The idempotency claim behind the request is inLatticeServiceIdempotencyLogs(same filter; a claim stillProcessingan hour later needs attention), and an async operation is inLatticeAsyncOperationTrackingRecords(filter onTrackingId). These three entities are shared across legal entities and read-only. Enums are filtered with their qualified name and returned as member names:GET https://<your-environment>/data/LatticeServiceCallLogs?$filter=Status eq Microsoft.Dynamics.DataEntities.MGCLatticeServiceCallStatus'Failed'&$orderby=StartDateTimeUtc desc&$top=50 -
Read company-specific data in a named legal entity. Most entities belong to a legal entity. Add
cross-company=trueand filter ondataAreaId; withoutcross-company=truethe filter runs inside the caller's default company and silently returns nothing for any other legal entity:GET https://<your-environment>/data/LatticeOpenSalesOrderLines?cross-company=true&$filter=dataAreaId eq 'usmf' and CustomerAccount eq 'US-001'The same applies to the standard entities, for example the confirmation lines of a sales order:
GET https://<your-environment>/data/SalesOrderConfirmationLines?cross-company=true&$filter=dataAreaId eq 'usmf' and SalesOrderNumber eq '000698'and to a
PATCHorDELETEwhose key names adataAreaId. Shared entities, such asLatticeExternalSystems, the monitoring entities andPurchaseRequisitionHeaders, take nodataAreaId. Use$selectand$topto keep reads small. Data entity reference lists every Lattice entity with its entity set, company scope, key and fields. -
Check a document's keys and attachments. The cross-reference entities return the keys stored for a record (
LatticeSalesOrderCrossReferences?cross-company=true&$filter=dataAreaId eq 'usmf' and SalesOrderNumber eq '000698'), and the document attachment entities (for exampleLatticeCustomerDocumentAttachments) return the files attached to customers, orders, invoices and projects, with the file content inAttachment.
How to verify
- A status query answers
SuccesstruewithDocumentTypeandDocumentStatusfilled for a document that exists inLegalEntityId. - The call log row for your
RequestIdagrees with the response you received, andCalledByis your integration user. - In the client, the same records are on System administration > Inquiries > Lattice > Services > Service call log and on the integration operations workspace (System administration > Inquiries > Lattice > Integration operations > Integration operations).
When it goes wrong
| What you see | Cause and fix |
|---|---|
Success false, ErrorCode DocumentNotFound (2), "Sales order ... was not found." | No such document in LegalEntityId. Check the number and the legal entity. |
ValidationFailed (1) with "DocumentId ... is required." | Send DocumentId, or ExternalSystem with DocumentIdExternalKey. |
ValidationFailed with "RequestId is required." or an unknown legal entity | Status queries need RequestId and an existing LegalEntityId like every other call. |
ValidationFailed with "No ... has key ... in external system ..." | The key does not resolve; see Use external keys. |
TransientRuntime (6), IsRetryable true | A runtime fault; retry the query. |
An OData read returns an empty value for data that exists | The read ran in the default company: add cross-company=true. |
| HTTP 400 on a filter | A GUID was quoted, or an enum was compared to a plain string; use the forms shown in step 3. |
| HTTP 403 on an entity | The user's roles do not grant that entity: Lattice roles for Lattice entities, standard roles for standard entities. |
| No call log row for a call you made | The operation's logging level is set to Errors only or Off on System administration > Setup > Lattice > Service operation logging configuration, or the row is older than the retention window (90 days by default). |
Reference
- API reference, section 20 (Status Query Operations) and section 24 (OData Monitoring Entities).
- Data entity reference: every Lattice entity.
- Data entities: browsing the OData surface, metadata and Postman or OpenAPI exports.
- Integration operations: the service call log and the daily check.
- Workflow approvals:
getWorkflowStatusin a workflow. - Batch and async operations:
getAsyncOperationStatus.