Prebit Developer Docs

Inventory API

Setting absolute stock levels — and the race this deliberately doesn't solve.

PATCH /platform/v1/products/:id/inventory — scope write_products (inventory is a sub-resource of the product aggregate, not a separate scope — a finer write_inventory split is possible later if a partner needs stock-only access). Requires Idempotency-Key.

const { data } = await client.setInventory(productId, { stock: 12 }, crypto.randomUUID());
// or, for a variant:
await client.setInventory(productId, { stock: 12, variantId: "..." }, crypto.randomUUID());
curl -X PATCH https://admin.prebit.in/api/platform/v1/products/$ID/inventory \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{ "stock": 12 }'

Response: 200 { "data": { "productId": "...", "variantId": null, "stock": 12 } }.

This is an ABSOLUTE set, not a relative adjustment

{ "stock": 12 } means "stock is now 12," not "decrease by 12." If you want to decrement, read the current value first (via list products) and compute the new absolute value yourself.

Known race with concurrent order checkouts

A live order checkout's relative decrement ($inc) and this endpoint's absolute $set can interleave. Mongo serializes the two writes with no data corruption, but whichever lands second silently wins — discarding the other caller's intent. There is currently no compare-and-swap / expectedStock precondition option. If you're syncing inventory from an external system, be aware that a sale happening in the same moment as your sync can be overwritten.

Errors

StatusCause
400Invalid product id, or stock isn't a non-negative integer
404Store not found, or product/variant not found — a variantId that doesn't match any variant on this product gives an honest 404, not a silent no-op
409Idempotency-Key reused with a different body

Full example

prebit-examples/inventory-sync reads a mock stock feed and calls this endpoint per SKU, with an idempotency key derived from productId + variantId + stock (so replaying the same feed doesn't double-apply, but a changed stock value for the same product is correctly treated as a new write).

On this page