Setting one up
Go to Organisation → Webhooks, add your URL, and tick the events you want. You get a signing secret when you create the endpoint. It’s shown once — copy it then. After that you only see a hint, and you can generate a new one if it’s lost.Events
call.completed
The conversation ended. Carries the summary, transcript and outcomes.
recording.ready
The audio file is ready to download.
call.status_updated
A call changed state while it was running.
call.transferred
A caller was handed to a person.
call.completed, plus recording.ready if you store the
audio.
What every delivery looks like
message differs per event — see the pages above.
Checking the signature
The signature is an HMAC-SHA256 of"{timestamp}.{body}" using your signing
secret.
Reject anything with a timestamp more than five minutes old.
await request.body(). In Express, mount
express.raw({ type: "application/json" }) on the route.
Retries
Anything that isn’t a 2xx, and anything that times out, is retried — quickly at first, then with longer gaps, over about a day and a half. After that the delivery is given up on. Because retries reuse the event id, your handler needs to cope with receiving the same event twice. An endpoint that keeps failing is switched off, so a receiver that’s been down for a long time doesn’t get hammered when it comes back. Turn it on again once you’ve fixed it. Answer quickly — acknowledge with a 2xx and do your work afterwards. A slow handler gets treated as a failure.Testing
Send test event delivers a signedtest.ping to your endpoint and records it
like any other delivery.
Deliveries shows recent attempts with the status code, the response and the
timing — the first place to look when something hasn’t arrived.