ml-connector
Microsoft Dynamics 365 F&OExpensify

Microsoft Dynamics 365 F&O and Expensify integration

Microsoft Dynamics 365 F&O is the system of record for finance and accounts payable. Expensify is where employees submit expenses and managers approve them. Connecting the two means approved expense reports become vendor invoices in D365 without anyone re-keying them. Expensify category GL codes and tags line up with D365 main accounts and financial dimensions, so each expense lands on the right account and cost center. ml-connector handles the very different APIs on each side and moves the data on a schedule you control.

How Microsoft Dynamics 365 F&O works

Microsoft Dynamics 365 F&O exposes all public data entities through OData v4 over REST and JSON at a single tenant-specific root URL such as contoso.operations.dynamics.com. Key finance entities include VendorsV2, VendorInvoiceHeaders, VendorInvoiceLines, MainAccounts, and DimensionAttributeValues. Authentication uses OAuth2 client credentials through Microsoft Entra ID, with a bearer token that expires about every hour and is re-requested. D365 can push through the Business Events framework, but events carry only identifiers, so full records are still read back over OData. Financial dimensions are written as a formatted display string and must be configured before any write.

How Expensify works

Expensify exposes its data through the Integration Server API, where every call is an HTTP POST to one endpoint and the type field in the JSON body selects the operation. Authentication is a long-lived partnerUserID and partnerUserSecret pair sent inline with every request, not OAuth2. It can export expense reports and the expenses inside them, create reports and expenses, and provision employees and policies. GL codes are not a standalone entity; they live on policy categories through categoryGLCodeMap, and tags act as project or department dimensions. Expensify is pull-only, so the connector polls; amounts are always returned in cents.

What moves between them

The main flow runs from Expensify into Microsoft Dynamics 365 F&O. ml-connector polls Expensify for newly approved reports, then creates a vendor invoice header and lines in D365 for each report, with the merchant, amount, and category carried onto the lines. Expensify category GL codes map to D365 main accounts and Expensify tags map to D365 financial dimensions, so every line posts to a valid account and cost center. Reference data such as GL codes and dimension values is aligned so the maps stay current. Employee records flow the same direction to keep Expensify approvers and policy membership in step with D365. Posted D365 invoices are read-only over OData, so the connector never writes financial postings back into Expensify.

How ml-connector handles it

ml-connector stores both credential sets encrypted. For Expensify it sends the partnerUserID and partnerUserSecret inline on each POST, since there is no token to refresh; for Microsoft Dynamics 365 F&O it runs the Entra ID client credentials flow and requests a fresh bearer token when a call returns 401. Because Expensify has no webhook, the connector polls on a schedule, passing approvedAfter with the last processed timestamp and filtering on markedAsExported so a report is never ingested twice. Each Expensify amount is in cents and is converted before it reaches D365. Category GL codes are mapped to D365 main accounts and tags to financial dimensions, which D365 expects as a formatted display string, so the maps are validated before a write. The D365 vendor invoice header is created before its lines and only while the invoice is unposted. Expensify rate limits return HTTP 429, and D365 returns 429 with a Retry-After header, so ml-connector backs off and retries, with a full audit trail and error replay on every record. Expensify has no sandbox, so a dedicated test policy is used to avoid touching live data.

A real-world example

A professional services firm of about three hundred staff runs Microsoft Dynamics 365 F&O for finance and uses Expensify for travel and corporate card expenses across several offices. Before the integration, the accounts payable team exported approved reports from Expensify each week and keyed the totals into D365 by hand, picking the GL account and cost center for every line and fixing mistakes during month-end close. With Expensify connected to D365, each approved report becomes a vendor invoice automatically, with the category GL code and the office tag already mapped to the right main account and financial dimension. The manual keying is gone, and expense accruals are current when close begins.

What you can do

  • Turn approved Expensify expense reports into vendor invoices in Microsoft Dynamics 365 F&O without re-keying.
  • Map Expensify category GL codes to D365 main accounts and Expensify tags to D365 financial dimensions.
  • Keep Expensify employees and policy membership in step with D365 vendor or worker records.
  • Bridge the Expensify partner key pair and the D365 Entra ID OAuth2 client credentials flow.
  • Poll Expensify on a schedule you set, with dedup, retries, and a full audit trail on every record.

Questions

Which direction does data move between Microsoft Dynamics 365 F&O and Expensify?
The main flow is Expensify into D365. Approved expense reports and the expenses inside them become vendor invoices in Microsoft Dynamics 365 F&O, and employee records move the same direction. Posted D365 invoices are read-only over OData, so ml-connector does not write financial postings back into Expensify.
How are Expensify GL codes and tags matched to D365 accounts?
Expensify keeps GL codes on policy categories through categoryGLCodeMap, and tags act as dimensions. ml-connector maps each category GL code to a D365 main account and each tag to a D365 financial dimension. D365 expects dimensions as a formatted display string, so the maps are validated before any invoice is written.
How does the integration handle Expensify having no webhook?
Expensify is pull-only with no event push, so ml-connector polls on a schedule you control. It passes approvedAfter with the last processed timestamp and filters on markedAsExported so a report is never ingested twice. Amounts come back in cents and are converted before they reach D365.

Related integrations

Connect Microsoft Dynamics 365 F&O and Expensify

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

Get started