The decision to hand a warehouse to a third-party logistics provider is usually made for good reasons: you do not want to run a building in a region you are growing into, or you need overflow capacity for a season, or the 3PL already has the labor and the equipment and you do not. None of those reasons are wrong.
The reason it goes sideways is almost never the 3PL's operations. It is that you now have two systems that each believe they hold the truth about your inventory, and they update on different clocks. D365 thinks it knows what is on hand. The 3PL's warehouse system actually knows. Between those two facts sits every late shipment, every oversell, and every reconciliation meeting nobody enjoys.
So the real question is not "should we use a 3PL." It is "how do D365 and the 3PL stay in agreement about what exists, where it is, and what just happened to it."
The first decision: who runs the warehouse system
Before any integration, settle who owns warehouse execution for each location.
If you run the building, D365's native Warehouse Management handles it: locations, wave and load processing, mobile device steps — the whole execution layer lives inside D365 and there is one system of record.
If a 3PL runs the building, their warehouse system handles execution and D365 steps back to being the system of record for inventory and finance. D365 does not pick or pack at that site. It tells the 3PL what to do and listens for what the 3PL did.
A lot of confusion on these projects comes from not drawing that line cleanly per site. You can absolutely run native WMS in your own DCs and integrate to 3PLs for others, in the same D365 instance — we do it regularly. But each location has to be unambiguously one model or the other, and the org structure in D365 (site, warehouse) has to reflect that.
The handshake that actually matters
When a 3PL runs the building, the integration is a conversation made of a few EDI documents, and getting that conversation right is most of the work.
The outbound order. D365 tells the 3PL to ship something. In EDI terms this is the 940, the warehouse shipping order. It carries the order, the items, the quantities, and the ship-to.
The confirmation back. The 3PL tells D365 what it actually shipped. This is the 945, the warehouse shipping advice. This is the document that lets D365 relieve inventory and move the order forward, and it is the one people underestimate, because shipped is not the same as ordered. Short ships, substitutions, and damage all show up here, and D365 has to be ready to receive a 945 that does not match the 940 it sent.
The inbound side mirrors it. A 943 tells the 3PL stock is coming; a 944 confirms what they received. And the 856, the advance ship notice, is how the 3PL tells your customer's systems (or yours) what is on the truck.
On-hand is a timing problem, not a data problem
Here is the thing that surprises people. Even with the messages mapped perfectly, D365 and the 3PL will disagree about on-hand — briefly, constantly, all day long. The 3PL picked an order ten minutes ago and the 945 has not flowed yet. A receipt landed on their dock and the 944 is queued. The data is not wrong; it is in flight.
Two practical consequences follow.
First, decide how D365 reflects inventory that is at the 3PL but not yet confirmed in or out. If you let sales commit against numbers that lag reality by an hour, you will oversell during your busiest hours — which are exactly the hours the lag is worst.
Second, build the reconciliation in from the start, not after the first bad month. A periodic on-hand file from the 3PL — often a daily inventory snapshot — compared against D365 on-hand, with a defined owner and a defined tolerance, is what catches drift before it becomes a writeoff. The integration handles the transactions. The reconciliation handles the truth.
Returns, the part everyone forgets
Returns flow backward through all of this, and they are where ghost inventory is born. A unit comes back to the 3PL, gets received, and if the status and the message handling are not defined, it either reappears as sellable when it is damaged or vanishes when it is fine. Decide the return disposition and the message that carries it before go-live, not after the first customer complaint.
What we would tell you on day one
A 3PL relationship runs on the integration, and the integration runs on exceptions, not the happy path. Anybody can map a 940 that matches a 945. The engagement is worth it when the short ship, the partial receipt, the damaged return, and the hour-long lag during peak are all handled on purpose.
Draw the execution-ownership line per site and make D365's org structure match it. Treat the 945 and the 944 as first-class citizens, because confirmation is where reality enters the system. Build the daily reconciliation before you need it. Define return disposition up front.
Frequently asked questions
Which EDI documents connect D365 to a 3PL warehouse?
On the outbound side, D365 sends the 940 (warehouse shipping order) to tell the 3PL what to ship, and the 3PL returns the 945 (warehouse shipping advice) to confirm what actually shipped. On the inbound side, the 943 (warehouse stock transfer shipment advice) tells the 3PL stock is coming, and the 944 (warehouse stock transfer receipt advice) confirms what was received. The 856 advance ship notice tells the customer's systems what is on the truck.
Why is the EDI 945 so important?
The 945 is the document that lets D365 relieve inventory and move the order forward — because shipped is not the same as ordered. Short ships, substitutions, and damage all surface in the 945, so D365 has to be ready to receive one that does not match the 940 it sent. Treat the 945 and the 944 as first-class citizens; confirmation is where reality enters the system.
Should D365 or the 3PL be the system of record for inventory?
When a 3PL runs the building, the 3PL's warehouse system owns execution and D365 is the system of record for inventory and finance. D365 does not pick or pack at that site; it directs and listens. Draw that line cleanly per site and make the D365 org structure — site and warehouse — reflect it. You can run native D365 Warehouse Management in your own DCs and integrate to 3PLs for others in the same instance, but each location has to be unambiguously one model or the other.
Why do D365 and a 3PL disagree about on-hand?
On-hand is a timing problem, not a data problem. Even with the messages mapped perfectly, the two systems disagree briefly and constantly all day because confirmations are in flight — a pick happened but the 945 has not flowed, or a receipt landed but the 944 is queued. The fix is to decide how D365 reflects unconfirmed inventory so sales does not oversell against lagging numbers, and to build a periodic on-hand reconciliation with a defined owner and tolerance.
How should returns be handled between D365 and a 3PL?
Returns flow backward through the integration and are where ghost inventory is born. A unit comes back, gets received, and if the status and message handling are not defined, it either reappears as sellable when it is damaged or vanishes when it is fine. Decide the return disposition and the message that carries it before go-live, not after the first customer complaint.
Caf2Code integrates Dynamics 365 Supply Chain Management with 3PL providers and native warehouse operations across distribution, manufacturing, and transportation clients. If your D365 and your 3PL are not telling the same story, we can help you find out why.