Microsoft Dynamics 365 Business Central and HubSpot integration
Microsoft Dynamics 365 Business Central runs finance, inventory, and order fulfillment, and is the system of record for posted invoices and the general ledger. HubSpot runs sales, marketing, and customer relationships. Connecting the two gives sales and account teams the customer, product, and billing data that lives in the ERP, without anyone re-keying it or asking finance for a status. ml-connector reads the Business Central records and keeps the matching HubSpot companies, products, and invoices in step on a schedule you control. Because HubSpot has no general ledger or vendor records, the accounting stays in Business Central where it belongs.
What moves between them
The main flow runs from Microsoft Dynamics 365 Business Central into HubSpot. ml-connector reads customers and posts them as HubSpot companies, reads items and posts them as HubSpot products, and reads posted sales invoices and creates the matching HubSpot invoices with their line items, associated to the right company so account teams see what was billed. Customer identity is matched on company name and invoices on the Business Central document number so updates land on the existing CRM record rather than creating duplicates. HubSpot is treated as the downstream CRM, so ml-connector does not write financial entries back into Business Central; the cadence is a scheduled poll you set, typically a few times a day.
How ml-connector handles it
ml-connector stores both credential sets encrypted. For Business Central it requests a Microsoft Entra ID bearer token with the client credentials grant against the fixed scope https://api.businesscentral.dynamics.com/.default, and builds the base URL from the environment name and company id the customer provides. For HubSpot it sends the Private App token as a static bearer header on every request. Customers map to HubSpot companies, items to HubSpot products, and posted sales invoices to HubSpot invoices with their lines, since HubSpot requires invoices to carry associations and line items to be valid. Writes use the HubSpot batch upsert endpoint keyed on company name or a stored Business Central number so re-runs update instead of duplicate, which matters because neither API offers an idempotency-key header; a BullMQ jobId derived from the document number adds a second guard against a re-read invoice being booked twice. Business Central notifications carry only a change signal and the subscriptions expire every three days, so reads page through OData with a lastModifiedDateTime filter rather than relying on a push, and HubSpot webhooks are not used because they need a separate Public OAuth app. Only posted Business Central invoices are synced, since a draft is not yet a real bill. Business Central rate limits return HTTP 429 and HubSpot returns HTTP 429 with a Retry-After header, so ml-connector backs off and retries, and every record carries a full audit trail and can be replayed if a HubSpot write fails.
A real-world example
A mid-sized specialty distributor with about 150 staff runs Microsoft Dynamics 365 Business Central for finance, inventory, and invoicing, and uses HubSpot for its sales and account management teams. Before the integration, when a rep wanted to know whether a customer's order had been invoiced or what they had been billed, they emailed finance and waited, and the company list in HubSpot drifted from the real customer master in the ERP. With Business Central and HubSpot connected, each customer and posted invoice flows into HubSpot within the polling window, attached to the right company, so reps see billing status without leaving the CRM. The customer list stays in step on both sides, and the back-and-forth with finance is gone.
What you can do
- Create and update HubSpot companies from Microsoft Dynamics 365 Business Central customers, matched on company name to avoid duplicates.
- Sync Business Central items into HubSpot products so deal and invoice line items reference a real catalog entry.
- Push posted Business Central sales invoices into HubSpot as invoices with line items, associated to the right company.
- Bridge Business Central's Microsoft Entra ID OAuth token and HubSpot's static Private App token automatically.
- Poll Business Central on the schedule you set with a lastModifiedDateTime delta filter, with upserts, retries, and a full audit trail on every record.
Questions
- Which direction does data move between Microsoft Dynamics 365 Business Central and HubSpot?
- The main flow runs from Business Central into HubSpot. Customers, items, and posted sales invoices move from Business Central into HubSpot as companies, products, and invoices. HubSpot is treated as the downstream CRM, so ml-connector does not write financial entries back into Business Central, and the general ledger stays in the ERP because HubSpot has no GL resource.
- How does the integration avoid creating duplicate records in HubSpot?
- HubSpot companies are matched on name and invoices on the Business Central document number using the batch upsert endpoint, which updates an existing record when a matching idProperty is found and creates one otherwise. Neither API provides an idempotency-key header, so ml-connector keys every write on a stable identifier and adds a BullMQ jobId so a re-read record updates rather than duplicates.
- Does the integration use webhooks or polling?
- It polls Business Central on a schedule you set. Business Central notifications carry only a change signal rather than the data, and the subscriptions expire every three days, so reads page through OData with a lastModifiedDateTime filter. HubSpot webhooks are not used here because they require a separate Public OAuth app rather than the Private App token used for syncing.
Related integrations
More Microsoft Dynamics 365 Business Central integrations
Other systems that connect to HubSpot
Connect Microsoft Dynamics 365 Business Central and HubSpot
Free to use. Add your credentials, ping your real systems, and see if we fit.
Get started