← All postsDevelopment ยท 3 November 2026

Integrating with Business Central: APIs done properly

Every integration with Business Central should go through the API. Most still do not, and the ones that do often do it badly. OAuth, the standard v2.0 APIs, custom API pages, webhooks, throttling, idempotency and the SOAP endpoints that are going away: what a system integrator needs to know in 2026.

Business Central online has one supported way in and out: HTTPS, OAuth 2.0, and REST APIs. Everything else (direct SQL, the old web-service user keys, page-based SOAP) is deprecated, blocked, or about to be. If you are a system integrator connecting a web shop, a WMS, a payroll system, an EDI provider or a data warehouse to Business Central, this is the shape of it done properly.

Authentication: OAuth 2.0, service-to-service

Register an application in the customer's Entra ID tenant, grant it the Business Central API permission, and register it inside Business Central (Entra Applications page) with the permission sets it needs, and nothing more. Client credentials flow, token from the Microsoft identity platform, bearer token on every call, refreshed before expiry. No user accounts for integrations, no shared passwords, no web-service access keys (removed in 2022). One registration per integration, so that when one is retired or compromised it can be revoked on its own.

The standard APIs first

Microsoft publishes versioned APIs (currently v2.0) for the common entities: customers, vendors, items, sales orders and invoices, purchase orders and invoices, journals, G/L entries, dimensions, and more. They are stable across release waves, documented, and they handle the posting logic for you. Use them before writing anything. The URL shape is /api/v2.0/companies({id})/salesOrders, with OData query options for filtering, selecting and expanding.

Custom API pages for everything else

When the standard API does not cover a field or a table (your extension's fields, a custom table, a specific projection), build an API page in AL: PageType = API, with a publisher, group and version in the URL, exposing exactly the fields the integration needs. Version it; when the shape changes, publish v2.0 alongside v1.0 rather than changing v1.0 under the integration's feet. Never expose a list page as OData for an integration; it is unversioned, it changes when the page does, and it is slow.

Reads: filter, select, page

Every read uses $filter to restrict rows, $select to restrict fields, and handles @odata.nextLink paging. Pulling the whole item ledger every fifteen minutes to find what changed is the most common integration performance problem we see. Use lastModifiedDateTime filters (the standard APIs have it; add SystemModifiedAt to custom ones) for delta reads, or better, use webhooks.

Webhooks for change notification

Business Central can call your endpoint when a record on an API page changes: subscribe with a notification URL, respond to the handshake, renew the subscription before it expires (they do), and then fetch the changed records when notified. It turns a polling integration into an event-driven one and it is the right pattern for "tell the WMS when a sales order is released". Handle notifications idempotently; they can arrive more than once.

Writes: batches, idempotency, and let Business Central post

Throttling and resilience

Business Central online enforces limits on concurrent requests and on request rate per tenant, and returns 429 (too many requests) or 503 with a Retry-After header when you hit them. Your client backs off and retries with jitter; it does not hammer. Long operations go through a job queue on the Business Central side rather than a long-running API call. Design for the Business Central environment being unavailable for an hour (it will be, during an update): queue outbound messages, replay them, and make the business process survive a delay.

Environments and companies

The URL includes the environment name and the API includes the company ID. Every integration is configured per environment, so that the sandbox integration talks to the sandbox web shop and never the live one. A refreshed sandbox is a copy of production including any stored integration settings, which is how sandboxes end up sending real emails and real orders. Disable outbound integrations on refresh.

What is going away

Page-based SOAP endpoints on Microsoft's own pages are now disabled by default and will be removed. The old beta APIs are gone. Basic authentication is gone. OData on list pages is tolerated but unsupported for integration. If an existing integration uses any of these, it is on a clock, and the release wave checklist is where it gets caught.

The checklist we hand to integrators

  1. OAuth client credentials, one app registration per integration, least-privilege permission set.
  2. Standard v2.0 APIs where they exist; versioned custom API pages where they do not; never list-page OData.
  3. Delta reads by modified timestamp or webhooks; never full-table polling.
  4. External ID on every created record; idempotent creates; ETags on updates.
  5. Posting through API actions, never ledger writes.
  6. Back-off on 429 and 503; queue and replay outbound; survive an hour of downtime.
  7. Per-environment configuration; outbound disabled on sandbox refresh.
  8. Telemetry on both sides, correlated by a request ID.

Integrations are where most project cost hides and most go-lives go wrong. If you are an integrator new to Business Central, or a business with an integration that keeps falling over, we are happy to review it against this list: get in touch.

Talk to us
Want this done in your Business Central?
Book a 30 minute callGet the monthly newsletter

More from the blog