We are integrating an external OMS with Dynamics 365 Finance & Operations and creating Sales Orders using the standard OData entities:
SalesOrderHeadersV4SalesOrderLinesV3
Our current flow is:
- Create Sales Order Header via OData (
POST /data/SalesOrderHeadersV4) - Retrieve the generated
SalesOrderNumber - Create lines via
POST /data/SalesOrderLinesV3
This works, but because header and lines are separate calls we must handle several edge cases in our integration layer:
- Header succeeds but line creation fails
- Some lines succeed and some fail
- Retry logic may create duplicate headers
- Need to implement idempotency and reconciliation logic
We explored OData batch (/data/$batch) with a single changeset to make the operation atomic. The goal was to create header and lines in the same batch request.
However, referencing the created header inside the batch (for example using $1/... patterns similar to the OData documentation examples) results in URI errors in D365, suggesting that SalesOrderLinesV3 may not be exposed as a navigation path from SalesOrderHeadersV4.
Because of this, we are trying to understand the recommended integration pattern for this scenario.
Questions:
- Is there a supported way to create a Sales Order header and lines atomically via OData in D365 F&O?
- Is OData batch intended to work for this scenario with these entities?
- If not, is the recommended approach to create the header first and then create lines while handling idempotency and retries in the integration layer?
- Alternatively, should Data Management / composite entities be used for this type of document-style import even for near-real-time integrations?
Any guidance on the recommended approach for creating Sales Orders from external systems would be greatly appreciated.
Thanks!


Report
All responses (
Answers (