Your order automation is checking stock when it should be checking availability
Book stock above zero does not mean the units are free. If the integration ignores allocations and never reserves what it checked, it will promise delivery dates on cartons that were committed to somebody else weeks ago.
This article was generated by AI. Labelled in accordance with Article 50 of the EU AI Act. Responsible for publication: Sophera Consulting.
Two orders, four seconds apart, same 340 cartons
A stock check does not take anything out of the warehouse. It reads a field and moves on. So two orders arriving four seconds apart will both read 340, both confirm 300, and both get told they are fine.
That is the shape of nearly every overselling bug we get called in for. The integration is not doing arithmetic wrong. It is treating a question as though it were a commitment.
The other half of the problem sits one layer below that, in which number gets read at all.
The 340 that were never free
A safety equipment distributor supplying logistics operators and two hospitals ran orders from a customer portal straight into their ERP. Before creating the order, the workflow checked stock. If the ordered quantity came in under the number it found, the confirmation went out automatically with a delivery date two working days out.
In June a customer ordered 300 cartons of nitrile gloves. The ERP reported 340 in stock. Confirmation sent, delivery Wednesday.
Tuesday morning, picking found 40. The other 300 had been allocated two weeks earlier to a hospital contract call-off scheduled for Thursday. They were physically on the shelf, which is precisely why they showed up in stock. They had not been free since May.
Six months of order history contained 22 orders with the same pattern. Six shipped late. The other sixteen were rescued by an inbound delivery that happened to land in time.
Three numbers, one word
Warehouses hold cartons. Systems hold at least three numbers about those cartons, and treating them as interchangeable is what breaks the workflow.
Book stock is what the system says is physically there. Almost every product endpoint returns this one as `quantity` or `stock`, because it is the only figure that needs no context.
Allocated stock is the portion already committed: open sales orders, contract call-offs, transfers to another site, production orders, consignment.
Available stock is the difference, extended by confirmed inbound receipts inside a time window. Depending on the vendor your ERP calls this available-to-promise, free stock, or unrestricted stock.
Only the third one answers what the workflow is really asking, which is whether a promise can be made.
Availability is a function, not a field
Book stock hangs off the product record. Availability comes out of a calculation that needs arguments: which warehouse, which date, which batch, and in some businesses which customer, because certain stock is ring-fenced for certain accounts.
That calculation lives elsewhere in the ERP, usually in the sales order module or behind a dedicated availability service. The product endpoint cannot run it, so it returns the one number it can produce while knowing nothing about the order.
The API is not lying. It is answering a narrower question than the one being put to it.
A date is part of the question
Even integrations that correctly read free stock frequently drop the second half.
Availability describes a moment. Three hundred cartons are free today and gone Thursday because a call-off lands in between. Zero are free today and eight hundred are free Friday because a goods receipt is booked.
Checking at order entry and deriving a delivery date from it compares a value from now against a promise for the day after tomorrow. That holds up until something happens in between, which at any real order volume it does.
What the automation actually removed
The integration did not invent this failure mode. It removed a check that used to happen without anyone naming it.
When a person keyed the order into the ERP, the order screen showed free stock in red. They would not have described that as running an availability check. They saw the colour and picked up the phone. Replace them with a webhook and the colour goes with them.
Worth being precise about, because the fix is not putting the person back. It is moving the check they were doing into the workflow, with the number they were looking at.
What we build instead
Start by asking for availability rather than reading stock. Most ERPs expose this somewhere: an availability endpoint, an order simulation call, a proposed line item that comes back priced and dated. If you cannot find it, ask whoever administers your ERP before you go through the API docs. It tends to be documented under sales orders rather than under products.
The second change matters more and gets skipped more often. Checking and reserving belong in the same call. Where the ERP supports reservations over the API, use them. Where it does not, create the order first and validate coverage afterwards, so a record exists before the confirmation leaves. What goes out to the customer should follow a write, not a read.
Reservations need an expiry or you get the mirror-image problem four weeks later. Orders parked in an approval step will sit on inventory nobody is waiting for. Forty-eight hours is a workable starting value for portal orders.
Split the acknowledgement from the commitment. "We have your order" can always go out. "Delivery Wednesday" goes out only once the quantity is reserved. Separating those two messages is half an hour of work and takes most of the cost off the table.
For fast-moving lines we auto-confirm only up to a fraction of free stock and route the rest to manual review. It is inelegant. It works.
Then measure the gap. A weekly comparison of promised against actual ship date surfaces this before a customer does. At the distributor it now runs as a scheduled report that posts into a channel every Friday.
When the ERP has no reservation API
This happens more often than vendors admit, particularly with older systems and with integrations that run through a middleware layer.
Two approaches have held up for us. The first is a small reservation table alongside the workflow, recording which quantity was committed by which order and when. The availability check subtracts those open commitments from the ERP figure. It is an extra component carrying its own maintenance cost, but a contained one.
The second is to make automatic date commitments only above a safety threshold. One client sets that at thirty percent of average weekly consumption. Anything below gets an acknowledgement with no date and a line on a list somebody reviews twice a day. It is the worse design and it shipped in two days.
How to tell in ten minutes
Open the step in your workflow that checks stock.
Which field does it read? If it is called `quantity`, `stock`, or `onHand`, it is almost certainly book stock.
Does the request carry a date? If not, you are checking against today and promising for later in the week.
How many steps run between the check and the order being written? Every one of them is a window in which a second order can be promised the same units.
In most of the integrations we look at, all of this traces back to a single step. That is the useful part: nobody has to rebuild the workflow. It has to ask for a different number.