Event catalogue
Every event type, with a payload example.
Set up in the dashboard
No code: add an endpoint in Settings and send a test.
Create an endpoint
The response is
201 with the endpoint and its signing secret (whsec_…). The secret is returned only now and when you rotate it; store it somewhere safe.
What a delivery looks like
Each event is onePOST with a JSON body:
Verify the signature
Always verify before trusting a delivery. The signature is an HMAC-SHA256 of{webhook-id}.{webhook-timestamp}.{raw body}, keyed with the base64-decoded part of your secret after whsec_, then base64-encoded and prefixed v1,.
With the Kallabot SDK
The SDKs verify the signature and timestamp and return a typed event.With the Standard Webhooks library
Standard Webhooks publishes libraries for most languages. They check the signature and the timestamp for you.Without a library
Respond fast, work later
- Answer with any 2xx status within 15 seconds. Anything else, a timeout or a redirect counts as a failure. Redirects are not followed.
- Put the event on a queue and return straight away. Don’t make the call to your CRM before responding.
- The same event can arrive more than once (after a timeout, for example). Store
webhook-idand skip ids you’ve already handled. - Events can arrive out of order. Use
timestamp, or therevisionin call events, to keep the newest state.
Retries
A failed delivery is retried on this schedule, about 27 hours in all:- If you answer
429or503with aRetry-Afterheader, the next attempt waits that long instead (up to an hour). - Answering
410 Goneswitches the endpoint off straight away. Use it when an endpoint is retired for good. - An endpoint that has failed continuously for five days is switched off (
status: auto_disabled), and the workspace owners get an email. - After the last attempt, the delivery is marked
dead. Nothing is lost: events are kept for 30 days.
Replay and recover
Every delivery and every attempt (status code, timing, the first 2 KB of your response) is kept and readable:
After an outage: fix the endpoint, call
enable, then recover from when it started failing.
Test an endpoint
POST /v1/webhooks/{endpoint_id}/test sends one signed event now and returns the delivery with its attempt, so you can see exactly what your server answered. Pass {"event_type": "call.ended"} to get that event’s sample payload; leave it out for a plain webhook.test. Test deliveries have "test": true and are never retried.
Rotate the secret
POST /v1/webhooks/{endpoint_id}/rotate-secret returns a new secret. For grace_hours (default 24, up to 72) both secrets sign every delivery, so the webhook-signature header has two entries. Deploy the new secret within that window and nothing breaks. Send {"grace_hours": 0} to drop the old secret at once if it leaked.
Endpoints created before Standard Webhooks show
secret_format: "legacy". Rotate their secret once so the official libraries can load it.Content and privacy
By default, webhook payloads carry ids, statuses and masked numbers, and no conversation content. Each event lists its content fields in the catalogue, such as the messagetext, a call summary, or from_number and to_number. They’re only sent to endpoints with include_content: true.
Turn content on only for endpoints you control, over a connection you trust. Changes to include_content are recorded in the workspace’s audit log.
Manage endpoints
Reading needs
webhook:read; every change needs webhook:write.