Skip to main content

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​

  1. 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 by MGCLatticeIntegrationServiceMonitoringDuty (all three roles).
    • The other Lattice entities are granted by MGCLatticeDataEntitiesView (read) and MGCLatticeDataEntitiesMaintain (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.

  2. Nothing here is license-gated. Status queries and entity reads keep working when the license is not valid.

  3. The client is connected (Connect an integration client).

Steps​

  1. Pick the status query for the document.

    DocumentOperationService / service groupDocumentId isDocumentStatusStatusDetails names
    Sales ordergetSalesOrderStatusMGCLatticeSalesOrderPostingService / MGCLatticeAccountsReceivableServiceGroupthe sales order numberSalesStatus symbol, for example Backorder, Delivered, InvoicedSalesStatus, CustAccount, ConfirmDate, PackingSlipDate, InvoiceDate
    Purchase ordergetPurchaseOrderStatusMGCLatticePurchaseOrderPostingService / MGCLatticeAccountsPayableServiceGroupthe purchase order numberPurchStatus symbol, for example Backorder, Received, InvoicedPurchStatus, OrderAccount, ConfirmDate, ReceiptDate, InvoiceDate
    Production ordergetProductionOrderStatusMGCLatticeProductionOrderPostingService / MGCLatticeProductionServiceGroupthe production order numberProdStatus symbol, for example Released, StartedUp, ReportedFinishedProdStatus, ItemId, QtySched, QtyStartedUp, QtyReportFinished, QtyErrorCur
    Ledger journalgetJournalStatusMGCLatticeGeneralLedgerJournalService / MGCLatticeGeneralLedgerServiceGroupthe journal number (not the journal name)Posted or NotPostedPosted, JournalName, Description, NumberOfLines
    WorkflowgetWorkflowStatusMGCLatticeWorkflowActionService / MGCLatticeWorkflowServiceGroupthe workflow correlation id, the source record's record id, or a purchase requisition numberthe tracking status, for example Pending, Completed, Cancelled, FaultedTrackingStatus, WorkflowType, WorkflowCorrelationId, one PendingWorkItem_<RecId> per pending work item, FaultMessage when faulted

    The date details appear only once the document has that posting, and are written yyyy-MM-dd.

  2. Call it. Every status query takes the same request. RequestId is 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, send ExternalSystem and DocumentIdExternalKey to 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.

  3. Look up what happened to a request. Every call, including replays and refusals, is a row in the monitoring entity LatticeServiceCallLogs. Filter on the RequestId you sent (GUIDs are not quoted):

    GET https://<your-environment>/data/LatticeServiceCallLogs?$filter=RequestId eq 9b2d5f60-1c34-4e8a-b7d2-0a4c6e8f1b23

    Each row carries ServiceName, OperationName, LegalEntityId, CalledBy, Success, Status, ErrorCode, Message, DocumentId, PostedDocumentId, DurationMs and IsPreview. The idempotency claim behind the request is in LatticeServiceIdempotencyLogs (same filter; a claim still Processing an hour later needs attention), and an async operation is in LatticeAsyncOperationTrackingRecords (filter on TrackingId). 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

  4. Read company-specific data in a named legal entity. Most entities belong to a legal entity. Add cross-company=true and filter on dataAreaId; without cross-company=true the 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 PATCH or DELETE whose key names a dataAreaId. Shared entities, such as LatticeExternalSystems, the monitoring entities and PurchaseRequisitionHeaders, take no dataAreaId. Use $select and $top to keep reads small. Data entity reference lists every Lattice entity with its entity set, company scope, key and fields.

  5. 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 example LatticeCustomerDocumentAttachments) return the files attached to customers, orders, invoices and projects, with the file content in Attachment.

How to verify​

  • A status query answers Success true with DocumentType and DocumentStatus filled for a document that exists in LegalEntityId.
  • The call log row for your RequestId agrees with the response you received, and CalledBy is 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 seeCause 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 entityStatus 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 trueA runtime fault; retry the query.
An OData read returns an empty value for data that existsThe read ran in the default company: add cross-company=true.
HTTP 400 on a filterA GUID was quoted, or an enum was compared to a plain string; use the forms shown in step 3.
HTTP 403 on an entityThe 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 madeThe 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​