The flow in five steps
1
Get your key
PlatformDTC issues you a scoped key (
sq_agt_*) and a webhook secret. Scopes:
read_assigned_fulfillment_orders, write_assigned_fulfillment_orders, write_fulfillments.2
Register your service
POST /fulfillment_services with your callback_url. We auto-create a dedicated location
for you; every order line routed to you becomes an assigned FulfillmentOrder.3
Get notified
When a merchant requests fulfillment, we POST
{callback_url}/fulfillment_order_notification
with {"kind":"FULFILLMENT_REQUEST"} and fire the
fulfillment_orders/fulfillment_request_submitted webhook. You then pull the details.4
Accept & ship
Accept the request, then create a fulfillment with tracking. Partial shipments are supported.
5
Sync stock
Serve
GET {callback_url}/fetch_stock (we poll it) or push levels via /inventory_levels/set.Key concepts
- FulfillmentOrder (FO) — one order is split into one or more FOs; each FO is the slice of line items assigned to your location. You only ever see FOs assigned to you.
status—open·scheduled·in_progress·on_hold·incomplete·closed(fully shipped) ·cancelled.request_status— what the merchant is asking of you:unsubmitted·submitted(please fulfill) ·accepted·rejected·cancellation_requested·cancellation_accepted·cancellation_rejected.- Fulfillment — a shipment you create against an FO. Multiple per FO (partials), each with tracking.
Conventions
- Auth:
X-Agent-Key: sq_agt_*(orAuthorization: Bearer). See Authentication. - Idempotency: send
Idempotency-Key: <uuid>on every POST — duplicates return the original result. - Envelope:
{ "success": true, "data": … }on success;{ "success": false, "message": "…" }on error.
You only ever see and act on FulfillmentOrders assigned to your own service location — scope
isolation is structural, enforced on top of your key’s scopes.
Multi-merchant suppliers
A fulfillment service is scoped to a single merchant by default — one merchant’s orders route to one supplier registration. Some suppliers serve multiple merchants on PlatformDTC from a single registration; this is set up by the PlatformDTC team during onboarding, not something you configure yourself. If that applies to you, every FO you pull carriesmerchant_id and store_id
at the top level (same fields also appear on topic-webhook payloads) so you can tell tenants apart,
and the lightweight callback body is extended with merchant_id, store_id, and
fulfillment_order_id so you can route inbound pings without a pull — all additive, so
per-merchant integrations can ignore them.
Optional URL templating. If your callback_url contains {store_id}, {merchant_id} or
{fulfillment_order_id}, those tokens are substituted per outgoing POST. A callback URL with
no tokens is used verbatim (per-merchant clients are unaffected).
sq_agt_* key + webhook_secret are minted by
the PlatformDTC team; send us your callback_url and whether you’ll be receiving orders from more
than one merchant.