ml-connector
Microsoft Dynamics 365 Business CentralBrex

Microsoft Dynamics 365 Business Central and Brex integration

Microsoft Dynamics 365 Business Central runs finance and purchasing. Brex runs corporate cards, expenses, and bill pay. Connecting the two moves coded card spend into the general ledger without re-keying receipts. When Brex finishes coding a transaction, ml-connector pulls the accounting record and posts it into Business Central as a draft purchase invoice mapped to the right vendor, GL account, and dimensions. It also pushes Business Central vendors into Brex so bill payments reference real payees, and it reconciles completed Brex transfers back to the ledger.

How Microsoft Dynamics 365 Business Central works

Microsoft Dynamics 365 Business Central exposes vendors, purchase invoices, GL accounts (chart of accounts), dimensions, and general ledger entries through the Business Central API v2.0, a REST API built on OData v4 at a URL that includes the tenant and a named environment such as production. Authentication is OAuth 2.0 client credentials through Microsoft Entra ID, a service-to-service flow that needs no logged-in user. Purchase invoices are created as drafts and posted with a bound action, while the chart of accounts and GL entries are read-only. Business Central supports push notifications through a subscription API, but each subscription expires after three days and the notification carries only a change signal, so the record must be fetched after the alert.

How Brex works

Brex exposes card expenses, accounting records, vendors, transfers, and custom accounting fields through its REST API, using a static bearer token or OAuth 2.0 for partner apps. The accounting records surface is the ERP export path: each record carries a GL account, accounting field dimension values, and an export status of ready-for-export or exported. Vendors and transfers are read-write, and transfer creation requires an Idempotency-Key header. Brex pushes events through Svix-signed webhooks, including ACCOUNTING_RECORD_READY_FOR_EXPORT when a transaction is fully coded and TRANSFER_PROCESSED when a payment completes.

What moves between them

The main flow runs from Brex into Microsoft Dynamics 365 Business Central. When a Brex accounting record is coded and ready for export, ml-connector reads it and posts the spend into Business Central as a draft purchase invoice against the matching vendor, GL account, and dimensions, then marks the Brex record exported. Vendor records flow the other way: Business Central vendors are synced into the Brex vendor directory so Brex bill payments reference real payees. Completed Brex transfers are reconciled against the corresponding Business Central documents. Brex accounting records and transactions are the read source for spend, so ml-connector does not write expense data back into Brex beyond the exported flag.

How ml-connector handles it

ml-connector stores both credential sets encrypted. On the Business Central side it builds the base URL from the stored tenant and environment name and obtains an Entra ID client-credentials token, refreshing it on a 401. On the Brex side it sends the bearer token and verifies inbound webhooks using the Svix signing scheme over the webhook-id, webhook-timestamp, and raw body. It subscribes to the Brex ACCOUNTING_RECORD_READY_FOR_EXPORT event so coding completion triggers a pull and post, and it polls Brex accounting records on a schedule to backfill anything a webhook missed. Brex merchant names rarely match Business Central vendor names exactly, so a fuzzy-match and cache layer resolves each merchant to a real vendor before posting, and Brex accounting fields map to Business Central dimensions. Posted invoices stay as drafts unless your flow runs the post action. Brex transfer creation carries an Idempotency-Key, Business Central uses a stable jobId keyed to the record so a retry never double-posts, and HTTP 429 from either side triggers exponential backoff with jitter. Because Business Central subscriptions expire after three days, ml-connector renews them before expiry, and every record carries a full audit trail and can be replayed if a downstream call fails.

A real-world example

A 150-person software company runs Microsoft Dynamics 365 Business Central for finance and issues Brex cards to its engineering and sales teams. Before the integration, an accountant exported Brex expenses each month, matched merchants to vendors by hand, and keyed the totals into Business Central, with software subscriptions and travel landing on the wrong GL accounts until someone caught it at close. With Business Central and Brex connected, each coded Brex accounting record posts into Business Central as a draft purchase invoice on the correct account and department dimension, and the merchant-to-vendor matching is handled automatically. Month-end close starts with card spend already booked, and the manual export-and-rekey step is gone.

What you can do

  • Post coded Brex accounting records into Microsoft Dynamics 365 Business Central as draft purchase invoices on the right GL account and dimensions.
  • Sync Business Central vendors into the Brex vendor directory so bill payments reference real payees.
  • Resolve fuzzy Brex merchant names to existing Business Central vendors with a match-and-cache layer.
  • Bridge Brex bearer-token auth with the Entra ID client-credentials login Business Central requires.
  • React to the Brex ready-for-export webhook, backfill by polling, and mark each record exported so nothing posts twice.

Questions

Which direction does data move between Microsoft Dynamics 365 Business Central and Brex?
The main flow is Brex into Business Central. Coded Brex accounting records become draft purchase invoices in Business Central, while vendors sync the other way so Brex bill payments reference real payees. Brex accounting records are the read source for spend, so ml-connector marks each record exported rather than writing expense data back.
How does ml-connector avoid posting the same Brex spend twice?
Each Brex accounting record carries an export status. After ml-connector posts a record into Business Central it sets that status to exported, and it keys the Business Central job to the record id so a retry re-runs under the same id and deduplicates. The Brex ready-for-export webhook and a scheduled poll only ever act on records still marked ready for export.
Does the connector handle Business Central webhook expiry and the Entra ID login?
Yes. ml-connector obtains an Entra ID client-credentials token for Business Central and refreshes it on a 401. Business Central push subscriptions expire after three days, so the connector renews them before expiry and completes the validation-token handshake; because notifications carry only a change signal, it fetches the changed record afterward.

Related integrations

Connect Microsoft Dynamics 365 Business Central and Brex

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

Get started