Microsoft Dynamics 365 Business Central and ServiceTitan integration
Microsoft Dynamics 365 Business Central runs finance, the general ledger, and the chart of accounts. ServiceTitan runs field service operations: dispatch, jobs, customer records, invoicing, and payments for home and commercial trades. Connecting the two carries the revenue ServiceTitan books in the field into Business Central as accounting records without re-keying, and keeps the customer master and price list aligned across both systems. Job invoices and the payments applied against them post into Business Central as sales invoices and customer payments, coded to the right GL dimensions. ml-connector handles the very different authentication on each side and uses ServiceTitan webhooks to react as soon as an invoice is finalized or a payment is taken.
What moves between them
The flow runs in both directions, split by system of record. From ServiceTitan into Microsoft Dynamics 365 Business Central, ml-connector reads finalized job invoices and the payments applied against them and posts them as Business Central sales invoices and customer payment journal lines, with each ServiceTitan business unit mapped to a Business Central dimension so revenue is coded correctly. The customer master is aligned the same direction so Business Central reflects new and changed ServiceTitan customers. From Business Central into ServiceTitan, ml-connector can push items into the ServiceTitan pricebook as services or materials so field pricing matches the ERP. Customers flow before invoices, because a Business Central sales invoice needs an existing customer. The Business Central chart of accounts stays the source of truth, since ServiceTitan has no GL accounts to write back to.
How ml-connector handles it
ml-connector stores both credential sets encrypted. On the Business Central side it requests an Entra ID OAuth 2.0 client-credentials token, scopes every call to the tenant and the configured environment name, and refreshes the token before expiry. On the ServiceTitan side it obtains a bearer token, caches it for its short fifteen-minute life rather than re-requesting per call, and attaches the ST-App-Key header and the tenant ID in the path on every request. Customers are synced before invoices, because a Business Central sales invoice cannot post against a customer that does not exist; each ServiceTitan business unit is mapped to a Business Central dimension, which is how revenue gets a cost center given that ServiceTitan exposes no GL chart. Incoming work is event-driven: ml-connector subscribes to ServiceTitan invoice and payment webhooks, verifies the HMAC-SHA256 signature in the x-servicetitan-signature header against the raw JSON body before processing, then creates and posts the matching Business Central sales invoice or customer payment. Because ServiceTitan replay tooling is still being rolled out, the connector also polls ServiceTitan on a schedule as a backstop, and on the Business Central side polling uses a lastModifiedDateTime filter since notifications carry no payload and expire every three days. Neither system offers an idempotency-key header, so ml-connector dedupes on the ServiceTitan invoice or payment ID and a BullMQ jobId before posting to Business Central. ServiceTitan enforces a hundred-second request timeout and sixty calls per second, and Business Central returns HTTP 429 when throttled, so the connector backs off with jitter and queues rather than fanning out. ServiceTitan AP bills are read-only and derived from received purchase orders, so the connector treats them as a source to read, never a target to write. Every record carries a full audit trail and can be replayed if a downstream call fails.
A real-world example
A regional HVAC and plumbing contractor with roughly 150 field technicians runs ServiceTitan for dispatch, job invoicing, and payments, and uses Microsoft Dynamics 365 Business Central for finance and the general ledger. Before the integration, the accounting team exported invoice and payment registers from ServiceTitan and re-entered the totals into Business Central by hand, splitting revenue across departments manually and chasing differences during month-end close. With Microsoft Dynamics 365 Business Central and ServiceTitan connected, each finalized job invoice and the payment taken against it post into Business Central automatically the moment the ServiceTitan webhook fires, coded to the dimension that matches the originating business unit, and the customer master stays aligned across both systems. The manual re-keying step disappears and close starts from revenue that already reconciles.
What you can do
- Post ServiceTitan job invoices into Microsoft Dynamics 365 Business Central as sales invoices coded to the right GL dimension.
- Record ServiceTitan payments in Business Central as customer payment journal lines applied to the matching invoice.
- Keep the customer master aligned so every Business Central sales invoice posts against a valid customer.
- Push Business Central items into the ServiceTitan pricebook as services or materials so field pricing matches the ERP.
- Bridge Microsoft Entra ID OAuth on the ERP side and the ServiceTitan bearer token plus ST-App-Key, with webhooks, dedup, retries, and a full audit trail.
Questions
- Which direction does data move between Microsoft Dynamics 365 Business Central and ServiceTitan?
- It moves both ways, split by system of record. Finalized job invoices and the payments applied to them are read from ServiceTitan and posted into Business Central as sales invoices and customer payment journal lines, with customers aligned the same direction. Business Central items can push into the ServiceTitan pricebook so field pricing matches the ERP. The Business Central chart of accounts stays authoritative because ServiceTitan exposes no GL accounts to write back to.
- How does the integration handle GL coding when ServiceTitan has no chart of accounts?
- ServiceTitan has no chart-of-accounts API, so GL coding is resolved on the Business Central side. ml-connector maps each ServiceTitan business unit, which is ServiceTitan's primary cost-center dimension, to a Business Central dimension. When a ServiceTitan invoice posts into Business Central as a sales invoice, that mapping gives the revenue a valid dimension so it lands in the right place in the ledger.
- Does ServiceTitan push events, or does ml-connector poll for new invoices and payments?
- ServiceTitan supports V2 webhooks, and ml-connector uses them as the primary trigger. It subscribes to invoice and payment events and verifies the HMAC-SHA256 signature in the x-servicetitan-signature header against the raw body before acting. Because ServiceTitan replay tooling is still rolling out, the connector also polls ServiceTitan on a schedule as a backstop, and on the Business Central side it polls with a lastModifiedDateTime filter since notifications carry no payload and expire every three days.
Related integrations
More Microsoft Dynamics 365 Business Central integrations
Other systems that connect to ServiceTitan
Connect Microsoft Dynamics 365 Business Central and ServiceTitan
Free to use. Add your credentials, ping your real systems, and see if we fit.
Get started