ml-connector
Microsoft Dynamics 365 Business CentralCin7

Microsoft Dynamics 365 Business Central and Cin7 integration

Microsoft Dynamics 365 Business Central runs finance, the general ledger, and the chart of accounts. Cin7 Core runs inventory, purchasing, and order management. Connecting the two means supplier bills entered against stock in Cin7 Core become purchase invoices in Business Central without re-keying, and the item and vendor master in Business Central stays aligned with Cin7 Core. Each invoice is coded to a valid Business Central GL account and dimension, and suppliers map to Business Central vendors. ml-connector handles the very different auth on each side and moves the records on the schedule you set.

How Microsoft Dynamics 365 Business Central works

Microsoft Dynamics 365 Business Central exposes vendors, customers, purchase invoices, purchase orders, items, GL accounts, general ledger entries, dimensions, and payment journals through the Business Central API v2.0, a REST API built on OData v4 with JSON payloads. Authentication uses Microsoft Entra ID OAuth 2.0 client credentials (service-to-service), scoped to a tenant and a named environment such as production, so the base URL is tenant-specific. The chart of accounts and general ledger entries are read-only, while vendors, items, and purchase invoices support writes; posting a draft purchase invoice requires the Microsoft.NAV.post bound action. Business Central can push change notifications by subscription, but notifications carry no data and subscriptions expire every three days, so finance records are typically read by polling with a lastModifiedDateTime filter for delta sync.

How Cin7 works

Cin7 Core, formerly DEAR Systems, exposes suppliers, purchases, sales, payments, products, and chart of accounts through a REST JSON API at inventory.dearsystems.com. Authentication uses two static header keys, api-auth-accountid and api-auth-applicationkey, rather than OAuth. A single Purchase record covers the full procure-to-pay cycle through its Approach field of ORDER, RECEIVE, or INVOICE, and records start as Draft until a separate authorise call moves them to Authorised. Products carry SKU, units of measure, and the purchase, sale, inventory, and COGS account codes, and the chart of accounts is read-only over the API. Cin7 Core can push Purchase created, Purchase updated, Supplier created, and Supplier updated events from its Automation module, though those payloads are unsigned, and list endpoints page with page and limit parameters.

What moves between them

The flow runs in both directions but is split by system of record. From Cin7 Core into Microsoft Dynamics 365 Business Central, ml-connector reads supplier purchases that reach the INVOICE approach and Authorised status and creates a matching purchase invoice in Business Central against the correct vendor, GL account, and dimensions. Supplier records flow the same direction so Business Central vendors reflect new and updated Cin7 Core suppliers. From Business Central back into Cin7 Core, ml-connector pushes the item master and vendor records so products and suppliers used in purchasing stay aligned with the ERP. The chart of accounts is read-only over both APIs, so ml-connector reads account codes for mapping but never writes accounts to either side, and posted Business Central purchase invoices are not pushed back as Cin7 Core purchases.

How ml-connector handles it

ml-connector stores both credential sets encrypted. On the Cin7 Core side it sends the api-auth-accountid and api-auth-applicationkey headers on every request. On the Business Central side it requests a Microsoft Entra ID OAuth 2.0 client-credentials token, scopes every call to the tenant and the configured environment name, and refreshes the token before it expires. Cin7 Core Purchase created and Purchase updated webhooks from the Automation module trigger the work, and because those payloads are unsigned, ml-connector reads the Purchase back from the API before acting, and a scheduled poll backfills anything a webhook missed. Only purchases at the INVOICE approach and Authorised status are turned into Business Central purchase invoices, so draft and order-stage records are skipped; the invoice is created as a draft and then posted with the Microsoft.NAV.post bound action. Suppliers and item SKUs are mapped to Business Central vendors and items first, and Cin7 Core account codes are mapped to Business Central GL accounts, so every line references a record that already exists. Neither API offers an idempotency-key header, so ml-connector checks Business Central for the supplier document number before posting and dedupes on a BullMQ jobId, which prevents a re-read purchase from posting twice. Business Central returns HTTP 429 when throttled and Cin7 Core returns 429 with a Retry-After header, so ml-connector backs off with jitter on both, and every record carries a full audit trail and can be replayed if a downstream call fails.

A real-world example

A mid-sized specialty foods distributor with roughly 90 staff runs Microsoft Dynamics 365 Business Central for finance and the general ledger and uses Cin7 Core to manage stock, supplier purchasing, and warehouse receiving across two sites. Before the integration, a clerk exported authorised supplier bills from Cin7 Core each week and re-keyed them into Business Central as purchase invoices, matching each line to the right vendor and GL account by hand, which delayed payables and produced coding errors at month-end close. With Microsoft Dynamics 365 Business Central and Cin7 connected, every authorised Cin7 Core supplier purchase flows into Business Central as a purchase invoice already coded to the correct vendor, account, and dimension, and the item and vendor master stays aligned across both systems. Payables are entered the same day and the manual re-keying step is gone.

What you can do

  • Create Microsoft Dynamics 365 Business Central purchase invoices from authorised Cin7 Core supplier purchases, coded to the right GL account and dimension.
  • Keep Business Central vendors aligned with Cin7 Core suppliers as they are created and updated.
  • Push the Business Central item and vendor master into Cin7 Core so purchasing uses the same products and payees.
  • Bridge Cin7 Core api-auth header keys and the Microsoft Entra ID OAuth 2.0 token, refreshing the Business Central token automatically.
  • Trigger on Cin7 Core Purchase events, backfill by scheduled poll, and check the document number before posting to avoid duplicates.

Questions

Which direction does data move between Microsoft Dynamics 365 Business Central and Cin7?
It moves both ways, split by system of record. Authorised supplier purchases and supplier records move from Cin7 Core into Business Central as purchase invoices and vendors, while the Business Central item and vendor master pushes into Cin7 Core to keep purchasing aligned. The chart of accounts is read-only over both APIs, so ml-connector reads account codes for mapping but never writes accounts to either side.
How does the integration avoid posting a supplier bill twice without an idempotency key?
Neither Business Central nor Cin7 Core exposes an idempotency-key header. Before creating a purchase invoice, ml-connector queries Business Central for the supplier document number and skips the post if a match already exists, and it dedupes on a BullMQ jobId. Because Cin7 Core webhook payloads are unsigned, it also reads the Purchase back from the API to confirm the event before acting.
Does the integration use Cin7 Core webhooks or polling?
It uses both. Cin7 Core Purchase created and Purchase updated events from the Automation module trigger the sync as soon as a bill is authorised. Business Central change notifications carry no payload and expire every three days, so a scheduled poll with a lastModifiedDateTime filter reads Business Central reference data and backfills anything the unsigned Cin7 Core events miss.

Related integrations

Connect Microsoft Dynamics 365 Business Central and Cin7

Free to use. Add your credentials, ping your real systems, and see if we fit.

Get started