Microsoft Dynamics 365 F&O and Stedi integration
Microsoft Dynamics 365 F&O runs procurement, finance, and supply chain. Stedi translates and routes X12 EDI to and from your trading partners. Connecting the two lets purchase orders raised in D365 leave as outbound 850 EDI, and lets inbound supplier invoices and ship notices come back into D365 as records without re-keying. ml-connector handles the OData API on the D365 side and the EDI generation and webhook delivery on the Stedi side. Because Stedi is a translation and routing layer rather than a data store, D365 stays the system of record for every business object.
What moves between them
Outbound runs from Microsoft Dynamics 365 F&O into Stedi. When a purchase order is confirmed in D365, ml-connector reads the header and lines from OData and posts them to Stedi as JSON, which generates an outbound 850 and delivers it to the supplier. Inbound runs from Stedi into D365. Stedi parses partner 810 invoices and 856 ship notices to JSON and pushes them by webhook, and ml-connector writes them into D365 as vendor invoice headers and lines tied to the originating purchase order. Item numbers, vendor accounts, and PO numbers are aligned in both directions so every EDI document maps to a real D365 record. Stedi holds no ledger, so GL postings stay in D365.
How ml-connector handles it
ml-connector stores both credentials encrypted. On the D365 side it requests an Entra ID client-credentials token scoped to the environment host and refreshes it on expiry, and it scopes each OData call to the right legal entity with the dataAreaId key and cross-company filter. On the Stedi side it sends the API key in the Authorization header and targets the correct partnership and transaction setting, which are configured in the Stedi portal because there is no API to create them. For outbound, a D365 purchase order confirmed Business Event arrives as a stub, so ml-connector reads the full PO from OData, then posts it to Stedi with an Idempotency-Key so a retry does not produce a duplicate EDI file. For inbound, Stedi must get a 2xx within its 5 second webhook timeout, so ml-connector acknowledges immediately, deduplicates on the eventId, fetches the full JSON from the artifact download URL with the API key, then creates the D365 vendor invoice header before its lines, since lines require an existing header and posted invoices are read-only. Item numbers and vendor accounts are mapped first so each EDI line resolves to a real D365 product and vendor. D365 returns HTTP 429 with Retry-After under service protection limits and Stedi throttles by concurrency, so ml-connector backs off and retries on both.
A real-world example
A mid-sized consumer goods manufacturer with around 600 employees runs Microsoft Dynamics 365 F&O for procurement and finance and supplies several large retailers that mandate EDI. Before the integration, a coordinator exported each confirmed purchase order from D365 and keyed it into a portal to send the 850 by hand, then took supplier invoices that arrived as EDI and re-typed them into D365 as vendor invoices, which delayed orders and produced mismatches against the purchase orders. With Microsoft Dynamics 365 F&O and Stedi connected, confirmed purchase orders flow out as 850 documents and inbound 810 invoices come back as D365 vendor invoice records matched to their PO. The manual portal step is gone and invoices reconcile against their orders.
What you can do
- Generate outbound 850 purchase order EDI in Stedi from confirmed Microsoft Dynamics 365 F&O purchase orders.
- Write inbound 810 invoices and 856 ship notices that Stedi parses back into D365 as vendor invoice records.
- Map D365 item numbers, vendor accounts, and PO numbers so each EDI document lines up with a real record.
- Bridge Microsoft Dynamics 365 F&O Entra ID OAuth and the Stedi API key, with idempotency on every outbound EDI file.
- Acknowledge Stedi webhooks within the 5 second timeout, dedupe on eventId, and back off on 429 with Retry-After.
Questions
- Which direction does data move between Microsoft Dynamics 365 F&O and Stedi?
- Both directions. Confirmed purchase orders move outbound from D365 to Stedi, which generates 850 EDI for the supplier, and inbound 810 invoices and 856 ship notices move from Stedi into D365 as vendor invoice records. Stedi is a translation and routing layer with no ledger, so GL postings stay in Microsoft Dynamics 365 F&O and ml-connector never writes financial entries into Stedi.
- Does D365 push records to Stedi, or does ml-connector poll for them?
- D365 can push lightweight Business Events such as purchase order confirmed, but those payloads carry only a ControlNumber and key identifiers, not the full record. ml-connector uses the event as a trigger and then reads the full purchase order back through OData, and it can also poll OData on a schedule where Business Events are not enabled. The full record is always fetched from OData before it is sent to Stedi.
- How does the integration handle Stedi's 5 second webhook timeout and artifact downloads?
- Stedi requires a 2xx response within 5 seconds, so ml-connector acknowledges the webhook immediately and processes it asynchronously. It deduplicates on the eventId from the event envelope, then fetches the full translated JSON from the documentDownloadUrl using the Stedi API key, since that artifact URL is not public. Only after the payload is retrieved does it create the matching record in D365.
Related integrations
More Microsoft Dynamics 365 F&O integrations
Other systems that connect to Stedi
Connect Microsoft Dynamics 365 F&O and Stedi
Free to use. Add your credentials, ping your real systems, and see if we fit.
Get started