ml-connector
Microsoft Dynamics 365 F&OSFTP / Flat Files

Microsoft Dynamics 365 F&O and SFTP / Flat Files integration

Microsoft Dynamics 365 F&O is a cloud ERP with a modern OData API, while many trading partners and legacy systems can only exchange data as files over SFTP. This connection lets D365 trade with those partners without anyone re-keying data. Records such as purchase orders and vendor invoices read out of D365 and land as X12 or CSV files in a partner's outbound folder, and inbound files drop back in as D365 entities. Because SFTP is a pull-only transport with no push, the connector polls for new files on a schedule. The general ledger and posted records stay authoritative in Microsoft Dynamics 365 F&O.

How Microsoft Dynamics 365 F&O works

Microsoft Dynamics 365 F&O exposes its public data entities through an OData v4 REST/JSON service at a tenant-specific host, for example contoso.operations.dynamics.com/data/. Key collections include VendorsV2, CustomersV3, PurchaseOrderHeadersV2 with PurchaseOrderLines, VendorInvoiceHeaders with VendorInvoiceLines, MainAccounts, and GeneralJournalAccountEntries. Authentication is Microsoft Entra ID OAuth 2.0 client credentials, returning a Bearer token scoped to the environment host. D365 can push outbound Business Events such as PO confirmed or invoice posted to an HTTPS endpoint, but those payloads are lightweight stubs that carry a ControlNumber and require a follow-up OData read for full detail, and each event must be activated per legal entity.

How SFTP / Flat Files works

SFTP / Flat Files is a file-transfer transport, not an API. The connector connects over SSH on port 22 and reads or writes structured text files in agreed folders, typically /inbound/, /outbound/, /processed/, and /acks/. File formats are per-partner and include X12 EDI such as 810 invoices, 850 purchase orders, and 856 ship notices, plus CSV, fixed-width, and EDIFACT. Authentication is an SSH key pair, with the connector holding the private key and the partner registering the public key; username and password is a fallback. There is no native push, so the connector polls the directory on a schedule, and EDI flows return a 997 or CONTRL acknowledgment file for each set received.

What moves between them

Direction depends on the partner relationship and is usually two-way. Outbound, ml-connector reads D365 purchase orders, vendor invoices, vendors, items, and journal entries over OData and writes them as X12 or CSV files into the partner's outbound folder. Inbound, it polls the inbound folder, parses partner files such as 810 invoices or 850 purchase orders, and creates the matching D365 entities like VendorInvoiceHeaders or PurchaseOrderHeadersV2. Reference data such as vendor IDs, item numbers, and GL account codes is aligned so every file line resolves to a real D365 record. Cadence is the SFTP poll interval, commonly 5 to 60 minutes, and D365 Business Events can trigger an outbound file as soon as a record posts.

How ml-connector handles it

ml-connector stores both credential sets encrypted. For Microsoft Dynamics 365 F&O it requests a Microsoft Entra ID client-credentials token scoped to the tenant host, sends it as a Bearer token, and refreshes it when a call returns 401, since the token expires roughly hourly. It accepts the full operations.dynamics.com host per customer because there is no shared base URL, and it scopes reads to the right legal entity with dataAreaId and cross-company. For SFTP / Flat Files it authenticates with the partner's SSH key, verifies the server host key to block man-in-the-middle, and writes outbound files with deterministic names so a retried FlowRun produces the same filename. Inbound, it polls the folder, skips partial uploads by waiting for a sentinel file or a stable size, and dedupes on a filename plus content hash so a re-listed file is never imported twice. Each inbound FlowRun carries a jobId of sftp plus filename and a hash prefix for BullMQ-level dedup. D365 OData has no idempotency header, so it relies on natural keys such as InvoiceNumber to avoid duplicate-key errors, and it posts vendor invoices only before they are posted because posted records are read-only. Real edge cases handled include X12 delimiter characters in vendor names, CRLF versus LF line endings, server-local file timestamps, and the financial dimension display-string format D365 requires before a write. D365 429 responses honor Retry-After, and EDI files get a 997 acknowledgment written back to the acks folder.

A real-world example

A mid-sized consumer goods manufacturer with roughly 600 employees runs Microsoft Dynamics 365 F&O for procurement and finance and sells to several big-box retailers. Those retailers will only trade by X12 EDI dropped on an SFTP server, not by API. Before the integration, a coordinator exported purchase orders from a retailer portal, retyped them into D365, then manually built invoice files to upload back, which was slow and error-prone and left orders sitting for a day. With Microsoft Dynamics 365 F&O and SFTP / Flat Files connected, inbound 850 purchase orders are parsed into D365 purchase orders within the poll window, and confirmed invoices are written back as 810 files with a 997 acknowledgment. The re-keying step is gone and orders move the same day.

What you can do

  • Read D365 purchase orders, vendor invoices, vendors, and items over OData and write them as X12 or CSV files to a partner's SFTP folder.
  • Poll the inbound SFTP folder and create matching D365 entities such as VendorInvoiceHeaders and PurchaseOrderHeadersV2 from 810 and 850 files.
  • Authenticate D365 with Microsoft Entra ID OAuth 2.0 and the SFTP server with an SSH key, verifying the server host key.
  • Dedupe inbound files by filename and content hash and write deterministic outbound filenames so a retry never doubles a record.
  • Return X12 997 acknowledgments for inbound EDI and honor D365 Retry-After backoff, with a full audit trail and replay on every file.

Questions

Which direction does data move between Microsoft Dynamics 365 F&O and SFTP / Flat Files?
It is usually two-way and depends on the trading partner. Outbound, the connector reads D365 records over OData and writes them as X12 or CSV files to the partner's folder; inbound, it polls the folder and creates D365 entities such as vendor invoices and purchase orders from partner files. The general ledger and posted records stay authoritative in D365, so file data never overwrites a posted entry.
How does the connector know when a new file has arrived if SFTP has no webhooks?
SFTP is a pull-only transport with no native push, so the connector polls the inbound folder on a schedule, commonly every 5 to 60 minutes. It compares the listing against a processed-files log and dedupes on filename plus content hash so a re-listed file is never imported twice. To avoid reading a file that is still uploading, it waits for a sentinel file or a stable size before processing.
How are D365 entity writes handled to avoid duplicates and posting errors?
D365 OData has no idempotency key header and uses natural keys such as InvoiceNumber plus VendorAccount, so creating the same record twice returns a duplicate-key error that the connector handles gracefully. Vendor invoices are written only before they are posted, since posted records are read-only over OData. The connector also formats financial dimensions as the display string D365 expects so a write does not silently fail.

Related integrations

Connect Microsoft Dynamics 365 F&O and SFTP / Flat Files

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

Get started