API

Your operation, over HTTP

A predictable REST API over the same data the dashboard reads. JSON in, JSON out, integers for money, and a version you pin rather than one that changes underneath you.

https://api.stocked.com/v1 · request
curl https://api.stocked.com/v1/products \
  -H "Authorization: Bearer sk_live_..." \
  -H "Stocked-Version: 2026-07-01" \
  -G -d location_id=loc_1 -d limit=25
200 OK · response
{
  "data": [
    {
      "id": "prd_8f21",
      "name": "Flatbread, 12in",
      "sku": "BRD-012",
      "on_hand": 148,
      "available": 132,
      "unit_cost": 42000,
      "price": 95000,
      "currency": "NGN"
    }
  ],
  "has_more": true,
  "next_cursor": "cur_9d02"
}
Current version 2026-07-01 · keys are issued per workspace in Settings → Developers

Keys, not passwords

Secret keys are issued per workspace in Settings → Developers and scoped to the permissions you pick. A key can be rolled without downtime, and the old one stays valid for an hour.

Cursor pagination

List endpoints return up to 100 records with a next_cursor. Pass it back as cursor to walk the set. Offsets aren't supported, so nothing shifts underneath you mid-page.

Money in minor units

Every amount is an integer in the currency's minor unit, alongside a currency field. No floats, no rounding surprises between your system and ours.

Idempotent writes

Send an Idempotency-Key header on any POST and a retry returns the original result instead of creating a second record. Keys are remembered for 24 hours.

Rate limits

1,000 requests a minute per workspace, burstable to 100 a second. Every response carries the remaining budget, and a 429 tells you exactly when to come back.

Dated versions

Pin a version with the Stocked-Version header. Breaking changes only ever ship behind a new date, and old versions are supported for 18 months.

Endpoints

A selection. The full reference lists every field, filter and error code.

Catalogue

Products, variants, categories and the prices attached to them.

  • GET/productsList products with stock figures per location.
  • POST/productsCreate a product, optionally with opening stock.
  • PATCH/products/{id}Update naming, costing or reorder settings.
  • GET/categoriesList categories and their parents.

Stock

Levels, movements, counts and transfers between locations.

  • GET/stockOn-hand, committed and available by product and location.
  • POST/stock/adjustmentsAdjust a level with a reason. Lands in the audit log.
  • GET/stock/movementsEvery movement, filterable by product, location and date.
  • POST/transfersDispatch stock from one location to another.

Sales

Orders, payments, refunds and the customers behind them.

  • GET/ordersList orders with lines, payments and fulfilment state.
  • POST/ordersRecord a sale and draw down stock in one call.
  • POST/orders/{id}/refundsRefund whole lines or partial quantities.
  • GET/customersList customers with balances and purchase history.

Purchasing

Suppliers, purchase orders and what actually arrived.

  • GET/purchase-ordersList orders with outstanding quantities per line.
  • POST/purchase-ordersRaise an order against a supplier.
  • POST/purchase-orders/{id}/receiptsReceive a delivery, in full or in part.
  • GET/suppliersList suppliers with terms and lead times.

Webhooks

Get told when something happens instead of asking every minute. Every delivery is signed, and failures retry with backoff for 24 hours before they're parked for you to replay.

  • stock.lowAn item dropped to its reorder point.
  • stock.movedAny adjustment, count, transfer or sale that moved stock.
  • order.createdA sale was recorded at any channel.
  • order.refundedA refund was issued against a sale.
  • purchase_order.receivedA delivery was received, in full or in part.
  • batch.expiringA lot entered its expiry warning window.
  • register.closedA register was counted and closed, with the variance.