Webhooks
When something happens in a workspace, such as an order paid, an invoice sent or a message received, Digize posts the event to every endpoint that asked for it. Each delivery is signed with the endpoint’s own secret, and tried again with backoff when the endpoint doesn’t take it.
Endpoints
Section titled “Endpoints”Endpoints are added through the API with POST /api/v1/webhooks, by a key with settings:write:
curl -X POST https://digize.com/api/v1/webhooks \ -H "x-api-key: $DIGIZE_API_KEY" \ -H "content-type: application/json" \ -d '{"url":"https://example.com/digize","events":["commerce.order.paid","crm.invoice.paid"],"description":"Fulfilment"}'{ "id": "whe_01JD7QX3E5G7J9K1M3P5R7T9V1", "url": "https://example.com/digize", "events": ["commerce.order.paid", "crm.invoice.paid"], "description": "Fulfilment", "source": "api", "createdBy": "Warehouse sync", "createdAt": "2026-10-27T10:00:00.000Z", "disabledAt": null, "failures": 0, "lastDeliveryAt": null, "secret": "whsec_9yLx4mTq2VbN7cR1kP5sW8eH3jD6fG0aZuQiOtYrXlE"}urlis anhttps://address on the public internet. Addresses onlocalhost, private networks and the like are refused.eventslists event names, up to 50, or["*"]for every event, including ones added later.- Subscribing sends records out, so the key also needs read on each event’s module:
commerce:readforcommerce.*events,crm:readforcrm.*, and every module’s read for*. secretsigns every delivery to this endpoint. It’s in this answer only; Digize keeps it sealed.- A workspace can have 50 endpoints, Zapier’s subscriptions included.
GET /api/v1/webhooks lists the endpoints with how their deliveries are going, POST /api/v1/webhooks/{id}/ping sends one a test event, and DELETE /api/v1/webhooks/{id} removes one. To change an endpoint’s events or address, add a new one and remove the old.
A delivery
Section titled “A delivery”Each delivery is a POST of JSON:
POST /digize HTTP/1.1Host: example.comcontent-type: application/jsonuser-agent: Digize-Webhooks/1digize-event: commerce.order.paiddigize-delivery: whd_01JD7QY4F6H8K0M2P4R6T8W0X2digize-signature: t=1793095200,v1=1bc22bd169c5eaf9f3a834600a99bcbe6b0f802c57c8965b17473e0b701214a7
{"id":"evt_01JD7QY3D5F7H9K1M3P5R7T9V1","type":"commerce.order.paid","created_at":"2026-10-27T10:00:00.000Z","workspace_id":"ws_01JB8X4Q2M7KTW9C3N5RVHZ1DE","data":{"id":"ord_01JD7QK2X8V5N3M4P6R9T0W1YZ","number":1042,"status":"paid","total":4850}}The body is compact JSON, and the signature is over it exactly as sent: keep the raw body until it’s checked.
id |
The event’s id: the same for every endpoint it goes to and every retry. Deduplicate on it. |
type |
The event’s name, also in the digize-event header. |
created_at |
When the event happened. |
workspace_id |
The workspace it happened in. |
data |
The record, as each event’s page shows. |
digize-delivery |
This endpoint’s delivery of the event, the same across its retries. |
digize-signature |
The signature to check before trusting any of it. |
Answering
Section titled “Answering”Answer with any 2xx within 5 seconds, before doing slow work: queue the event and process it afterwards.
- Anything else is a failed delivery and is tried again: another status, a timeout, a connection that fails. A redirect is a failure too; it isn’t followed.
410 Goneremoves the endpoint, as Zapier’s REST hooks expect: nothing more is sent to it.
Zapier’s REST hooks
Section titled “Zapier’s REST hooks”Zapier subscribes with POST /api/v1/hooks (target_url, event) and unsubscribes with DELETE /api/v1/hooks/{id}, which need automations:write. They’re endpoints like any other, with source: "zapier", and get the same signed deliveries. See Zapier.