Notes
Which stock counts: on hand, available or committed?
The store should show available stock: what is on hand, minus what is committed to open orders, minus what may not be sold, at the locations that ship web orders. Of 100 units on the shelves in the example on this page, 64 are available to the store.
Updated
The short answer
The store shows available stock. On hand is too high, because it still holds units that are sold and waiting on the shelf to ship. The difference is not rounding. For item 20417 across three locations:
on hand, three locations 100
retail counter, does not ship -10
returns cage, in inspection -6
committed to open orders -15
safety stock -5
available to the store 64
An integration that sends 100 offers 36 units that cannot ship. That does not show on the day it happens. It shows on the order that sells the 65th unit.
Three choices set the number: which states of stock are subtracted, which locations count, and how much is held back. The whole stock flow is on stock and availability; this page goes through the states and the names each system gives them.
Six states of the same stock
An ERP or a warehouse system keeps more than one number per item. The names differ per system; the states are the same.
| State | What it is | Item 20417 | Counts for the store |
|---|---|---|---|
| On hand | Everything physically at a location | 100 | No, too high |
| Committed | Sold, not yet shipped | 15 | No |
| Unavailable | Damaged, in inspection, on hold | 6 | No |
| Safety stock | Held back on purpose | 5 | No |
| Available | On hand minus the three above, at shipping locations | 64 | Yes |
| Incoming | On an open purchase order, with a date | 240 on Nov 30 | Separately, with the date |
Backorders sit outside these six. A backorder is a sale without stock behind it. An item with 0 on hand and 6 back ordered has 240 incoming, but only 234 of those are free to sell when they arrive.
What Shopify, NetSuite and Business Central call each state
These names were read in each vendor's documentation on October 3, 2026.
| State | Shopify | NetSuite | Business Central API v2.0 |
|---|---|---|---|
| On hand | on_hand |
Quantity On Hand | inventory on item |
| Committed | committed |
Quantity Committed | Not in the standard API |
| Unavailable | reserved, damaged, quality_control |
A location with Make Inventory Available cleared | Not in the standard API |
| Safety stock | safety_stock |
Safety Stock Level | Not in the standard API |
| Available | available |
Quantity Available | Not in the standard API |
| Incoming | incoming |
Quantity On Order | Not in the standard API |
| Back ordered | No state | Quantity Back Ordered | Not in the standard API |
Shopify defines the sum in its inventory states documentation: on_hand is available plus committed, reserved, damaged, safety_stock and quality_control. incoming is the one state that is not physically there. NetSuite defines Quantity Available as Quantity On Hand less Quantity Committed in its stock level definitions.
Four details in those definitions cause wrong numbers in practice:
reservedin Shopify is not reserved for orders. It is stock set aside for holds or inspection. Stock for open orders iscommitted. An integration that maps an ERP's "reserved for sales orders" field to Shopifyreservedmoves the units into the wrong state.- NetSuite's Quantity Available does not take off safety stock. At Reno it is 84 minus 15 is 69. The safety stock of 5 is subtracted by the integration: 64.
- NetSuite's Quantity Available never goes below zero. Six units back ordered show as Available 0, the same as an item with nothing owed. The integration reads Quantity Back Ordered next to it to know how much of the next receipt is already sold.
- Business Central's standard API has one number.
inventoryon theitemresource is a single read-only quantity, without committed stock and without a location. Available per location needs an API page or query added to Business Central for that purpose.
Shopify sends inventory_levels/update when available changes. Changes to committed, reserved, damaged, safety_stock and quality_control trigger no webhook, so an integration that listens for webhooks sees the new available figure and not which state the units went to.
Which locations count
Stock is a number per location. Item 20417 sits in three places:
| Location | On hand | Ships web orders | Counts |
|---|---|---|---|
| Reno warehouse | 84 | Yes | 84 |
| Sacramento retail counter | 10 | No | 0 |
| Returns cage, inspection | 6 | No | 0 |
| Total | 100 | 84 |
An integration that asks for the item total gets 100. One that asks per location and adds only the shipping locations gets 84. Both numbers are correct; they answer different questions.
NetSuite has two checkboxes on a location record for this: Make Inventory Available, which decides whether on-hand stock there can go on orders, and Make Inventory Available in Web Store, which decides whether it counts toward the quantity NetSuite's own web store shows. Neither tells an outside integration which store or channel a location serves. That rule lives in the integration, per location and per channel, as described on multi-location inventory.
What goes wrong between two runs
Even with the right formula, the store runs behind the warehouse. How far depends on how often stock is read and in which order orders and stock are processed.
An example with a run every 15 minutes. The store shows 64. At 10:02 a customer orders 20 and the store lowers its own count to 44. At 10:05 the stock run reads NetSuite. The order of 10:02 has not reached NetSuite yet, so NetSuite reports 69 available, the integration writes 64, and the store offers 20 units too many until the next run at 10:20.
An integration prevents this in one of two ways:
- Orders first, then stock. The run sends open orders to the ERP and reads stock afterwards. NetSuite has committed the 20 and reports 49; minus 5 is 44.
- Subtract orders in flight. The integration knows which store orders it has not delivered yet and takes them off the answer: 64 minus 20 is 44.
What remains is selling through other channels within one run: the retail counter, a marketplace, a sales rep entering phone orders. That is what the safety stock covers. If the counter sells 4 units of an item an hour and stock runs every 15 minutes, it sells 1 per run on average, and a buffer of 2 also covers a busy run. A buffer also hides stock: with a buffer of 5 and 5 available, the store shows 0. For an item that sells 3 a month, that is 5 units never offered online, so the buffer is set per item group, not as one number for the catalog. The safety stock page covers the sizing, and real time versus batch the interval.
Zero is three states
An item at 0 can be sold out and arriving next week, discontinued, or missing from today's supplier file. The store shows the same number for all three and needs three different messages. The integration sends a status next to the quantity: active with an expected date, discontinued, or unknown, which keeps the last quantity and raises an alert.
Incoming stock is the 240 units on the purchase order. It is not stock, and it is information a buyer uses. The integration sends two values: available 0 and the expected date. In Shopify incoming is its own state next to available, and in NetSuite it is Quantity On Order; the date sits on the purchase order line and is read from there. With 6 back ordered, 234 of the 240 can be offered against that date.
What this means for your integration
We set per item group which states are subtracted, which locations count for which channel, and how large the buffer is. The integration calculates the available number on the source side and writes only that number to the store. A dry run before go-live puts the calculated number next to what the store shows now, per item, so the differences are visible before anything is overwritten.
Then we host and run it. In the dashboard you see per run which quantities changed, from which number to which. The full stock flow is on stock and availability. Tell us your systems and locations, and you hear which number each system delivers and what still has to be subtracted.
Frequently asked questions
What is the difference between on hand and available inventory?
On hand is every unit physically at a location, including units already sold and waiting to ship. Available is what a new customer can still buy: on hand minus committed, minus anything set aside or blocked. Shopify calls them on_hand and available; NetSuite calls them Quantity On Hand and Quantity Available.
What is committed inventory?
Units promised to orders that have not shipped yet. They are still on the shelf and still in on hand, but they are no longer for sale. An order for 20 units lowers available by 20 at once; on hand drops only when the shipment leaves.
Should my retail store's stock count toward the web store?
Only if the retail location ships web orders or holds them for pickup. Counting a location that does not ship sells units online that the warehouse cannot send. The choice is set per location and can differ per sales channel; the multi-location inventory page covers the rules.
Why does the store quantity jump back up after an order?
The store lowers its own count when the order is placed. If the integration then writes the ERP's available quantity before that order has reached the ERP, the old, higher number is back. The integration prevents it by sending open orders before it reads stock, or by subtracting the orders it has not delivered yet.
Can I sell stock that is still on a purchase order?
Yes, when the store shows the date with it. Incoming stock comes from open purchase orders and has an expected date. The integration sends the quantity and the date as separate values, so the store shows 0 in stock with an expected date instead of promising shipment from stock. See delivery dates.
Tell us what you need
Tell us which systems you use and what needs to work better. We reply personally within one working day. We help you define the work, then agree the price and timing before you commit.
- You know the price and the timeline before you commit to anything
- We work out the connection that takes the work off your hands
- We handle the build, hosting, monitoring and maintenance
- Your team has less information to retype and fewer discrepancies to chase