Skip to main content
Webhooks are the alternative to polling. Subscribe an HTTPS URL on your side to one or more event topics; we’ll POST a signed JSON payload every time something matters. Use them to rebuild a static site, fan out to Slack/Discord, sync orders to your warehouse, or refresh a CDN cache.

Setup in 60 seconds

1

Stand up an endpoint

Any HTTPS URL that responds 2xx within 10 seconds. Keep it cheap; do the heavy work asynchronously after acknowledging.
2

Subscribe

Create the endpoint via API or dashboard. The response includes a signing_secret — store it; it’s shown only once.
3

Verify and act

On every delivery, recompute the HMAC and compare it constant-time. Reject requests with a stale timestamp (we recommend a 5-minute window).

Event topics

A complete reference with payload schemas is on the API reference.

Delivery shape

Verifying the signature

The signature is a hex-encoded HMAC-SHA256 of the raw body (do not parse and re-stringify) using your signing_secret. The header is t=<unix>,v1=<hex>; future signature versions will append additional algorithms (e.g. v2=).
Always verify against the raw request body — if you parse JSON first and re-serialize, key ordering changes will break the HMAC. In Express, that means express.raw() on the route, not express.json(). In Next.js App Router, use await req.text() (not await req.json()).

Retry behavior

Each attempt waits up to 10 seconds for a 2xx. A 4xx answer marks the delivery failed straight away (fix your endpoint, then retry it). A 5xx, timeout or network error is retried, up to 5 attempts in total: Failed deliveries are listed with GET /v1/webhook-deliveries (and in the admin under Settings → For developers → Webhooks). Retry one by hand:
The data payload is the resource as it stood when the event happened.

Best practices

Return 2xx as soon as you’ve persisted the raw payload (or queued a job). Don’t run business logic in the request handler — anything over a few seconds risks a retry that double-processes.
Treat X-Neural-Draft-Delivery as the dedupe key. Index it; reject (and 2xx) duplicates. Retries happen — they’re a feature, not a bug.
Reject deliveries with timestamps more than 5 minutes off. The verifier helpers above do this for you.
Rotate the signing secret with POST /v1/webhook-endpoints/{id}/rotate-secret if you suspect a leak. The new secret is returned once and applies to the next delivery, so deploy it promptly.
Watch the last_delivery_status field on the endpoint resource (also visible in the dashboard’s delivery log). A failed state for more than an hour is your cue to investigate.
A single endpoint subscribed to many topics is fine; the X-Neural-Draft-Event header tells you which one. But splitting concerns by URL (orders, content, bookings) makes failure isolation cleaner.

Local development

Use ngrok or Cloudflare Tunnel to expose localhost, subscribe that URL, and use Send test event in the admin (Settings → For developers → Webhooks) to fire a signed sample.

Cost

Webhook deliveries use no credits.