Skip to content

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.