Skip to main content

Scenario: Post a pending vendor invoice

Goal. Vendor invoices are entered as pending vendor invoices (by an invoice-capture tool through the standard entities, or by AP clerks in D365) and your system decides when each one is posted. Lattice posts a pending invoice the way Post on the Pending vendor invoices page does: the standard invoice posting runs on the saved invoice, so invoice matching, invoice policies, the vendor invoice approval workflow and every posting check are D365's own. The response tells you the voucher the invoice was posted on.

When to use. Invoices with or without purchase order lines that are reviewed, matched or approved in D365 before they post, for example an OCR or e-invoicing tool that creates the invoices and a scheduler that posts the approved ones. For a purchase order invoice that needs no review, post it in one call with invoicePurchaseOrder (Receive and invoice a purchase order). For invoices that are registered first and approved in a journal, see Register vendor invoices and approve them later. To pay the posted invoice, continue with Pay vendors.

Prerequisites​

  1. Security. MGCLatticeAccountsPayableServiceMaintain grants postPendingVendorInvoice and its batch variant. It is in duty MGCLatticeIntegrationServiceOperationsDuty (integration operator and administrator roles). It posts vendor invoices to the ledger, so grant it only to integration identities that may post payables. Creating the pending invoice through the standard VendorInvoiceHeaders, VendorInvoiceLines and InvoiceSubLinesV2 entities needs D365's own privileges for them. See Security model.
  2. D365 configuration in the legal entity:
    • the vendor (USMF US-101, sales tax group No-Tax) with a posting profile;
    • for a line without a purchase order, a procurement category with an expense account (Inventory management > Setup > Posting > Posting, Purchase order tab, Purchase expenditure for expense by category). USMF UTILITIES (hierarchy "Procurement - Office Supplies") posts to its own account 605160. Under budget control, the account needs available funds: in USMF the selling expense accounts such as 601300 are refused for lack of funds;
    • for a purchase order invoice, a confirmed purchase order, with its product receipt posted when the item uses three-way matching;
    • when a vendor invoice approval workflow applies to the invoice, the invoice approved by it before you post.
  3. Lattice. A valid license (an expired or invalid one refuses the call with LicenseNotValid). To name the vendor by your own key, send VendorAccountExternalKey with ExternalSystem (Use your own keys).

Steps​

The operation is postPendingVendorInvoice on MGCLatticeVendorInvoiceService in service group MGCLatticeAccountsPayableServiceGroup. Send a POST with an OAuth 2.0 bearer token and the request in _request (see Trial and day-one guide).

  1. Create the pending invoice. Skip this step when the invoice was entered in D365 (Accounts payable > Invoices > Pending vendor invoices). Otherwise create the header:

    POST https://<your-environment>/data/VendorInvoiceHeaders
    {
    "dataAreaId": "usmf",
    "InvoiceAccount": "US-101",
    "VendorAccount": "US-101",
    "InvoiceNumber": "UT-2026-1008",
    "InvoiceDate": "2026-10-08T12:00:00Z",
    "Date": "2026-10-08T12:00:00Z",
    "Currency": "USD",
    "InvoiceDescription": "Utilities October"
    }

    The answer carries the new invoice's HeaderReference. Then add the lines with that HeaderReference. A line without a purchase order names a procurement category:

    POST https://<your-environment>/data/VendorInvoiceLines
    {
    "dataAreaId": "usmf",
    "HeaderReference": "<HeaderReference>",
    "InvoiceLineNumber": 1,
    "ProcurementCategoryName": "UTILITIES",
    "LineDescription": "Electricity, October",
    "ReceiveNow": 1,
    "UnitPrice": 125.00,
    "NetAmount": 125.00,
    "Unit": "ea",
    "Currency": "USD"
    }

    For a purchase order invoice, send PurchaseOrderNumber on the header, and on each line PurchaseOrder, PurchLineNumber, ItemNumber, ReceiveNow, UnitPrice and NetAmount instead of the category. To match the line to its product receipts, add InvoiceSubLinesV2 rows (ProductReceiptNumber, InvoiceLineReference = the header reference, PurchaseOrder, InvoiceLineNumber, PurchaseOrderLineNumber, PurchaseQuantity).

  2. Review, match or approve the invoice in D365 when your process needs it. An invoice on hold, in the approval workflow, or open on someone's screen is refused until it is released, approved or closed.

  3. Post it. Name the invoice by its HeaderReference:

    POST https://<your-environment>/api/services/MGCLatticeAccountsPayableServiceGroup/MGCLatticeVendorInvoiceService/postPendingVendorInvoice
    {
    "_request": {
    "RequestId": "8d1f5b3a-6c2e-4e97-a0b4-2f7c9e1d5a68",
    "LegalEntityId": "USMF",
    "UserContext": "ap-scheduler",
    "HeaderReference": "<HeaderReference>"
    }
    }

    or by VendorAccount and InvoiceNumber ("VendorAccount": "US-101", "InvoiceNumber": "UT-2026-1008"), not both. The invoice posts on its own posting date and invoice date (the Accounts payable parameter Posting date adjustment applies as it does on the page), completely or not at all: when D365 refuses it, the invoice stays pending as it was.

  4. Read the result. DocumentId is the vendor's invoice number and PostedDocumentId the voucher of the posted invoice, which is also the voucher of the vendor transaction: Pending vendor invoice UT-2026-1008 of vendor US-101 posted with voucher APINV000214. Warnings and information from the posting are in Warnings and InformationalMessages.

