Skip to main content

Allocation, hold & backorder statuses & fields

This page is the lookup for three related records that commit and reserve stock behind an order: the allocation (which claims stock or demand for a line), the stock hold (which fences physical units off from selling), and the backorder queue that ranks demand waiting on supply. It defines every allocation status, every derived hold state, the fields each record carries, the columns and filters on the Backorders page, and the account-level backorder settings.

For the model behind these records — how demand becomes an allocation, how a backorder gets covered by a purchase order and then released — read the concept page Allocations & backorders. To work with them in the app, see Work the backorder queue, Browse allocations & pin stock to bins, and Place & manage stock holds.

There is no "reserved" inventory status

SKU.io has no reserved allocation status and no "reserved" stock bucket. Demand and stock are tracked through the five allocation statuses below, the stock states (Available, Allocated, On Hold, Non-Sellable), and stock holds. If you are looking for where committed stock lives, it's the Allocated status and the Allocated stock bucket — see the stock states & fields reference.

Allocation statuses

An allocation is a single row that ties a quantity of a product at a warehouse to a demand link — a sales order line, a warehouse-transfer line, or a manufacturing-order component. Its status moves through five values. Three are active (they represent live demand: Planned, Awaiting Receipt, Allocated); two are terminal (Fulfilled, Cancelled). Only Allocated claims physical on-hand stock and reduces Available.

StatusActive?Claims on-hand?Meaning
PlannedYesNoDemand with no stock and no purchase-order coverage yet — a true shortage.
Awaiting ReceiptYesNoA backorder bound to an incoming purchase-order line that will cover it.
AllocatedYesYesOn-hand stock committed to the line. The only status that reduces Available.
FulfilledNo (terminal)NoThe linked shipment shipped. Can't transition further.
CancelledNo (terminal)NoNo longer needed. Can't transition further.

The rest of this section documents each status and its transitions.

Planned

A Planned row is demand with no on-hand stock and no purchase-order coverage yet — a real, uncovered backorder. It carries a priority (its rank in the backorder queue) and a supplier, so you can see who to reorder from.

  • Supplier is backfilled automatically. When a Planned row is created without a supplier, SKU.io fills supplier_id from the product's default supplier (the is_default row in the product's supplier list). The same backfill runs on update, so a row that transitions into Planned from a status that didn't need a supplier still gets one.
  • It marks the order line as backordered. Any Planned (or Awaiting Receipt) row sets has_backorder = true on the linked sales order line, which is what surfaces the line as backordered on the order and blocks the order from closing.

Transitions from Planned:

ToTriggerWhat happens
Awaiting ReceiptA purchase-order line is linked (coverage set)The row binds to purchase_order_line_id; it stays a backorder.
AllocatedStock arrives and the backorder is releasedThe row claims the freed on-hand stock; priority is cleared.
CancelledThe demand is cancelledTerminal.
Unreserving reverts an allocation to Planned

Unreserving an Allocated row (freeing its stock back to the pool) reverts it to Planned and assigns it a fresh priority at the back of the queue, so it re-enters the backorder pipeline rather than jumping the line.

Awaiting Receipt

An Awaiting Receipt row is a backorder that a purchase-order line is expected to cover. It still counts as an active backorder (has_backorder stays true) — the stock hasn't landed yet. Its ETA derives from the covering purchase order or its inbound shipment.

  • is_tight_coverage marks a manual link created in the PO Builder, as opposed to an automatic one. Tight (manual) links are protected from automatic re-shuffling when priorities are reordered — see Preserve manual PO links.
  • Coverage is kept in sync with PO capacity. If a covering PO line's quantity shrinks below what it was covering, SKU.io reconciles the excess — the uncovered remainder reverts to Planned with its purchase_order_line_id cleared so it can be re-covered.

Transitions from Awaiting Receipt:

ToTriggerWhat happens
AllocatedThe covering PO is receivedThe PO link is nulled and the row claims the received stock.
PlannedCoverage is clearedThe purchase_order_line_id is removed; the row is an uncovered shortage again.
CancelledThe demand is cancelledTerminal.

Allocated

An Allocated row is on-hand stock committed to the line. It's the only status that reduces Available — the stock is spoken for but still physically in the warehouse until the order ships. Its priority is cleared (it's no longer waiting in the queue).

  • Release source. When an Allocated row is reached by releasing a backorder against received stock, it records a release_source — the FIFO layer or receipt the stock came from. An invariant enforces that a row with a release source has no purchase_order_line_id: it represents stock that already landed, not stock still on order.
  • It can be pinned to a bin. Setting warehouse_location_id pins the allocation to a specific bin — a hard reservation of those exact units. Bin pinning is currently API-only; there is no in-app control for it yet (SKU-8191).
  • It can move to another line. An Allocated row can be reassigned to a different sales order line as a conserved swap under a pool lock; the source line falls back to a Planned backorder if it still needs the stock.

