ml-connector
Microsoft Dynamics 365 F&OProcore

Microsoft Dynamics 365 F&O and Procore integration

Procore runs construction project management, including commitments, subcontractor invoices, and direct costs. Microsoft Dynamics 365 F&O runs the company's finance and procurement back office. Connecting the two moves project costs that originate in the field into the ERP without re-keying. Purchase order contracts, subcontractor requisitions, and direct costs captured in Procore post into Microsoft Dynamics 365 F&O as purchase orders and vendor invoices coded to the right GL accounts and financial dimensions, and vendor records stay aligned on both sides. ml-connector handles the very different APIs and moves the data as Procore activity is approved.

How Microsoft Dynamics 365 F&O works

Microsoft Dynamics 365 F&O exposes vendors, vendor invoice headers and lines, purchase order headers and lines, GL main accounts, posted journal entries, and financial dimensions through an OData v4 REST API at a tenant-specific host such as contoso.operations.dynamics.com. Every call carries an OAuth2 bearer token obtained with client credentials from Microsoft Entra ID, and the token is scoped to that environment host. Finance reads are pulled with OData query options and server-driven paging up to 10,000 records per page. The platform can also push outbound notifications through Business Events, but those payloads carry only identifiers and a ControlNumber, so the full record must be fetched back over OData.

How Procore works

Procore exposes its finance and procurement data through a REST API at api.procore.com, with most resources scoped by company_id and project_id. It authenticates with OAuth2 client credentials via a Developer Managed Service Account, and tokens expire after 5400 seconds and must be refreshed proactively. Key resources include company and project vendors, purchase order contracts, requisitions for subcontractor invoices, direct costs, commitment change orders, budget line items, and cost codes, which stand in for GL codes since Procore has no standalone GL accounts endpoint. Procore pushes create, update, and delete events by webhook with no cryptographic signature, so a shared secret header is set at registration and verified on receipt.

What moves between them

The main flow runs from Procore into Microsoft Dynamics 365 F&O. As commitments are executed, ml-connector reads Procore purchase order contracts and writes them into D365 F&O as purchase orders, then reads approved subcontractor requisitions and direct costs and posts them as vendor invoices coded to the matching GL accounts and financial dimensions. Procore vendors are reconciled against D365 vendors so every cost references a vendor that exists in the ERP. Cost codes and cost types from Procore are mapped to D365 financial dimensions in a setup step that both directions depend on. D365 posted journal entries are read-only over OData, so ml-connector never writes financial entries back into Procore.

How ml-connector handles it

ml-connector stores both credential sets encrypted, mints a Procore DMSA token and refreshes it before the 5400-second expiry, and obtains a D365 OAuth2 bearer token from Microsoft Entra ID scoped to the customer's environment host, which is held as a credential field since each tenant has its own URL. Procore webhooks on Commitments, Requisitions, DirectCosts, and Vendors trigger work as activity is approved, and because Procore signs nothing, the connector verifies the shared secret header set at registration; a nightly reconciliation poll backfills anything a webhook missed, since Procore documents no delivery retry. Procore payloads carry only a resource id, so the full record is fetched over the Procore REST API before mapping. Cost codes are mapped to D365 financial dimensions first, and dimensions are written as the formatted display string D365 requires, so a wrong format is caught early. D365 OData writes use natural keys such as InvoiceNumber plus VendorAccount and have no idempotency header, so each job is deduplicated on its own key, and 429 responses on either side are retried with backoff against the Retry-After hint. Every record carries a full audit trail and can be replayed if a downstream call fails.

A real-world example

A mid-sized general contractor running fifteen active jobs uses Procore as the system of record for commitments, subcontractor billings, and direct costs in the field, and Microsoft Dynamics 365 F&O for corporate AP, procurement, and the general ledger. Before the integration, project accountants exported committed cost and subcontractor invoice data from each Procore project every week and re-entered it into D365 by hand, which delayed AP and left job cost in the ledger trailing what the field already knew. With Microsoft Dynamics 365 F&O and Procore connected, executed purchase order contracts and approved requisitions flow into the ERP as purchase orders and vendor invoices coded to the right job dimensions, vendors stay aligned, and AP works from current numbers instead of stale spreadsheets.

What you can do

  • Post executed Procore purchase order contracts into Microsoft Dynamics 365 F&O as purchase orders coded to the right financial dimensions.
  • Write approved Procore requisitions and direct costs into D365 F&O as vendor invoices against the matching GL accounts.
  • Keep Procore vendors and D365 vendors aligned so every project cost references a vendor that exists in the ERP.
  • Map Procore cost codes and cost types to D365 financial dimensions so job costs land on valid accounts.
  • Trigger on Procore webhooks, verify the shared secret header, and backfill with a reconciliation poll since Procore documents no delivery retry.

Questions

Which direction does data move between Microsoft Dynamics 365 F&O and Procore?
The main flow is Procore into Microsoft Dynamics 365 F&O. Purchase order contracts, subcontractor requisitions, and direct costs move from Procore into the ERP as purchase orders and vendor invoices, while vendors and cost code mappings are aligned across both sides. D365 posted journal entries are read-only over OData, so ml-connector does not write financial entries back into Procore.
How does the integration handle authentication across the two systems?
Procore uses OAuth2 client credentials through a Developer Managed Service Account, and the token expires after 5400 seconds, so ml-connector refreshes it proactively. Microsoft Dynamics 365 F&O uses OAuth2 client credentials through Microsoft Entra ID, scoped to the tenant-specific environment host that is held as a credential field. ml-connector stores both credential sets encrypted and presents the correct token to each system on every call.
What happens with Procore webhooks given there is no signature?
Procore pushes create, update, and delete events but provides no HMAC signature, so a shared secret header is set when the webhook is registered and verified on every inbound payload. Because the payload carries only a resource id, ml-connector fetches the full record over the Procore REST API before mapping it. Since Procore documents no retry schedule for failed deliveries, a scheduled reconciliation poll catches any events that were missed.

Related integrations

Connect Microsoft Dynamics 365 F&O and Procore

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

Get started