Operations
One balanced document per call — the only way on-hand quantity changes.
/inventory/operationsScope: inventory:write. Honors Idempotency-Key. Response 201 is the
posted operation plus its movements.
Balancing rules
| Type | Legs | Rule |
|---|---|---|
receive | all + | inbound from a supplier; unitCost may enter on the legs |
supplier_return | all − | blocked below reserved |
transfer | − at source, + at dest | nets to zero per (key, batch) |
convert | role: in / role: out | quantity need not balance; value does. Outputs get a fresh CVT-{id} batch |
fulfill / pos_sale | all − | sold / dispatched |
customer_return | all + | restock |
adjust | any sign | requires note |
curl -X POST "https://apis.cloud.feeef.org/v1/inventory/operations" \
-H "Authorization: Bearer $FEEEF_CLOUD_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $REQUEST_KEY" \
-d '{
"type": "transfer",
"note": "restock Oran",
"legs": [
{ "namespace": "wh-main", "key": "tshirt/Red/XL", "quantity": -20 },
{ "namespace": "wh-oran", "key": "tshirt/Red/XL", "quantity": 20 }
]
}'A receive into an existing batch at a different unitCost is
422 batch_cost_conflict. An operation that would take on-hand below the
reserved counter is 422 reserved_stock_conflict.
Read and reverse
/inventory/operations/:id/inventory/operations/inventory/operations/:id/reverseOperations are immutable. Reverse posts a new operation whose legs negate
the original, or 422 operation_not_reversible if stock was already
consumed downstream.
Movements
/inventory/movementsExactly one of objectId, holderRef, or operationId, plus optional
from / to and a cursor. balanceAfter is stored so clients never
aggregate.
Generate REQUEST_KEY="$(uuidgen)" once before a write and reuse $REQUEST_KEY with the identical body on retries.