ERP
Microsoft Dynamics 365 Business Central
A test-only subset of Business Central API v2.0. Create Business Central under Systems → ERP. Each system has an isolated test company, credentials and records. No Microsoft request, inventory movement or accounting entry is made.
Testlie is independent of Microsoft. Names identify API compatibility, not endorsement or certification.
Connect
Replace the API host with the system's base URL. Use either <base>/api/v2.0/... or <base>/v2.0/{tenantId}/{environment}/api/v2.0/..., with the IDs shown in the system. Send Authorization: Bearer <accessToken> using its test access token. GET /api/v2.0/companies returns the configured company.
To test client-credentials OAuth, replace the Microsoft authorization host with the same base and POST a URL-encoded body to <base>/{tenantId}/oauth2/v2.0/token containing grant_type=client_credentials, client_id, client_secret and scope=https://api.businesscentral.dynamics.com/.default. Issued tokens expire after one hour; rotating client credentials or the test access token invalidates them. This is a local token simulation, without Entra ID roles, consent or real tenants.
Supported records
All resource paths below follow /api/v2.0/companies({companyId}):
| Resource | Operations | Main test inputs |
|---|---|---|
/customers and /customers({id}) |
POST, GET, PATCH, DELETE | displayName, number, contact/address fields |
/items and /items({id}) |
POST, GET, PATCH, DELETE | displayName, number, unitPrice, unitCost |
/salesOrders and /salesOrders({id}) |
POST, GET, PATCH, DELETE | Existing customerId or customerNumber, external reference, currency/dates |
/salesOrders({id})/salesOrderLines and /salesOrderLines({lineId}) |
POST, GET, PATCH, DELETE | Existing itemId or lineObjectNumber, positive quantity, unitPrice, discountAmount |
Create customers/items before orders and order lines. displayName is required for customers and items. Numbers are generated when omitted. Order lines support lineType: "Item" only. Totals use quantity × unit price − discount, rounded to two decimals, without taxes or currency conversion. Lines belong to exactly one order.
{
"displayName": "Sample Company",
"number": "TEST-CUSTOMER"
}POST this to /customers, then use the response's id in { "customerId": "..." } at /salesOrders. Create an item with a test unitPrice and add an order line. Orders remain Draft; posting, shipping, invoicing and financial ledger APIs are intentionally unsupported.
Queries and concurrency
Collection responses contain value, optional @odata.count and @odata.nextLink. Supported options: $select, $top (1–500), $skip (0–1000), $count=true, one $orderby field and literal $filter comparisons (eq/ne/gt/ge/lt/le) joined by and. Quote apostrophes as ''. Functions, or, $expand, $batch and custom APIs are unsupported. Follow the returned next link as a URL.
Records include @odata.etag. PATCH and DELETE require If-Match with the current ETag or *; missing headers return 428 and stale tags return 412. Changes use atomic compare-and-swap, so concurrent writes cannot silently overwrite one another. Refresh and retry after a conflict. Parent order ETags advance when their nested lines change.
Scenarios and limits
Rate-limit, server-error and response-delay scenarios use the shared machinery. Decline rejects record creates/updates. There are no native webhook registrations or event notifications in this subset, and no interactive action for Require action. Configure no webhook URL for this provider.
At most 500 records per resource and 100 lines per order; requests are limited to 128 KB. The shared object store scans the newest 1,000 records across resource types, so large test fixtures should use separate systems or clear old data. Retention and plan limits apply. Unsupported fields/operations return explicit errors. Use test business/contact data only.
Based on Microsoft's API reference and line update contract. Validate production accounting behavior against Microsoft itself.