In-transit inventory and available to promise: counting the stock that hasn't landed yet
On-hand is not your position. Your position is on-hand plus what's on the water and on the road, netted against what you've already committed. Here's the formula, the dates that break it, and the three decisions it makes possible.
Inventory Visibility, the parent page, is about getting one reconciled inventory record out of five disagreeing systems — WMS, ERP, TMS, forecast and POS — at the grain a replenishment decision is actually made. Start there if the question is whether your inventory data can be trusted at all. This page assumes that record exists and does arithmetic on it: the specific calculation that turns a position into a promise, and the three actions that only become available once in-transit is inside the number. The in-transit half of that record is built from the same normalised carrier and forwarder milestones behind Shipment Visibility — which is why the receipt date can move at all.
Start with Inventory VisibilityWhat available to promise means, and the formula
Available to promise (ATP) is the quantity of a SKU you can commit to a new order without breaking a commitment you have already made. It is not on-hand. It is on-hand that is genuinely free, plus receipts that will physically land inside the horizon, minus demand already committed against that horizon.
The calculation, run as a cumulative forward walk rather than a single number:
ATP(t) = [on-hand unrestricted − allocated − safety stock] + Σ scheduled receipts through t − Σ unallocated committed demand through t
That one word is where most hand-built walks break. If you net allocations out of the opening position, you must exclude those same order lines from the demand you subtract forward, or you subtract them twice and every bucket reads worse than it is. Two conventions work and you have to pick one: net allocations from on-hand and count only unallocated demand forward, or leave on-hand gross and subtract every committed line at its required date. The second is easier to audit. The first is what most ERPs do. What does not work is half of each, which is what a spreadsheet inherits when three people have touched it.
Every term is a trap. On-hand unrestricted means physically in the building, put away, not blocked for QA, not staged against a pick. Allocated means reserved against an open order line, including store replenishment orders that may live in a different engine than customer orders. Scheduled receipts is the term this page exists for: it should mean receipts arriving by the date the goods will actually be available to ship, not the requested, confirmed, or promised date carried on the PO line — and if you cannot say which of those four your ATP engine is reading, that is the first thing to go find out. Safety stock is a policy input you either net out or you don't; pick one and hold it.
The cumulative walk matters because ATP in week 4 is meaningless if week 2 is already negative. A single-bucket ATP hides the stockout it is standing on top of.
A useful discipline: publish ATP in three tiers and label which one any given number is.
Tier 1 · On hand
On-hand that is genuinely free — put away, unrestricted, net of allocations and whatever safety stock policy you hold.
Tier 2 · In transit
In transit with a confirmed departure or tender and an arrival ETA inside the horizon, discounted to its available-to-ship date rather than its arrival date.
Tier 3 · On order
On order but not shipped. Real commitment, no date you can stand behind.
Tier 3 is never ATP-eligible for a customer promise — but it is exactly the number you need to decide whether to reschedule a purchase order, which is why deleting it is the wrong fix.
The same position, two receipt dates
RDC 5, SKU 41822, cases. One receipt, booked two ways.
| Bucket | Receipts | Unallocated committed demand | ATP on PO dates | ATP on carrier milestones |
|---|---|---|---|---|
| Opening position | 4,200 on-hand − 900 allocated − 1,500 safety stock | — | 1,800 | 1,800 |
| Week 1 | — | 1,600 | 200 | 200 |
| Week 2 | 2,400 — PO 88214-1, per PO date | 1,700 | 900 | −1,500 |
| Week 3 | 2,400 — PO 88214-1, per carrier milestones | 1,650 | −750 | −750 |
| Week 4 | 3,600 — PO 88301-1 | 1,600 | 1,250 | 1,250 |
RDC 5, SKU 41822, cases. Same on-hand, same allocations, same demand, same purchase orders. The only variable is which date receipt 88214-1 is booked against. Cumulative — each ATP figure carries forward. Illustrative position.
Where the two columns diverge
The ERP's walk says week 2 is fine — 900 cases of headroom — and that you go short in week 3 by 750. Same on-hand, same allocations, same demand, same purchase orders in both columns. The only difference is which date receipt 88214-1 is booked against.
The ERP carried the confirmed delivery date from the PO line. The shipment's actual discharge is five days behind the ETA that date was built from, and once you add terminal dwell, customs release, drayage and putaway, those 2,400 cases are available to ship in week 3, not week 2.
On PO dates
−750
First miss in week 3, one short bucket.
On carrier milestones
−1,500
First miss in week 2, two consecutive short buckets.
That one date change does two things. The exposure starts a week earlier — week 2 instead of week 3 — and at its worst it is twice as deep. Which means the ERP's version gives you three weeks before the first miss and one problem to solve; the real version gives you two weeks and two consecutive short buckets. That is the difference between a DC-to-DC transfer that can still be booked and picked, and an airfreight conversation — and it changes whether the order you are about to confirm should carry a later date.
This is not an edge case. It is the default behaviour of an ATP walk whose receipt dates are entered once at PO creation and never re-derived from what the shipment is doing. The same failure runs on a domestic PO — the receipt sits on the confirmed delivery date rather than the tender and transit actually booked.
Same on-hand, same allocations, same demand, same purchase orders. One receipt dated off carrier milestones instead of the PO line, and the shortage arrives a week earlier and twice as deep.
Why your ERP's ATP number is wrong
Your ERP answers the question with the only inputs it has. The four inputs to ATP live in four different systems, keyed four different ways, timestamped on four different clocks — and nothing reconciles them.
| ATP input | System of record | Keyed on | Where it breaks |
|---|---|---|---|
| On-hand unrestricted | WMS | License plate, lot, bin | End-of-day posting lag; putaway gaps; QA-blocked and staged stock counted as free |
| Committed demand / allocations | ERP or OMS | Sales order line | Store replenishment sits in a separate engine; cancelled allocations never released |
| Scheduled receipts (in transit) | TMS, forwarder, carrier | Booking, container, B/L | No link to the PO line; the date is the PO's date, not the vessel's |
| Open purchase commitment | ERP | PO line | Change messages not reflected; split shipments modelled as one receipt |
| Actual receipt quantity | WMS goods receipt | ASN, license plate, PO line | Short or damaged receipts don't flow back to the walk; the forward position still carries the full ordered quantity |
| Forecast and safety stock | Planning system | SKU × location × period | A policy input, not an observation — and the one nobody re-checks |
The join problem
The reconciliation is the hard part, and it is mostly a keying problem. A container is keyed on booking and bill of lading, a purchase order on PO line, a receipt on ASN and license plate. One container holds lines from three POs; one PO line splits across two containers and arrives eleven days apart. Until shipment events are joined back to PO lines at the right pack configuration and unit of measure, you cannot tell the ATP engine when the receipt arrives — only what somebody typed when the PO was raised.
Most of what the join needs is already moving between you and your partners. The message that matters most here is the 856 ASN: its shipment / order / pack / item hierarchy is the only standard message that ties a physical pack back to an order line — precisely the link your ATP engine is missing. Around it sit the status messages that carry the dates, 214 for road and 315 for ocean container events, and the warehouse pair 940/945, which closes the loop on what was actually shipped versus what was instructed.
On Orkestra's side: 204, 210, 214, 856 and 940/945 are supported directly, alongside API feeds, portal data and custom flat files for everything else. If your position depends on a set that is not on that list, that is an integration scoping question to raise on the call rather than an assumption to make from a web page.
The data usually exists. What is missing is the join — and a receipt date derived from the last event rather than the first plan.
What counts as in-transit inventory — and when it should count
In-transit inventory is stock you own that has left the supplier or the shipping location and has not yet been received into a location you can ship from. There are two tests on it, and they answer different questions.
The accounting test
Ownership is the first test — and it is not settled by Incoterms alone, which is where most reports get it wrong. Incoterms allocate risk, cost and obligation; title passes according to your sales contract, and the two often differ. In practice most teams use the risk-transfer point as the working proxy: on FCA or FOB terms the goods are on your side from origin hand-over or vessel loading, on DAP or DDP they stay the seller's until delivery. Confirm which convention your controller actually applies before you put an in-transit figure into anything finance will read — that is the number that shows up as goods in transit on the balance sheet. It is capital sitting in a lane that your on-hand report does not mention.
The operational test
A different question from the accounting one, and for ATP the only one that matters. In-transit counts when you can name the date it becomes available to ship. That needs two things to be true: a confirmed departure or tender, and an arrival ETA with a credible band around it.
The band is the part that usually gets dropped, because a point date is easier to put in a cell. ETA precision is a function of distance to arrival, and any honest ATP model should carry that rather than treating a point date as fact. As a working discipline: outside 14 days, carry a several-day band and plan against the late edge; inside 7 days the band tightens to a day or two; after arrival the remaining lag is dwell plus customs plus drayage plus putaway, which varies materially by port pair and by DC and should be measured per lane rather than assumed. Whatever your real numbers are, use the late edge to promise and the early edge to decide not to buy more.
Worth being clear about who owns which half: the arrival date and its confidence come out of carrier and forwarder events and can be normalised for you. The lag from arrival to available-to-ship is your operation — your terminal, your broker, your dock, your putaway — so it is a parameter you measure and supply, not one a platform can infer. Get that number wrong and honest milestones still produce a dishonest position.
Two rules that prevent most bad promises: never let a shipment that has not departed contribute to a customer commitment, and never count a receipt as available on its arrival date — availability is arrival plus your measured dwell-to-putaway lag for that lane.
A receipt date that never moves is not a stable date
Pull any purchase order line that closed last quarter and count how many times its receipt date changed between the day it was raised and the day the goods were booked in. In most ERPs the answer is zero. The vessel behind it changed several times. The tell that a forward walk has gone stale is not a wild variance at goods receipt: it is a date field that has been quiet for six weeks.
Dating inbound off milestones is not precision for its own sake. Nobody needs the receipt date to the hour. What they need is for the number to move while there is still something to do about it, because each of the three calls below is priced by how early you knew.
The three decisions a correct position unlocks
A correct position is only worth the arithmetic if somebody acts on it inside the window. Three actions, each with a window that closes.
Reschedule or reduce the purchase order
This is the decision that rarely gets attributed to the position, because nothing visibly breaks when you get it right. It happens at the node that looks thin on paper and is not.
RDC 2, same SKU. On-hand shows 3.5 weeks of cover against 1,400 cases a week, the policy minimum is four, and the replenishment run fires. What on-hand does not mention is 4,200 cases already on the water against that node, arriving across weeks 2 and 4 — which puts real cover at just over six weeks before the new order is even raised. Raise it anyway and it lands on top of nine. That inventory is not a service failure, so nobody escalates it: it surfaces four months later as storage, then as markdown, and by then it is attributed to the forecast rather than to the buy.
Note the asymmetry with RDC 5 above — same SKU, same week, opposite call. Neither decision is available from a network total, and neither is available from on-hand.
Window
Move the stock you already own
RDC 5 goes negative in week 2. If RDC 2 is carrying nine weeks against the same article, the answer is a DC-to-DC transfer or a cross-dock at the port of discharge — not a new buy and not airfreight.
The windows are sequential and they are not the same window. Changing the discharge port is realistically only available before the manifest is filed. A divert or cross-dock at the port of discharge stays open until the container is released and drayed. After goods receipt it is no longer a reroute at all — it is a transfer, with the cost and lead time that implies. Knowing at week 0 instead of week 2 is what keeps the cheap option on the table.
Window
Quote a date you can hit
When the position your order desk quotes against includes inbound and is tiered by confidence, the promise comes off the position rather than off a lead-time table. Fewer optimistic confirmations, fewer expedites, fewer OTIF misses that started as a date somebody guessed. The promise itself is still made in your ERP or OMS — what changes is the number it is reading.
Window
The other half: cover you already bought
Everything above is a shortage story because shortage is what escalates. The mirror image is quieter and usually costs more. When in-transit is invisible to the replenishment run, the buy fires against on-hand, the goods that were already floating toward you arrive anyway, and the node ends up carrying nine weeks against a four-week policy. Nothing breaks. No customer calls. It surfaces a quarter later as storage cost, then as markdown, and by then it is filed under forecast error rather than under a receipt date.
The reason most teams pad safety stock is that they do not trust their receipt dates — which makes honest dates a working-capital argument, not just a service one.
And for multi-echelon operators the DC position is not the last word. ATP at the DC is not availability at the shelf: a promotional commitment is made against a DC number that still has to survive an allocation run across several hundred stores, and a receipt that lands three days late at the DC lands a week late on the shelf. The same discipline applies one level down against the reconciled record — tier the position, date the inbound off real events, and never promote against tier 3.
The freight does not wait for your planning cycle
Containers discharge on a Saturday. Drayage runs overnight. Rail ramps move boxes while the office is shut. A position rebuilt once a week spends six of those days describing a picture that has already changed, and the replenishment run does not care which day of that week it fires on.
So the test is not only whether the walk is right. It is whether it is at least as fresh as the decisions taken off it. Buys, transfers and promises fire on their own schedules, which means the position has to be rebuilt on the events rather than on the calendar.
Where Orkestra fits — and where it stops
Orkestra sits above the systems you already run and reconciles the position: on-hand from the WMS, allocations and open purchase commitment from the ERP, in-transit from the TMS, forwarders and 200+ carrier connections. The join is configured against your PO and ASN keys at the pack configuration a planner actually decides on — that configuration is the scoping work, and it is what lets the receipt date in your forward walk follow normalised carrier and forwarder milestones instead of the date somebody typed at PO creation. No rip and replace: the WMS keeps the four walls, the ERP keeps the master record.
Reconciling the position is half the job. The other half is that somebody has to act on it before the window closes. Because the position is reconciled and the inbound is dated off real milestones, a threshold can be set on the thing you actually care about — forward cover at a node, by article, by pack config — rather than on shipment status. When RDC 5 crosses it, the Exception Monitoring Agent raises it against the position, and the shipment that moved it is attached to the case.
Cover at RDC 5 falls below policy in week 2 · container MSKU4471983 on PO 88214-1 slipped 5 days
One case, with the cause in it. From there the Workflow Trigger Agent runs the playbook you defined, with a named owner and an SLA: notify the buyer to reschedule the replenishment PO before supplier cut, open the transfer request against the node carrying excess cover, raise the divert or cross-dock request with the forwarder while it is still cheap, and flag the affected open order lines so your order desk re-quotes off the real position. Orkestra raises, routes and tracks those actions and syncs status back to the connected systems — the PO reschedule is still confirmed with your supplier, and the promise date is still committed in the ERP or OMS that owns the order. Order-side drift is monitored through Order Management; the rules, thresholds and escalation chains live in Workflow Automation and Exception Management.
What Orkestra is not
Stated plainly, because this page invites the assumption. Orkestra does not run your ATP calculation and does not commit inventory to an order line — the ATP walk stays in the ERP or OMS that owns the order, and Orkestra does not replace it. It is also not a demand planning or forecasting engine and not an inventory optimiser: it does not generate the forecast, set safety stock, or compute reorder points. Those stay in your planning system and Orkestra reads them as inputs.
What it does is narrower and, if your receipt dates are wrong, more useful. It reconciles the four inputs your ATP engine is already trying to use — on-hand, allocations, open purchase commitment, in-transit — into one position at decision grain, dates the inbound off normalised carrier and forwarder milestones instead of the date typed at PO creation, and fires a workflow when that position crosses a threshold you set. Your ERP keeps calculating; it calculates on receipt dates that reflect what the freight is actually doing, and somebody gets told while the window is still open. If what you need is a forecast built, that is a different vendor. What Orkestra covers is the position you already have: reconciled, dated off real milestones, and wired to a trigger.
Where this sits
This page is one capability under Inventory Visibility. The rest of the picture:
ATP and in-transit questions, answered
A $32B fintech replaced manual tracking with real-time global inventory visibility — and took 10% out of transportation cost.
“Replaced manual tracking with real-time orchestration, cutting support response times by 85%.”— $32B FinTech Company, Technology & Hardware
