The Business Central API and OData services
By Emil Björk · Microsoft business apps consultant, Gothenburg
How external systems talk to Business Central — the v2.0 REST API, OData web services, bound actions, and call limits.
On this page (10)
Business Central has a first-class HTTP API that's the canonical way to integrate it with anything outside the product. The API is what powers Power Automate connectors, mobile apps, Power Pages portals, and partner integrations.
The v2.0 REST API. Microsoft maintains an OpenAPI-described REST API at /api/v2.0/companies({id})/... that covers the most-used entities: customers, vendors, items, sales orders, sales invoices, purchase orders, journals, GL accounts, and many more. Each entity supports the standard verbs (GET, POST, PATCH, DELETE) and OData query semantics ($filter, $select, $expand, $top, $skip). Pagination follows the OData convention with @odata.nextLink.
Custom API pages
When the v2.0 API doesn't expose what you need, partners or in-house developers write AL API pages. An API page targets a single table, lives at a customer-defined publisher / group / version path (e.g. /api/contoso/myapp/v1.0/...), and lets you control exposed fields, behaviour, and security.
Bound actions
Beyond reading and writing entities, API pages can expose bound actions — e.g. post a sales order, cancel an invoice, apply a payment. Actions invoke AL code and return a result, which is how you trigger BC's transactional behaviour rather than just writing fields.
OData v4 web services
A second, older surface exposes any page or query as an OData endpoint when published from the Web Services list. OData is read-and-write, less RESTful than v2.0, and useful for ad-hoc Excel pulls or Power BI imports. Some integration teams wrap this OData surface in GraphQL for their own front ends, though that's a client-side convenience rather than something BC exposes natively.
Authentication
SaaS APIs authenticate with Microsoft Entra ID OAuth 2.0 — usually via service-to-service flows with an app registration granted Dynamics 365 Business Central application permissions. Basic Auth is deprecated.
Call limits
Each tenant has API throughput limits: requests per minute per user, and an overall throughput allowance. Going over returns HTTP 429 with a Retry-After header. Well-behaved integrations honour the header, batch where possible, and prefer $expand over multiple round trips.
Webhooks
Business Central can push change notifications to a registered subscriber endpoint when records change, avoiding polling. Subscriptions auto-expire and must be renewed — build the renewal into your integration rather than discovering the expiry in production. The mechanics are covered in webhooks in Business Central.
URL anatomy — environments and companies
Two things trip up every first integration. First, the URL carries the environment name: https://api.businesscentral.dynamics.com/v2.0/{tenant}/{environment}/api/v2.0/... — an integration built against sandbox doesn't reach production by accident, which is a feature, but it means environment names belong in configuration, never in code. Second, almost everything in BC lives per company. The API root lets you list companies, and every entity call is scoped to one company ID. A multi-company tenant needs the integration to loop companies or be told which one it serves; assuming "the" company is the classic day-one bug in a multi-company setup.
Performance patterns that actually matter
The throughput limits aren't generous, so integration design matters more than in most SaaS APIs:
- Filter server-side, always.
$filterand$selectcut both payload and server work. Pulling a full table to filter client-side is the top cause of 429s. - Use
$expandinstead of N+1 calls. One request for sales orders with$expand=salesOrderLinesbeats a call per order by an order of magnitude. - Read deltas, not snapshots. Filter on
lastModifiedDateTime(present on v2.0 entities) to sync only what changed since the last run, or use webhooks to be told. - Batch writes. The
$batchendpoint packs multiple operations into one request and can run them in a single transaction — essential for journal lines that must post together. - Respect
Retry-After. On 429, wait the stated time and retry. Hammering through the backoff extends the penalty window.
For genuinely heavy reads (BI-scale extraction, warehouse loads), the API is the wrong tool regardless of tuning — that's what BC's Fabric/lakehouse paths and scheduled exports are for; keep the API for operational integration.
Choosing a surface — the decision in practice
The strategic order: v2.0 standard API first — versioned, documented, stable across release waves, and what Microsoft performance-tests. Custom API pages second, when you need custom fields or tables — they inherit the same versioned, RESTful behaviour and remain under your control. Published OData page endpoints last: they expose whatever the page shows, which means a page redesign or personalisation quirk can silently change your integration contract, and page-based endpoints drag UI logic through the server with every call. They earn their keep for ad-hoc Excel and Power BI pulls where a query object endpoint delivers joined, aggregated data efficiently — not as the backbone of a system integration. And SOAP, still technically present on-premise, belongs in migration plans only.
Best practice
Use v2.0 first, custom API pages second, OData last, basic auth never. Put a queue or integration layer between BC and any chatty upstream system, log correlation IDs from response headers when raising support cases, and test against a sandbox that actually resembles production data volumes — the API that flies with 50 demo items behaves differently against 200,000 SKUs.
Further reading
Related guides
- Business Central web servicesThe classic OData and SOAP web services in Business Central — how they differ from the v2.0 API, and when to use them.
- Business Central CI/CD with AL-GoHow AL-Go for GitHub turns an AL extension repo into a build-test-deploy pipeline — secrets, environments, and continuous delivery.
- Isolated storage and secrets in ALHow AL extensions store secrets safely — IsolatedStorage scopes, Azure Key Vault integration.
- The AL debugger in Business Central — a deep diveHow the AL debugger works for developing Business Central extensions — VS Code integration, snapshot debugging, attaching to sessions.
- The AL test frameworkWriting automated tests in AL — test codeunits, test runners, TestPage, mocking, test isolation, and CI with AL-Go.
Browse every guide in Business Central or just AL & development.
Was this helpful?
Signals which guides land and which need work. No account, no comment box — corrections go through the contact page.
Spot something wrong or want a topic covered? Send a correction or a topic request — both are welcome.