The bulk variant postPendingVendorInvoiceBatch takes { "_requests": [ ... ] }, each item a full request with its own RequestId, and answers one result per item, so a scheduler can post the day's approved invoices in one call (see Batch and async operations). The operation is synchronous only and has no preview.

How to verify​

  • The response: Success true, Status 3, DocumentId the invoice number, PostedDocumentId the voucher.
  • No longer pending: VendorInvoiceHeaders lists only invoices that are not posted, so GET https://<your-environment>/data/VendorInvoiceHeaders?cross-company=true&$filter=dataAreaId eq 'usmf' and HeaderReference eq '<HeaderReference>' returns nothing.
  • The vendor transaction: LatticeVendorTransactions with $filter=VendorAccountNumber eq 'US-101' and InvoiceId eq 'UT-2026-1008' and dataAreaId eq 'usmf'&cross-company=true has the invoice on the returned Voucher.
  • A purchase order invoice: the order is Invoiced (PurchaseOrderHeadersV2, PurchaseOrderStatus, or getPurchaseOrderStatus) once every line is invoiced.
  • In D365: the invoice is gone from Pending vendor invoices, and Accounts payable > Inquiries and reports > Invoices > Invoice journal shows it with the returned voucher.
  • The call: System administration > Inquiries > Lattice > Services > Service call log, or LatticeServiceCallLogs filtered on your RequestId.

When it goes wrong​

A failed call answers Success false, Status 4, an ErrorCode and the message "Posting the pending vendor invoice failed due to validation or business rule constraints."; the reasons are in Errors. The invoice stays pending.

ErrorCodeTypical cause (text in Errors)What to do
ValidationFailed (1)No RequestId or unknown LegalEntityId; "Name the pending vendor invoice by HeaderReference, or by VendorAccount together with InvoiceNumber."; named both ways; an unknown vendor or vendor key; "Vendor US-101 has 2 pending vendor invoices with invoice number ... (header references ...). Send the HeaderReference of the invoice to post."Correct the request and resend.
DocumentNotFound (2)"No pending vendor invoice has header reference ... in legal entity ..."; "Vendor ... has no pending vendor invoice ... in legal entity ..."Check the reference or the vendor and invoice number.
InvalidStatus (3)"Vendor invoice ... of vendor ... is already posted with voucher ..."; open for editing or being posted in another session; included in automated invoice processing; on hold; in the approval workflow, or a vendor invoice workflow applies and the invoice is not approved (the message names the workflow status and the workflow)Close, release, exclude or approve the invoice in D365, then resend. An invoice already posted needs nothing more.
BusinessRule (4)D365 refused the posting: matching discrepancies that need approval, invoice policies, a closed period, a duplicate invoice number, missing accounts, no available budget funds; its messages are in ErrorsFix the invoice or the setup in D365, then resend.
PreviewUnsupported (10)PreviewMode trueSend without PreviewMode. Nothing was run.
TransientRuntime (6)A runtime fault; IsRetryable trueResend with the same RequestId.
LicenseNotValid (12)The Lattice license is expired or invalidRenew the license, then resend.

Retries are safe. Resending a successful request with the same RequestId posts nothing again: the answer repeats the original voucher with the message Duplicate request detected. Original request processed at .... A new RequestId for an invoice that already posted is refused with InvalidStatus and names its voucher.

Reference​