Business Central API errors
By Emil Björk · Microsoft business apps consultant, Gothenburg
Business Central API and OData errors decoded — Authentication_InvalidCredentials, BadRequest_ResourceNotFound, Internal_CompanyNotFound, Request_EntityChanged, Application_DialogException, 429 limits, custom API 404s.
Business Central's API returns errors as a JSON body with a code and a message, and the codes are more useful than the HTTP status. This reference covers the ones that recur in integration work — authentication, addressing, concurrency, validation, limits, and custom API publishing — with what each actually means. For the API itself, start with Business Central API and OData; for web services more broadly, Business Central web services.
Reading an API error
Every failed call returns something like:
{
"error": {
"code": "Application_DialogException",
"message": "Posting Date is not within your range of allowed posting dates. CorrelationId: …"
}
}
The code says which family the error belongs to; the message is usually the same text a user would see in the client. The CorrelationId is what Microsoft support and your telemetry need — log it on every failure.
Authentication and authorisation
401 — Authentication_InvalidCredentials / Authentication_MissingCredentials
Symptom. Every call fails; Postman with a user token might work while your service does not.
Cause. In order of frequency: the token was requested for the wrong scope (it must be https://api.businesscentral.dynamics.com/.default); the token is for a different tenant than the environment; the Authorization header is missing or malformed; or, for service-to-service authentication, the app registration has not been added in Business Central under Microsoft Entra Applications with a permission set and with consent granted by an admin.
Fix. Decode the token (jwt.ms) and check aud and tid. Register the app in Business Central, assign permission sets (for example D365 BUS FULL ACCESS or a custom set), and grant consent from the same page.
Prevention. One app registration per integration with the least permission set that works, and a checklist that includes the Business Central-side registration — it is the step every new integration forgets.
403 — Forbidden / user status errors
Cause. The user or app is known but disabled, has no licence, or lacks permission on the object. For service principals, the entry on the Microsoft Entra Applications page has State set to Disabled, or its permission set does not cover the table.
Fix. Enable the entry; use Effective Permissions on the user to see what the permission set grants. See Business Central permissions and security.
Addressing
404 — BadRequest_ResourceNotFound
Symptom. The environment responds, but the resource is not found.
Cause. A wrong segment in the URL: the environment name, the API route (/api/v2.0/ for the standard API, /api/<publisher>/<group>/<version>/ for custom), the entity set name (plural: customers, salesInvoices), or an id that does not exist. Also the classic: the company id segment points at a company in a different environment.
Fix. Walk the URL: https://api.businesscentral.dynamics.com/v2.0/{tenant}/{environment}/api/v2.0/companies should list companies; then companies({id})/customers. Compare each segment with what that call returns.
404 — Internal_CompanyNotFound
Cause. The company id or name in the URL is wrong for this environment, or the company was renamed. Copying an environment gives companies new ids.
Fix. Call /companies and use the id it returns; store company ids per environment, never hard-code them.
Prevention. Environment-specific configuration for every integration, refreshed after any environment copy — see Business Central environments.
400 — "The property 'X' does not exist on type 'Microsoft.NAV.customer'"
Cause. A field name in $select, $filter, $orderby, or the body that is not in the API's contract, or has the wrong case (API field names are camelCase: displayName, not DisplayName).
Fix. Read the entity's metadata at /api/v2.0/$metadata and use the exact names.
405 — BadRequest_MethodNotAllowed
Cause. A verb the endpoint does not support: DELETE on a posted document, PATCH on a read-only API page, POST to a bound action without the action name.
Fix. Check the API page's Editable, InsertAllowed, ModifyAllowed, and DeleteAllowed properties, and call bound actions as POST …/Microsoft.NAV.post.
415 — Unsupported_MediaType / BadRequest_MissingContentType
Cause. A POST or PATCH without Content-Type: application/json.
Fix. Set the header.
Concurrency and keys
409 — Request_EntityChanged: "Another user has already changed the record…"
Symptom. PATCH or DELETE fails intermittently.
Cause. Business Central requires an If-Match header carrying the @odata.etag from the GET; if the record's etag has changed since, the write is refused. Integrations that GET a batch and PATCH later hit this whenever a user edits in between.
Fix. Re-read, take the new etag, retry once. If-Match: * overwrites unconditionally — acceptable for master data the integration owns, dangerous for anything users also edit.
Prevention. Keep read-to-write windows short and make the integration the single writer for the fields it manages.
400 — Internal_EntityWithSameKeyExists: "The record in table X already exists"
Cause. A POST with a key (number, code) that already exists, or a number series that handed out a used number.
Fix. Look up by the business key before creating; treat POST as upsert. Idempotency in Dynamics 365 integrations covers the pattern.
400 — Application_RecordNotFound / Internal_RecordNotFound
Cause. A reference in the body — customerNumber, itemId, paymentTermsId — points at a record that does not exist in this company.
Fix. Validate references against the target company; ids differ between companies and environments even when codes match.
Validation and business logic
400 — Application_DialogException
Symptom. The message is a Business Central business error: allowed posting dates, blocked customer, missing posting setup, "There is nothing to post".
Cause. The API ran the same validation and posting code a user would, and it failed for the same reason it would in the client.
Fix. Fix the data or the setup. The messages are decoded in posting setup errors and journal and document posting errors.
400 — Application_FieldValidationException
Cause. A field's OnValidate trigger rejected the value — an invalid VAT registration number, a date before the customer's start date, a code that does not exist in its lookup table.
Fix. Read the message; it names the field and the rule.
400 — Application_StringExceededLength
Cause. A value longer than the field: a 120-character address line into a 100-character field.
Fix. Truncate at the integration boundary; the $metadata document carries each field's MaxLength.
400 — Application_FilterErrorException
Cause. A $filter the OData layer could not translate — unsupported function, wrong type, unescaped quote in a value.
Fix. Escape single quotes by doubling them ('O''Brien'), use eq, ne, gt, lt, contains, startswith, and filter on fields the page exposes.
400 — "The request could not be understood by the server due to malformed syntax"
Cause. Invalid JSON — trailing comma, wrong quotes, a number where a string is expected, an enum value not in the allowed set.
Fix. Validate the body with a linter; check enum values against $metadata.
Limits and availability
429 — Too Many Requests
Symptom. Bursty integrations fail under load with Retry-After in the response.
Cause. Business Central online enforces operational limits per environment — a maximum number of concurrent API requests and a maximum request rate per rolling window — documented on Microsoft's operational limits page and revised from time to time.
Fix. Honour Retry-After with exponential backoff; reduce calls with $select and $filter, $batch for multiple operations, and delta sync via lastModifiedDateTime filters or webhooks rather than polling everything.
Prevention. Design for the limits from the first call; webhooks in Business Central and webhooks vs Service Bus cover the push alternatives.
503 / Internal_TenantUnavailable
Cause. The environment is being updated (the update window), restored, or is temporarily unavailable.
Fix. Retry after the window; integrations should tolerate a short outage at the scheduled update time.
Prevention. Align the environment's update window with a quiet period for integrations — see release waves.
Internal_ServerError / 500
Cause. An unhandled error inside Business Central — often a runtime error in an extension's API page or an event subscriber that fires during the API operation.
Fix. Find the CorrelationId in telemetry; the AL stack trace names the object. AL runtime errors covers the usual suspects.
Custom API pages
404 on a custom API that exists
Cause. The URL must match the page's APIPublisher, APIGroup, APIVersion, and EntitySetName exactly, and the page must have PageType = API, EntityName set, and the extension installed in that environment. A v1.0 in the page and v1 in the URL is a 404.
Fix. Compare the four properties with the URL segment by segment.
"The entity 'X' does not have a property 'Y'" on a custom page
Cause. The field's Caption is not what the API uses — the API name is the field's declared name in the page's field(name; Source) syntax, camelCase by convention.
Fix. Use the names from the page definition, and check $metadata.
Webhook subscription errors
Cause. "The provided callback URL could not be validated" means the receiving endpoint did not echo the validationToken query parameter within the timeout; subscriptions also expire after a few days and must be renewed, and repeatedly failing endpoints get their subscription dropped.
Fix. Implement the handshake exactly (respond 200 with the token as the body), renew before expiry, and answer notifications quickly — do the work asynchronously.
When the error is not from Business Central
A Power Automate flow or Logic App using the Business Central connector wraps these errors in its own; the code and message above are still inside the error body. Power Automate flow failures covers the wrapper. And if the call never reaches Business Central — DNS, proxy, TLS — the response has no error.code at all, which is itself the diagnostic.
Frequently asked questions
Why does my Business Central API call return 401 Authentication_InvalidCredentials?
- The token is for the wrong audience or the app is not known to Business Central. The OAuth scope must be https://api.businesscentral.dynamics.com/.default, the token must be for the same tenant as the environment, and for service-to-service calls the app registration must be added on Business Central's Microsoft Entra Applications page with a permission set and consent granted.
What does Request_EntityChanged (409) mean?
- Optimistic concurrency: the record changed since you read it. Every PATCH and DELETE must send an If-Match header with the @odata.etag you received, or If-Match: * to overwrite unconditionally. Re-read the record, take the new etag, and retry.
What is Application_DialogException?
- A business-logic error raised by Business Central itself — a posting date outside the allowed range, a blocked customer, a missing posting group. The message is the same text a user would see in the client; fix the data or setup, not the API call. The posting error references on this site decode the common ones.
Why does my custom API page return 404?
- The URL does not match the page's APIPublisher, APIGroup, APIVersion, and EntitySetName exactly, or the extension is not installed in the environment named in the URL, or the page's PageType is not API. Check the four properties against the URL segment by segment — they are case-sensitive.
Further reading
Related guides
- AL compiler errors in Business CentralThe AL compiler errors every Business Central developer hits — AL0118, AL0132, AL0185, AL0296, AL0432, AL0603, AL0604, ID-range and symbol errors — with cause, fix, and prevention.
- AL runtime errors in Business CentralThe Business Central runtime errors AL developers and admins meet most — record already exists, does not exist, modified by another user, string length, locks and deadlocks, G/L inconsistency — with fixes.
- Business Central job queue errorsWhy Business Central job queue entries fail or stall — Error status, stuck In Process, entries that never run, permission and user problems, overlapping jobs, sandbox copies, reports needing parameters — with fixes.
- Business Central journal and document posting errorsBusiness Central posting errors that are not posting groups — allowed posting dates, dimension code mandatory, number series, blocked customers and items, nothing to post, warehouse handling, approvals.
- Business Central posting setup errorsThe Business Central posting group errors — Gen. Posting Setup, VAT Posting Setup, Customer and Vendor Posting Group, Inventory Posting Setup, Direct Posting, blocked accounts — with cause, fix, prevention.
Browse every guide in Business Central or just Troubleshooting.
Spot something wrong or want a topic covered? Send a correction or a topic request — both are welcome.