Inventory sync

When your service is registered with inventory_management: true, you own the stock at your location. Two ways to keep it in sync:

Pull — we poll you

Serve GET {callback_url}/fetch_stock returning a SKU→on-hand map. SKUs are case-sensitive and must match the variant SKUs; unknown SKUs are ignored.
We poll it hourly, immediately when you register an inventory_management service, and on demand whenever you call POST /fulfillment_services/{id}/sync_stock (202 Accepted — the poll runs in the background). Each poll is a signed GET so you can confirm it’s us: verify X-Webhook-Signature = sha256=HMAC-SHA256(X-Webhook-Timestamp, your_webhook_secret) and that the timestamp is fresh (within a few minutes). Same your_webhook_secret as your webhooks.

Push — you write to us

You may pass variant_id instead of sku. Levels are scoped to your own location.

Webhooks

Subscribe to the topics you need by passing webhook_topics when you register your fulfillment service — the subscription is created in that one call, pointed at your callback_url (or webhook_url) and signed with the same webhook_secret. Available topics:

Topic webhook payload & headers

Each topic delivery is a POST to your subscription URL with these headers: The body is a JSON envelope — the event data is under data, alongside event and webhook_id:

The service callback

Separately from subscriptions, we POST a lightweight notify to {callback_url}/fulfillment_order_notification so your service knows to pull new work. Unlike topic webhooks it carries only X-Webhook-Signature (no X-Webhook-Event/X-Webhook-Id) and a minimal body:
("CANCELLATION_REQUEST" for cancellations.) On receipt, pull /assigned_fulfillment_orders for the detail.
merchant_id, store_id and fulfillment_order_id are additive tenant hints — added so a supplier receiving orders from more than one merchant can demultiplex inbound pings per tenant or route straight to the FO without a list call. Per-merchant integrations can ignore all three; the body’s original {"kind":"..."} shape is still valid JSON with unknown keys added next to it.If your callback_url contains {store_id}, {merchant_id} or {fulfillment_order_id} tokens, they are substituted per outgoing POST (verbatim otherwise). See Multi-merchant suppliers.

Verify every delivery [#webhook-signing]

Both topic webhooks and the callback carry X-Webhook-Signature: sha256=<hex> = HMAC-SHA256(raw_request_body, your_webhook_secret). Your webhook_secret is returned once, in the response to registering your fulfillment service — store it then. Compute the HMAC over the raw, unparsed body and compare in constant time.

Errors