SK Inventory · Developers

Same rails as the whole suite.

Bearer keys, prefixed ULIDs, cursor pagination, idempotency on every mutation, signed webhooks. Learn it once for SK Inventory; it holds across all of Softknack.

01

How it fits together

Every stock mutation requires an Idempotency-Key, so offline syncs and retries can never double-count. Movements are append-only; the on-hand quantity is derived from the log.

fig · the shape of itGRN receipt · lot L-218+40sale · order #2048−2customer return+1day-end variance±0 postedon hand 39movements, never edits — every count traces back to its source
02

Your first movement in three steps

Get a test key, make one authenticated call, and listen for the webhook. The same three moves work for every endpoint in the suite.

1

Get a test key

Test and live keys are separate environments. Build against sk_test_ without touching a real customer.

2

Create a movement

One authenticated POST with an idempotency key. Same key + same body always returns the same result.

3

Receive the webhook

A signed movement.created event hits your endpoint — verify the HMAC, act on it, return 200.

Terminal
curl -X POST https://api.softknack.com/inventory/v1/movements \
  -H "Authorization: Bearer sk_live_..." \
  -H "Idempotency-Key: 9f2c-4d1a-...-e7b3" \
  -H "Content-Type: application/json" \
  -d '{
    "item_id": "itm_01J9X...",
    "qty": -2,
    "type": "sale",
    "reason": "order_fulfilled"
  }'
03

Webhooks you can trust

Signed with HMAC-SHA256, delivered at-least-once, retried on a fixed schedule, and replayable from a dead-letter queue. You will never miss an event because a deploy was mid-flight.

EventWhen it fires
movement.recordedReceipt, sale, return or adjustment — idempotent, reason-coded.
grn.completedPurchase receipt posted: quantities, lots, landed cost.
stock.lowReorder threshold crossed.
stock.outOn-hand reached zero.
dayend.closedVariances booked forward as current-dated adjustments.
lot.expiringA batch is approaching expiry.
retry schedule
1s4s16s1m5m30m2hdead-letter
04

Guarantees, not vibes

The platform conventions every SK product obeys — learn them once, rely on them everywhere.

Idempotency, 24h

Every mutation takes an Idempotency-Key. Same key + body returns the original result; a conflicting body gets 409.

Prefixed ULIDs

Sortable, debuggable IDs like mov_01J9X... — you can read the type and the time right off the wire.

Cursor pagination

Stable cursors that never skip or repeat a row when data changes mid-list. No page-offset drift.

Row-level tenancy

Isolation enforced in the database. 404-over-403, so the existence of another tenant's record never leaks.

Signed webhooks

HMAC-SHA256 on every delivery, with the full retry schedule and dead-letter replay above.

Spec drift-checked

The OpenAPI spec is generated from the code's validators and checked in CI — the docs can't lie.

05

Bring your own agent

Sync stock from a POS, a warehouse scanner, or a marketplace over REST — every mutation idempotent, so a flaky network never double-counts. Subscribe to stock.low to drive reordering, or expose inventory to your own agents over MCP so they can answer 'in stock?' truthfully.

fig · MCP, scopedcatalogheadlessAPI · webhook · MCPservedyour agentsbuild on your catalog instead of being held by it
06

Just need a stock check?

Query on-hand quantity and WAC for any item over the API in one call — the same read the chat and voice agents use to answer availability questions live.

The docs go deeper.

Auth, errors, pagination, every endpoint and schema — written once for the platform, shared by every product.

docs.softknack.com/inventory  See pricing →