ml-connector
Microsoft Dynamics 365 Business CentralMicrosoft Power BI

Microsoft Dynamics 365 Business Central and Microsoft Power BI integration

Microsoft Dynamics 365 Business Central holds the finance and supply chain records. Microsoft Power BI builds the reports and dashboards on top of them. Connecting the two keeps analytics current with the ledger without anyone exporting spreadsheets. ml-connector reads vendors, customers, invoices, GL accounts, and general ledger entries from Business Central and pushes them as rows into Power BI datasets, so a report opens on the latest posted numbers. The data moves one direction only, because Power BI is a reporting destination and not a source of truth.

How Microsoft Dynamics 365 Business Central works

Microsoft Dynamics 365 Business Central exposes vendors, customers, purchase invoices, sales invoices, GL accounts, general ledger entries, items, and dimensions through its REST API built on OData v4. All resources nest under a company on a tenant and environment URL, authenticated with an OAuth 2.0 client credentials token from Microsoft Entra ID using the scope https://api.businesscentral.dynamics.com/.default. It supports push subscriptions for most entities, but those notifications only signal that a record changed and carry no data, expire after three days, and exclude purchaseOrders. For sync, records are read by OData polling with a lastModifiedDateTime filter for deltas.

How Microsoft Power BI works

Microsoft Power BI exposes datasets, push dataset tables, reports, and workspaces through its REST API at https://api.powerbi.com/v1.0/myorg. A service principal authenticates with OAuth 2.0 client credentials using the scope https://analysis.windows.net/powerbi/api/.default, and every call is scoped to a workspace GUID, not a display name. The connector defines a table schema, then appends rows to a push dataset, capped at 10,000 rows per POST and 120 POSTs per minute per dataset. Power BI sends no outbound webhooks, so the connector pushes on a schedule and can trigger a dataset refresh after loading.

What moves between them

Data moves one direction, from Microsoft Dynamics 365 Business Central into Microsoft Power BI. On a schedule you set, ml-connector reads posted finance records from Business Central, vendors, customers, purchase invoices, sales invoices, GL accounts, and general ledger entries, maps each to a Power BI table, and posts the rows into push datasets in the target workspace. Accounting dimensions ride along as extra string columns on the relevant tables. Power BI owns no transactional records and is read-only as a source, so ml-connector never writes anything back into Business Central.

How ml-connector handles it

Both systems authenticate through Microsoft Entra ID, but with different app setups, so ml-connector keeps two service principals: one with Business Central application permissions and the BC scope, one added as a member on the Power BI workspace with the Power BI scope. It refreshes each bearer token on its own clock and renews when a call returns 401. Business Central change subscriptions expire every three days and notifications carry no payload, so rather than depend on them ml-connector polls with a lastModifiedDateTime filter and stores a watermark per entity, fetching only changed records and following the @odata.nextLink for pages up to 20,000 rows. Those records are batched into Power BI POSTs no larger than 10,000 rows. Because push row POSTs are append-only with no idempotency key, ml-connector either deletes all rows and reloads for a clean replace or pushes only net-new rows past the watermark, avoiding duplicates. Business Central returns HTTP 429 when throttled and Power BI returns HTTP 429 with a Retry-After header, so both call paths back off with jitter and retry. Note that Microsoft has marked the push datasets API for deprecation in favor of scheduled refresh against a direct data source, so the schema is kept simple to ease that future move. Every record carries a full audit trail and can be replayed if a push fails.

A real-world example

A mid-market distributor with about 200 employees runs Microsoft Dynamics 365 Business Central for purchasing, sales, and finance, and its leadership team reviews margins and cash in Microsoft Power BI. Before the integration, an analyst exported invoice and GL extracts from Business Central every Monday, reshaped them in spreadsheets, and reloaded the Power BI dataset by hand, so the dashboards were always a week behind and broke whenever a column moved. With the two systems connected, posted invoices and general ledger entries flow into the Power BI dataset on a nightly schedule, dimensions included, and the weekly export is gone. The finance dashboards now open on the prior day's posted numbers instead of last week's.

What you can do

  • Push Business Central vendors, customers, invoices, GL accounts, and ledger entries into Power BI datasets on a schedule.
  • Carry Business Central accounting dimensions into Power BI as extra columns so reports slice by cost center and department.
  • Read only changed records using a lastModifiedDateTime watermark, avoiding full reloads on every run.
  • Authenticate Business Central and Power BI with separate Entra service principals on their own token scopes.
  • Replace or append rows without duplicates, with retries on throttling and a full audit trail on every record.

Questions

Which direction does data move between Microsoft Dynamics 365 Business Central and Microsoft Power BI?
Data moves one direction only, from Business Central into Power BI. Finance records such as invoices, GL entries, vendors, and accounts are read from Business Central and pushed into Power BI datasets. Power BI is a reporting destination and owns no transactional records, so ml-connector never writes back into Business Central.
Does Microsoft Power BI notify the connector when something changes?
No. Power BI sends no outbound webhooks for dataset, report, or refresh events, so there is nothing to receive on the connector side. ml-connector pushes rows into Power BI on a schedule and can trigger a dataset refresh after loading. The change signal comes from Business Central, where the connector polls with a lastModifiedDateTime filter.
How are duplicate rows avoided when pushing into Power BI?
Power BI push dataset row POSTs are append-only and have no idempotency key, so a naive re-run would duplicate rows. ml-connector handles this two ways: it can delete all rows in a table and reload the full set for a clean replace, or it can track a watermark and push only records changed since the last run. Each POST stays within the 10,000-row limit, and a failed push can be replayed from the audit trail.

Related integrations

Connect Microsoft Dynamics 365 Business Central and Microsoft Power BI

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

Get started