API Process

Prev Next

Process

This page describes how to use the E-Invoice API to create master data (customers, vendors) and documents (sales/purchase invoices and credit memos) in Business Central, and how to combine requests using $expand to reduce round trips. For setup fields referenced below, see API Setup.

The general pattern is the same across entities: create the master record (customer/vendor) with a template auto-assigned, then create documents against it — most address and partner fields are filled automatically from the master record, and lines/attachments can be added in the same request via $expand.

Common scenarios

  • Onboard a new customer with an auto-assigned template and default dimensions → see Customers
  • Onboard a new vendor with an auto-assigned template, default dimensions, and a bank account → see Vendors
  • Create a sales or purchase document with its lines in one request → see Sales Documents / Purchase Documents
  • Attach a PDF or contract to a document → see the Expand methods tables below
  • Post many records at once (e.g. journal lines) without one request per record → see $batch requests
  • Decide where dimensions should live (Business Central vs. your external system) and how to post them efficiently on large documents → see Dimensions strategy
  • Check for VAT mismatches between your system and BC → see Total sums checks under Sales Documents

$batch requests

When you need to create or update many records in one go — for example, importing a batch of general journal lines from an external system — send them together as a single $batch request instead of one call per record. This reduces network round trips and lets Business Central process the whole set together.

  • A single $batch call supports up to 100 operations. If you have more, split them across multiple batch requests.
  • Each operation inside the batch is evaluated on its own — a failure in one operation does not automatically roll back the others, so check the individual response status for each operation in the batch response.

Customers

New customers are created using the customer API, providing only the information specific to that customer. Generic information — such as posting groups — comes from a Customer Template, which is assigned automatically based on the country in the request, according to the templates defined in API Setup.

If you have more templates than the three defaults (Local, EU, Foreign), you can assign a specific one directly in the request instead of relying on auto-assignment: set customerTemplateCode in the API request, and unmark Assign Default Template in E-Invoice Setup so your value isn't overwritten.

Default dimensions can be assigned in the same request the customer is created, using $expand=defaultDimensions — this only applies where the customer template doesn't already define that dimension.

Vendors

New vendors are created the same way, using the vendor API, providing only the information specific to that vendor. As with customers, a Vendor Template is assigned automatically based on country, according to the templates defined in API Setup.

If you have more templates than the three defaults (Local, EU, Foreign), set vendorTemplateCode directly in the API request and unmark Assign Default Template in E-Invoice Setup, the same way as for customers.

Default dimensions can be assigned in the same request the vendor is created, using $expand=defaultDimensions — this only applies where the vendor template doesn't already define that dimension.

In addition, Vendor Bank Accounts can be created together with the vendor, using the vendorBankAccount API.

Sales Documents Creation

Sales Invoices are created using the salesInvoice API. Most address fields (those starting with billTo, shipTo, sellTo) are filled automatically from the customer record, so you only need to send them when they differ from the customer's defaults. Use $expand to minimize the number of requests needed.

Sales Credit Memos are created the same way, using salesCreditMemo.

Total sums checks between BC and integrating system
Always include apiTotalAmountExclVAT and apiTotalAmountInclVAT in the request — these let Business Central verify its calculated totals against your system's. Rounding and total-amount calculation can differ between systems, so checking (and correcting, if needed) these amounts is essential to avoid VAT mismatch errors.

Expand methods

Document Lines Attachments
Sales Invoice salesInvoiceLine documentAttachment — for extra files like a signed Sales Contract; the file content itself is sent in a separate PATCH request
Sales Credit Memo salesCreditMemoLine documentAttachment

For a concrete example of this API in use, see the Json Collection in the Overview section.

Purchase Documents Creation

Purchase Invoices are created using the purchaseInvoice API, following the same pattern as sales: fields starting with payTo, shipTo, buyFrom are filled automatically from the vendor record, and only need to be sent when they differ.

Purchase Credit Memos are created the same way, using purchaseCreditMemo.

Expand methods

Document Lines Attachments
Purchase Invoice purchaseInvoiceLine documentAttachment
Purchase Credit Memo purchaseCreditMemoLine documentAttachment

Dimensions strategy

Before posting documents, determine where the dimension master data should reside — in Business Central, or in the external system:

  • If default dimensions are assigned to the customer, vendor, G/L Account, or Item, overriding them at the document-line level requires additional PATCH requests to modify the default values per line. For example, if a company invoices multiple services through the same G/L Account (type = "G/L Account") that require different dimensions, default dimensions should not be assigned to that account; each line should specify its own dimensions instead.
  • If no default dimensions are assigned, dimensions can be added directly to document lines (e.g. salesInvoiceLines) within the same request, using $expand with dimensionSetLines.

To assign default dimensions to a customer or vendor, use the defaultDimensions API, either within the same request as the master record (via $expand) or as a separate request. The required fields are:

  • dimensionCode — specifies the dimension code to be used.
  • dimensionValueIddimensionValueCode cannot be provided directly, as it is a read-only field. To obtain the dimensionValueId for a given value code, query the dimensionValues API filtered by dimensionCode and code (the value code), and use the returned id field.
Important

Requests containing many lines combined with expand methods increase processing time and complexity. For invoices with only a few lines, expanding both salesInvoiceLines and dimensionSetLines within a single request is acceptable. For invoices containing hundreds of lines, dimensions should instead be posted via a separate $batch request to reduce complexity.

FAQ

Customers/Vendors API

1. How do I assign payment terms for each customer/vendor?
Get all available payment terms with a GET request on the paymentTerms API, then set paymentTermsCode or paymentTermsId on the customer/vendor record. If multiple companies share the same payment terms codes, paymentTermsCode is usually more convenient. Once assigned, the payment term automatically carries over to sales documents and determines the due date.

2. Where can I store additional information from my integrating system?
Use the customerLink and vendorLink fields to store a reference number or a direct link back to the external system.

Sales Documents

1. How can I get a Sales Invoice printout from Business Central?
Use a separate GET request on pdfDocument. The report and layout are selected via Report Selections setup for that document type — if more than one report is defined, the first in sequence is used. See the Json Collection for a worked example.

2. Can I post Sales Invoice Lines in a separate request?
Yes, but we recommend using $expand to post the whole document at once, once you have a final version in your other platform — this reduces the number of requests. For invoices with many lines, consider $batch requests instead.