Skip to main content

Event catalog

Every webhook payload is wrapped:

{
"event": "<event name>",
"store_id": 13,
"occurred_at": "2026-04-30T21:18:21+00:00",
"data": { /* event-specific, documented below */ },
"delivery_id": "9f2c41ab77e05d18"
}

This page documents the data field for each event.

Order events

API v1 order events only follow API traffic

An order status event fires only when the status is changed through the API — PATCH /v1/orders/{id} or POST /v1/orders/{id}/cancel. Confirming or shipping from the DZBuild dashboard, bulk send-to-delivery, and automatic courier tracking updates all fire nothing here.

There are also 7 order statuses but only 5 status events: transitions into pending and into processing emit nothing at all. So an order can move pending → processing → shipped and you will see a single order.shipped.

If you need events that cover every order source and every status change, use the merchant Webhooks addon at /dashboard/webhooks instead — see the comparison in the Webhooks overview.

order.created

Fires only for orders created through POST /v1/orders. Storefront checkouts, landing-page orders and manual dashboard orders do not fire this event — wire fulfilment to it and you will miss the overwhelming majority of a merchant's orders.

{
"data": {
"order_id": 6894,
"order_number": "ORD-13-20260317-AD3C",
"customer_phone": "0555000000",
"total": 1000
}
}

Those four keys are the entire payload. Fetch GET /v1/orders/{id} if you need anything else.

order.confirmed

Fires when status moves to confirmed. Stock is decremented at this moment.

{
"data": {
"order_id": 6894,
"old_status": "pending",
"new_status": "confirmed"
}
}

order.shipped

{ "data": { "order_id": 6894, "old_status": "processing", "new_status": "shipped" } }

old_status can be a state you were never told about — the move into processing in this example fired no event of its own.

order.delivered

{ "data": { "order_id": 6894, "old_status": "shipped", "new_status": "delivered" } }

order.cancelled

Fires when an order moves to cancelled from pending, confirmed or processing — those are the only states cancellation is allowed from. POST /v1/orders/{id}/cancel on a shipped or delivered order returns 400 bad_request and no event fires. If the order was already in a committed-stock state, stock is restored before this event fires.

{ "data": { "order_id": 6894, "old_status": "confirmed", "new_status": "cancelled" } }

order.returned

{ "data": { "order_id": 6894, "old_status": "delivered", "new_status": "returned" } }

Payment events

payment.received

Reserved — not currently emitted. The name is accepted in the events array at registration and appears in allowed_events, but nothing fires it. Payment status changes will not reach your endpoint; read GET /v1/orders/{id} if you need it.

Signup / event tracking

signup.counted

Fires when a /v1/signups call lands and was actually counted (not a duplicate).

{
"data": {
"key_id": "dzpub_live_53f32d45fc356",
"source": "landing-page-1",
"country": "DZ"
}
}

For privacy reasons we do NOT echo back email, phone, or external_user_id in the webhook — your own systems already have those values. The webhook is the "this signup was counted, please mirror it to your CRM" signal.

event.recorded

Reserved — not currently emitted. POST /v1/events records the event and increments usage, but fires no webhook.

Product events

product.stock_low

Reserved — not currently emitted. There is no low-stock push today.

The underlying field is real, though: GET /v1/products/{id} returns low_stock_alert alongside stock_quantity under inventory, so you can poll for the condition yourself.

Internal / test

webhook.test

Fired by POST /v1/webhooks/{id}/test. Lets you check your endpoint is reachable without waiting for a real event.

{ "data": { "ts": 1717112657 } }

It cannot be subscribed to — including webhook.test in the events array at registration returns 400 bad_request "unknown event: webhook.test. Allowed: …". A test is delivered to the webhook you call it on regardless of that webhook's subscription list.

Headers (every event)

Content-Type: application/json
User-Agent: dzbuild-webhook/1
X-DZ-Timestamp: <unix seconds>
X-DZ-Signature: <hex hmac-sha256>
X-DZ-Delivery-Id: <numeric delivery id>

X-DZ-Delivery-Id is a numeric delivery id (e.g. 4127). It is stable across every retry of that delivery, and it is not the same value as the 16-hex delivery_id in the JSON body.

Versioning

We add new events under v1 freely (additive). When we change the shape of an existing event's data, that's a v2-required change and gets a new path prefix. So your code can rely on:

  • event is stable.
  • New top-level fields may appear in data.
  • Existing field types and meanings won't change without a v2.
  • Order of data keys is not guaranteed.