Transitions from Allocated:

ToTriggerWhat happens
FulfilledThe linked fulfillment shipsTerminal; stamps fulfilled_at.
PlannedUnreserveFrees the on-hand stock back to the pool; the row rejoins the queue with a fresh priority.
CancelledThe demand is cancelledFrees the on-hand pool and queues a re-release into other backorders.

Fulfilled

Fulfilled is terminal. It's reached when the fulfillment linked to the allocation ships; it stamps fulfilled_at and can't transition further. On the backorder queue it shows under the Released (Fulfilled) status view. Return-to-vendor (vendor-credit) restock lines fulfill from Planned or Allocated.

  • Reversible only by voiding. Reverting a fulfillment (voiding the shipment) reverses the allocation out of Fulfilled.
  • Partial fulfillment splits the row. Shipping part of an allocation splits it, keeping the unshipped remainder in its prior status.

Cancelled

Cancelled is terminal. It stamps cancelled_at and can't transition further. Cancelling an allocation runs cleanup:

  • Priorities close up. Later priorities are decremented so the queue has no gap where the cancelled row was.
  • Freed on-hand is re-released. If the cancelled row was Allocated, the freed on-hand stock is queued for re-release into other backorders for the same product and warehouse, so a downstream Planned row can claim it instead of stranding.
  • The backorder flag clears on the linked line once no Planned or Awaiting Receipt rows remain for it.
Cancelling on-hand stock triggers a re-fill

When you cancel an Allocated row, the stock it was holding is released back to the pool and re-offered to other waiting backorders. If that re-fill didn't fire, freshly created Planned rows for the same product could sit stranded even though stock had just been freed. That re-fill is guaranteed for cancellations today.

Stock hold states

A stock hold (also called a reservation in the route and API naming — the hold routes take a {reservation} parameter) fences a quantity of physical stock off from selling — for quality control, a customer hold, seasonal set-aside, and more. See Place & manage stock holds.

Holds have no status column. Their state is derived from two fields — released_at and released_quantity:

StateConditionMeaning
Activereleased_at is nullFully holding its quantity; stock is in the On Hold bucket.
Partially Releasedreleased_at is null and released_quantity > 0Some units released back to sellable, the rest still held.
Releasedreleased_at is setFully released; no stock held.
ExpiredActive and expires_at ≤ nowPast its expiry, but still holding until released (see below).

How release works:

  • Full release stamps released_at, released_by, and release_reason, and rolls the remaining held quantity into released_quantity. The state becomes Released.
  • Partial release reduces quantity by the released amount and accumulates released_quantity, leaving released_at null. The state becomes Partially Released.
  • Releasing or deleting an active hold dispatches a tracked job to release inventory allocations, so the freed stock can immediately resolve waiting backorders.
Expired holds aren't released automatically by time alone

A hold whose expires_at has passed is Expired but still holds its stock — the state is derived, not enforced. The units return to sellable only when releaseExpired() runs (the scheduled command), which stamps release_reason as Auto-released: reservation expired. Until then, expired holds keep their stock in On Hold. The Backorders and stock-hold pages surface expiring-soon holds (within seven days) so you can act before they lapse.

Allocation record fields

These are the fields on an allocation, as exposed by the allocation API resource. The record is unguarded; you never edit it directly — allocations are created and transitioned by the order, transfer, and backorder engines.

FieldWhat it holds
idThe allocation's identifier.
productThe product — id, sku, and name.
warehouseThe warehouse the stock or demand sits at — id and name.
link_id / link_typeThe polymorphic demand link (sales order line, warehouse-transfer line, MO component line, or FBA inbound plan item).
link_type_labelA friendly label for the link type: Sales Order, Warehouse Transfer, Transfer Receipt, Manufacturing Order, or FBA Inbound Plan.
link_routeA deep link to the source record (the sales order, transfer, or manufacturing order), resolved per link type.
link_referenceThe source's reference number, for example #SO-1042 or #MO-000003.
dateThe demand's date — the sales order's order date, the transfer's date, or the MO's scheduled start.
quantityThe allocated quantity.
status / status_labelThe allocation status and its display label.
priorityThe row's rank in the backorder queue. Cleared once Allocated.
supplierThe supplier to reorder from — backfilled from the product's default supplier on Planned / Awaiting Receipt rows.
purchase_order_line_idThe covering PO line, when the row is Awaiting Receipt.
is_tight_coverageWhether the PO link was made manually (in the PO Builder) and is protected from automatic re-shuffling.
release_source_id / release_source_typeThe FIFO layer or receipt an Allocated row was released from. Mutually exclusive with a PO link.
warehouse_location_idThe pinned bin, when the allocation is a hard reservation to a specific location.
fulfilled_atWhen the row reached Fulfilled.
cancelled_atWhen the row reached Cancelled.
created_at / updated_atRecord timestamps.

Allocations are activity-logged: their changes appear in the linked sales order's, transfer's, or product's history feed.

