A count (InventoryCount) records the process of physically counting the stock of a location — full, partial, or cyclic — and applies the variance found as inventory adjustments when completed. All endpoints for this resource require the inventory:count permission.
Stock is only touched on completion, and only if variance was recorded
Creating, starting, or cancelling a count does not move stock. The movement happens exclusively on complete, and only for items whose variance was calculated through a prior call to PUT .../items. If you complete a count without having recorded counted quantities, no adjustment is generated.
The variance (countedQuantity − systemQuantity) is calculated server-side for each item. An item without countedQuantity is left with variance: undefined — and therefore does not generate an adjustment when the count is completed.
Tip
You can call this endpoint multiple times as the physical count progresses; each call recalculates the variance for the items included in that request.
For each count item whose variance is different from 0 and different from undefined, the system:
Automatically creates an InventoryAdjustment (reason: 'count_correction', status: 'approved', sourceType: 'count', sourceId = the count's ID).
Writes the stock directly, in the same operation.
'complete' does NOT emit the 'Inventory Updated' event
Just like transfer receiving, complete moves stock through a path that bypasses the standard stock write — so it does not trigger Inventory Updated nor the low-stock check, even though it does internally create InventoryAdjustment records. A consumer that only listens to Inventory Updated will not learn about stock changes produced by a completed count.
No state-transition guard
start, complete, and cancel do not verify the current state before applying — just like with transfers, it's an unconditional findOneAndUpdate. Completing a count twice re-evaluates the variance of its countItems and can generate duplicate adjustments if you don't control the state from your integration.