How is a webhook delivered?
From the event through matching against your endpoints, signing, and sending, to a retry or disabling.
4 minute readWebhooksUpdated: 10/25/2026
On this page
Before you start
- For
- Anyone who builds or runs a receiver for webhooks and wants to know what to expect.
- Prerequisite
- None for reading. To create an endpoint you need the Owner role and a package that includes webhooks (Premium and above).
A webhook is a request that the platform sends to an address of your choice as soon as something happens in your organization. Here is the path from the event to your server’s response, and what happens when it does not respond.
From event to delivery
Every business event that is raised in the context of your organization is matched against your webhook endpoints. It reaches every endpoint that is active and has subscribed to this event type. The match knows three forms and no others: the exact event type, the whole area (composition.*), and * for everything. composition.scene.published therefore reaches an endpoint whose list contains this text, composition.*, or *.
For every matching endpoint, a separate delivery is created with its own ID (whd_…). Its body is the payload of the event as JSON. The platform signs this body with the secret of the endpoint (HMAC-SHA256) and sends it by POST to your address, together with the headers X-Signature, X-Event-Type, and X-Delivery-Id. Your server has ten seconds. If it responds with a 2xx status, the delivery counts as delivered.
If the receiver does not respond
If your server responds with 5xx, 408, or 429, or does not respond at all (network error, timeout), the platform treats this as a temporary disruption and retries: at most five attempts, with waits of 2, 4, 8, and 16 minutes, which a job running every five minutes picks up. After the fifth failure the delivery has failed for good. The exact values are in the retry schedule.
Any other 4xx response (such as 400, 401, or 404) counts as an error on your side that a retry does not fix. The delivery fails for good immediately, without another attempt. After that, it can be triggered again only through the API.
If an endpoint keeps failing
Every failure raises a counter on the endpoint, and every success resets it to zero. More than 20 failures in a row disable the endpoint: it becomes inactive, receives no new deliveries, and the platform records the event notifications.webhook.endpoint.disabled. An hourly job also checks whether an active endpoint is over the threshold. After you fix the cause, turn the endpoint back on in the portal with Activate. This takes effect up to an hour later.
Two kinds of events never reach an endpoint: the events of delivery itself (notifications.*), because otherwise every delivery would trigger the next one, and events without a link to an organization, such as those from platform operations.
What follows
- Respond with 2xx right away and process afterward. The ten-second timeout applies to the whole request. If you process first and respond afterward, you risk unnecessary retries.
- Deduplicate by
X-Delivery-Id. A retry carries the same ID as the first attempt. If you store the ID, you process each delivery exactly once, even if your first response got lost on the way. - Respond with 4xx only if the delivery is truly unusable. A 4xx ends the delivery for good. If your system is only temporarily unavailable, respond with 503 or 429, and the platform will try again.
- Check the delivery log when something is missing. For each delivery it shows the state, the response code, and the number of attempts.