Stock hold record fields

These are the fields on a stock hold, as exposed by the hold API resource.

FieldWhat it holds
idThe hold's identifier.
productThe product — id, sku, and name.
warehouseThe warehouse the held stock sits at — id and name.
quantityThe quantity currently held.
released_quantityThe quantity released back to sellable so far (drives the Partially Released state).
reasonWhy the stock is held. Free text — see the note below.
reason_labelA display label for the reason: a suggested-value label when the reason matches one of the presets, otherwise the raw reason text as typed.
notesFree-text notes about the hold.
expires_atAn optional expiry date; drives the Expired and expiring-soon surfaces.
released_atWhen the hold was fully released (null while Active or Partially Released).
released_byThe user who released the hold.
release_reasonWhy it was released (for example, Auto-released: reservation expired).
created_byThe user who placed the hold.
created_at / updated_atRecord timestamps.
archived_atSet when the hold is archived.
The reason is a combobox, not a fixed list

When you place a hold, Reason is a combobox: pick a suggested value or type your own. The suggested values are Quality Control, Customer Hold, Seasonal, Promotional, Internal Use, Damaged, Pending Inspection, Expired / Near Expiry, and Other. If you type a custom reason, reason_label falls back to that exact text. When the reason is Other, Notes is required. The reason filter on the stock-holds list is built from the distinct reasons actually in use, so custom reasons remain filterable.

Backorder queue columns

The Backorders page (Inventory → Backorders, the allocation pipeline) lists allocations as a work queue, ranked by priority. Each row is one allocation, and the columns come from the backorder API resource. See Work the backorder queue for the tasks.

ColumnWhat it shows
IDThe allocation's identifier.
StatusThe allocation status label.
PriorityThe row's rank in the queue. Lower runs first.
SKUThe product's SKU (links to the product).
Product NameThe product name.
Sales OrderThe source order number (links to the order).
Backordered QtyThe quantity on this row.
Released QtyThe same quantity, shown only when the row is Allocated or Fulfilled (that is, once the backorder has been released). Zero otherwise.
SupplierThe supplier to reorder from.
Covered by POA chip for the covering purchase order, with a lock icon when the link is a manual (tight) coverage. Blank for uncovered rows.
ETAThe covering supply's estimated arrival, as a chip colored by ETA state (see below), with a split-coverage icon when demand is split across sources.
Other WH StockA popover of the same product's available stock in other warehouses (only warehouses with stock above zero).
In TransitA popover of in-transit stock for the product.
Backorder DateWhen the backorder row was created.
Order DateThe source order's date.
Scheduled AtThe supplier's next backorder schedule date.
Created At / Updated AtRecord timestamps.

ETA state drives the color and text of the ETA chip:

ETA stateMeaning
Has ETAA covering PO or inbound shipment has a future date.
Late ETAThe covering date is already in the past.
Missing (No PO)No purchase order covers the row yet.
Missing (No Date)A PO covers the row, but it has no delivery date.

Filters above the queue: a Status tab set (All, Active, Released (All), Released (Fulfilled), Released (Submitted), Released (Unfulfilled)), plus Covered by PO, ETA state (Has ETA / Late ETA / Missing), Other WH Stock, and Supplier — combined with the advanced-filter builder and saved views.

"Other WH Stock" and "In Transit" are included in the export

The Other WH Stock and In Transit columns are populated in both the on-screen popovers and the backorder Export (XLSX/CSV) — each row carries the same product's total available stock in other warehouses and its in-transit total. For the per-warehouse breakdown behind those totals, see the per-warehouse stock view.

Backorder settings

The Settings tab on the Backorders page controls how the queue prioritizes and resolves backorders account-wide. These persist to the sales-order settings group; Save sends only the fields you changed, and Discard reverts unsaved edits.

SettingValuesWhat it controls
Backorder Priority Method (backorder_priority_basis)Sales Order Date (FIFO) (default) / Backorder Creation OrderHow the queue is ordered. FIFO prioritizes older orders first; creation order uses the sequence in which backorders were created.
Preserve Manual PO Links on Priority Reorder (backorder_preserve_tight_coverages)On (default) / OffWhen on, manual (tight) PO links survive a priority reorder — only automatic links are recalculated.
Auto-Resolve Backorders (backorder_auto_release)On (default) / OffWhen on, stock arriving from PO receipts, adjustments, and transfers automatically releases matching backorders. When off, you release them by hand.
Auto-Link POs to Backorders (backorder_auto_cover)On (default) / OffWhen on, PO lines are linked to backorders automatically. When off, only manual links from the PO Builder are created.
These settings back the queue's action dialogs

The same settings are surfaced by the queue's action dialogs — the Reset Priorities dialog options and the Unreserve action's disable auto-release toggle write to these same fields, so a one-off choice in a dialog and the persistent setting stay consistent.

Next steps

Last verified: