Home
Back to docs

Webhooks

Webhooks send this system's events to an address of yours; each is signed, queued and tried three times in about 6 minutes, and there is no test button, edit or replay.

Webhooks send this system's events to an address of yours in another system, as they happen.

Which events

An endpoint receives the events you choose, or every event if you choose none. You pick from the list of platform events or type a custom event name. Names must match exactly (a literal * also means all); there are no partial wildcards such as crm.*, and a name that never fires is accepted without complaint. A few internal events are never sent.

Delivery is queued, not immediate

An event is queued and a background worker picks it up, checking about every 30 seconds. So a delay of up to half a minute is normal, and a slow destination never slows the system down. Delivery is at least once: the same event can arrive twice, so use the delivery id to ignore a repeat.

What counts as success, and the three attempts

Your address must answer within 10 seconds with a status in the 200s. Redirects are followed (up to 4), and each hop is checked again. The response body is ignored.

There are three attempts in total: the first at once, a second about 1 minute later and a third about 5 minutes after that. Then the delivery is marked failed, so the whole story takes about 6 minutes (plus up to half a minute of waiting for the worker each time). A failed delivery is never retried automatically and there is no replay button, and an endpoint that keeps failing is never switched off for you.

Every request is signed

Each request carries:

  • X-Webhook-Signature: sha256=<hex>: an HMAC-SHA256 of the raw request body, using the endpoint's secret.
  • X-Webhook-Event: the event name.
  • X-Webhook-Delivery: a delivery id that stays the same across retries.

The body is JSON: {"event": "module:event.name", "data": {…}, "ts": "<time sent>"}. The ts is part of the body, so it changes on each attempt. To verify, compute the HMAC of the exact bytes you received with your copy of the secret and compare it with the header. Without that check, anyone who learns your address can send you forged events. Sensitive fields (passwords, tokens, secrets, login links) are replaced by [redacted] before sending.

The destination address is restricted

Only http and https addresses are allowed, and the address must be genuinely external: IP addresses, localhost and any name that points to a private or internal network are refused. This is checked when a delivery is attempted, not when you save, so such an address saves fine and never delivers, and no log line is written for it. If an endpoint receives nothing, check the address first.

Events go to every matching endpoint

Matching is by event name only; every matching endpoint on this install receives the event.

The delivery log

Each endpoint has a log of its attempts: event, attempt number, the HTTP status (or "err" when there was no response) and time. The error text is stored but not shown, and nothing is ever pruned.

Permissions and plan

You need the Webhooks read or manage permission; the Admin role has both and the Editor has neither. Creating and deleting endpoints are plan features. On a plan without the feature the queue stalls silently.

How do I…