Webhook Event Schemas
This document specifies the events the Platform sends to an endpoint you register: the envelope every delivery carries, the event catalog with each event's payload, how to verify a delivery's signature, and how deliveries are retried. Register and manage your endpoint in the Seller Center; the Developer Agreement governs webhook use.
Webhooks are outbound notifications from the Platform to your systems. They are authenticated by the delivery signature described below; your API key (Authentication Endpoints) is not used to receive them, and a delivery never carries your key.
Registering an endpoint
- Your endpoint must be a public HTTPS URL that accepts
POSTwith a JSON body and replies200within 10 seconds. - At registration you choose the event types you subscribe to and receive a signing secret, shown once. Store it as you store your API key; a replacement secret can be issued in the Seller Center, and the prior secret stays valid for 24 hours so you can rotate without losing deliveries.
- Do the slow work after replying: acknowledge first, then process from your own queue. A delivery that times out is treated as failed and retried.
The delivery envelope
Every delivery is one JSON object
{
"id": "evt_60rp18",
"type": "order.created",
"created_at": "2026-10-13T19:22:08Z",
"account_id": "acct_7k2m9x",
"data": {
"order_id": "ord_64kx20",
"order_number": "AAP-2026-104821",
"status": "confirmed",
"total": "60.04",
"currency": "USD"
}
}
Headers on every delivery
| Header | Meaning |
|---|---|
Pawz-Event | The event type, matching the body's type |
Pawz-Delivery | A unique identifier for this delivery attempt |
Pawz-Signature | t=<unix timestamp>,v1=<hex signature>: see verification below |
Deliveries for your account carry only your account's data. Event data objects follow the resource shapes in the resource references: an order event's data matches the order fields in Orders Endpoints, a shipment event's the fields in Fulfillment Endpoints, and so on. Fields may be added over time; ignore fields you do not recognize.
Verifying the signature
The signature proves the delivery came from the Platform and was not altered
- Take the
tvalue from thePawz-Signatureheader and the exact raw request body, byte for byte: do not parse and re-encode the JSON first. - Compute the hex-encoded HMAC-SHA256 of the string
<t>.<raw body>using your signing secret. - Compare the result with the header's
v1value using a constant-time comparison. Reject the delivery if they differ. - Reject a delivery whose
tis more than five minutes from your server's current time, to limit replay.
Process each event once: deliveries may repeat (see retries), so record the event id you have handled and skip a later delivery with the same id. This is the receiving side of the discipline in Idempotency Keys.
Retries and ordering
- A delivery that fails (non-
200reply, timeout, connection failure) is retried with increasing delays for up to 48 hours. After that the delivery is marked failed and the event is available for manual redelivery in the Seller Center. - Repeated failures over a day pause the endpoint and notify your technical contact; deliveries resume when the endpoint replies
200again. - Events are delivered in the order they occurred for a given resource, but network retries can interleave deliveries across resources. Always read the resource's current state (for example,
GET /orders/{id}) before acting on an older event, and prefer the resource's present status over the status in a delayed event.
The event catalog
Orders
| Event | When it fires | data fields |
|---|---|---|
order.created | An order is placed with your account and payment confirmed | order_id, order_number, status, total, currency, placed_at |
order.cancelled | An order is cancelled before shipment | order_id, order_number, reason, cancelled_at |
order.updated | An order's status changes for another reason | order_id, order_number, status, previous_status |
Fulfillment
| Event | When it fires | data fields |
|---|---|---|
shipment.created | A shipment is created for an order | shipment_id, order_id, carrier, tracking_number, status |
shipment.in_transit | The carrier reports the shipment moving | shipment_id, order_id, status, occurred_at |
shipment.out_for_delivery | The shipment is out for delivery | shipment_id, order_id, status, occurred_at |
shipment.delivered | Delivery is confirmed | shipment_id, order_id, status, delivered_at |
shipment.exception | The carrier reports a problem | shipment_id, order_id, status, detail |
Returns
| Event | When it fires | data fields |
|---|---|---|
return.requested | A buyer opens a return on your order | return_id, return_number, order_id, reason |
return.approved | A return is approved | return_id, order_id, status |
return.received | The returned goods arrive | return_id, order_id, status |
return.refunded | The refund or credit is issued | return_id, order_id, amount, currency, method |
Payload shapes follow Returns Endpoints.
Payments
| Event | When it fires | data fields |
|---|---|---|
payment.succeeded | A charge for your order succeeds | payment_id, order_id, amount, currency |
payment.failed | A charge fails | payment_id, order_id, amount, currency, failure_reason |
payment.refunded | A refund completes outside the returns flow | payment_id, order_id, amount, currency |
payout.paid | A payout is sent to your bank | payout_id, net, currency, period_start, period_end |
Payload shapes follow Payments Endpoints.
Catalog and inventory
| Event | When it fires | data fields |
|---|---|---|
product.updated | A product's content changes | product_id, seller_sku, updated_at |
price.changed | A variant's current price changes | product_id, variant_id, price, currency, effective_from |
inventory.low | Available stock crosses your low-stock threshold | variant_id, seller_sku, quantity_available |
inventory.out | Available stock reaches zero | variant_id, seller_sku, quantity_available |
Testing
The Seller Center offers a test delivery for each event type, carrying a payload whose identifiers begin test_ and whose type is the real event type. Use test deliveries to verify your signature check and handling before subscribing to live events, and never act on a test_ payload as if it were a real order, shipment, or payment.