
Is there an API-first alternative for Dual Write? - Patrick Mouwen
Is there an API-first alternative for Dual Write?
This is a question which has been bugging me for the last 3 years..
Every time I read a Technet article about D365 SCM or D365 CE being the price master (example), I catch myself thinking halfway:
“Really? Isn’t there an easier way?”
Here’s what we’re doing today:
1️⃣ The process (e.g. quote-to-order) runs in system A – D365 CE
2️⃣ System A asks system B – D365 SCM to recalculate pricing
3️⃣ The recalculation happens in B
4️⃣ System B syncs the data back to A
5️⃣ The process continues… hopefully
But what if something fails halfway?
⚠️ What if the recalculation (step 3) throws an error?
⚠️ Or the data sync (step 4) doesn’t bring back all price components — discounts, attribute pricing, shipping charges, minimum-order fees, overrides?
Couldn’t we do this faster, cleaner, and more reliably?

✅ My suggestion: API-first.
Let CE call SCM’s pricing engine directly in real time — no sync, no waiting, no partial data. You get a single, complete response containing every price component.Instant feedback, fewer moving parts, and a process that never pauses “mid-flow.”. But that’s theory? Can it work in reality?
An API-First Approach
Let’s explore the approach: there’s no data sync between D365 CE and D365 ERP. Instead, quote or order lines in CE are sent to an API endpoint that returns a detailed pricing breakdown — typically within 500–750 ms ⚡.
CE can trigger this in multiple ways:
as an in-process (underwater) flow, automatically invoked when a quote line is added, updated, or deleted,
or more explicitly via a JavaScript-enabled “Recalculate Pricing” button.
But the real question is… 👉 What’s behind that API endpoint?

D365 SCM OData and custom APIs aren’t known for stable, high-volume performance. They work fine for batch integrations, but for consistent real-time request/response patterns, they often fall short. There are many reasons — complex data models, non-optimized joins, limited caching — but the bottom line is: ⚠️ it’s very hard to make them truly performant consistently, especially under high volume.
By contrast, the D365 Commerce APIs are built for speed and consistency. They’re optimized for high-frequency scenarios like online cart operations and POS transactions, where performance must be predictable.
Even better: the Commerce Cart APIs support both the existing SCM pricing engine and the new Unified Pricing model — built on the same Commerce pricing foundation, now enhanced with attribute-based pricing.
SCM and Unified Pricing API for Quote to Order
So, to explore the options, I decided to develop a single API endpoint, implemented via an Azure Logic App, which wraps several existing D365 Commerce APIs into one cohesive call.
Create Cart
Add Cart Line
<Placeholder for adding shipping address and mode of delivery in the future>
Delete Cart

The API requires a very simple request body:

But it returns full pricing, including gross pricng, net pricing, shipping charges, minimum order fee, taxes, customers discounts, attribute based discounts etc. – Just a snippet:

No data sync. No duplication of logic. Just a question and a fast, detailed answer — so the Quote-to-Order process can simply continue. ✅ No process breaks. ✅ No endless loading spinners.
But wait… doesn’t Commerce require a Channel and an OUN (Operating Unit Number) to function? Can it really work with just a customer and quote lines as input? 🤔
How to “hide” the Commerce channel concept for Dataverse
By implementing a very simple Default flag on the channel in the Customer hierarchy form in D365 SCM, we can relate a B2B customer to 1 default channel in D365 SCM:

We can then accept the B2B customer as header parameter in the request from Dataverse, as opposed to the OUN (=Commerce channel):

Benefits
In my view, this API-first approach offers significant advantages over Dual Write, especially for the “Better Together” stories between D365 Dataverse (CE, Sales, Field Service, IOM, etc.) and D365 SCM — where large data volumes and complex business logic come into play.
If you’d ever count how many data entities need to sync through Dual Write just to make advanced pricing details flow between the two ecosystems… you’d quickly see how fragile and maintenance-heavy that becomes.
To make it concrete, the table below summarizes the most relevant benefits of API-first vs. Dual Write for this scenario 👇
Further optimization
The Logic App which I pragmatically built for my prototype is a so called Composite API: it wraps multiple standard Commerce APIs into 1 end point. There are platforms which do this wrappin more efficiently at run time than a Logic App. An example is FastAPI.
Another optimization would be to implement api-key authorization between Dataverse and D365 SCM. The ideal platform for this is Azure API Management. APIM can abstract Commerce CSU App or Customer based authorization and work securely with api-key towards Dataverse for simplification (which is easier to implement between the systems).
If you’re interested in this API-first approach, feel free to send me a dm on [email protected]. We are specialised in API development and integration between D365 SCM, Dataverse, Commerce and 3rd party systems.
