Inventory synchronisation
TechTur POS is the authority for physical stock. Your platform mirrors it.
Reading stock
GET /api/v1/businesses/{id}/stock?variantId=…&locationId=… (inventory:read) returns per location:
| Field | Meaning |
|---|---|
onHand |
physically present |
reserved |
held for unpaid online orders |
available |
onHand − reserved — what you should offer |
incoming |
on open purchase orders |
reorderLevel |
the business's reorder point |
Quantities are decimal strings (weighed goods have fractions).
Staying current
Subscribe to inventory.changed:
{ "type": "inventory.changed", "data": { "locationId": "…", "variantId": "…", "onHand": "7.000", "change": "-2.000", "reason": "SALE" } }
Map variantId back to yours with GET …/mappings?entityType=variant. Reasons: OPENING, SALE, ONLINE_ORDER, REFUND, PURCHASE_RECEIPT, SUPPLIER_RETURN, ADJUSTMENT, COUNT, DAMAGE, TRANSFER_IN, TRANSFER_OUT, RECIPE_CONSUMPTION.
Run a scheduled full read (daily) to repair anything missed.
Avoiding double deductions
When you submit an order to POS, POS deducts the stock (once, idempotently by externalRef). Do not also decrement your own count — wait for inventory.changed or read it back. If your platform must keep its own counter (e.g. for an instant-order cap), treat POS's available as the source and overwrite yours.
Writing stock
Only when your system is genuinely where stock is counted (a warehouse system, for example): POST …/stock/adjustments (inventory:write):
{ "locationId": "…", "type": "ADJUSTMENT", "note": "Cycle count from WMS", "lines": [{ "variantId": "…", "quantity": "-3" }] }
OPENING (positive, needs unitCost), ADJUSTMENT (±), DAMAGE (negative). Send an Idempotency-Key. Each adjustment is a ledger movement and posts its value to the business's books.
Costing
POS keeps weighted-average cost per location. FIFO costing is planned, not implemented.