POST to when something happens: a call ends, an SMS
arrives, a campaign finishes its list. Every message is signed with your key,
so you can check it came from us.
Setting up a webhook
Integrations → Custom tab → Notify on an event tile. The wizard has four steps:- Address - name, URL and signing key. The key is generated for you
(
whsec_…). Copy it straight away: after saving it is only shown masked. New key generates another one; replace it on your side too. - Events - which events to receive.
call.completedis always on. - Agents - all of them or selected ones only. Events tied to an agent
(calls, SMS, campaigns) of other agents do not reach this address.
balance.lowalways arrives. - Test - sends an example event, signed like a real one. You see your server’s response code, the body sent and the signature header.
Webhooks are available from the Start plan.
Message format
Every event has the same envelope:
The wizard’s example has
"test": true in data, so it is easy to filter out.
Events
Full examples and field descriptions: Post-call webhook payload.
Verifying the signature
Compute HMAC-SHA256 over the raw request body (the bytes as received, before parsing the JSON) and compare it with the header in constant time. Re-serialising the JSON can reorder keys or change whitespace, and then the signature will not match.Delivery and retries
- Answer with a
2xxwithin 15 seconds. The response body does not matter. - On a connection error, a timeout, or
408,425,429,5xx, we retry twice more (after 1 and after 5 seconds). Other4xxcodes count as a rejection and are not retried. - Every attempt is listed under Recent deliveries below the integrations catalog, with the response code and the error.
- In rare cases the same event can arrive twice. Use
eventwithdata.workflow_run_id(ordata.sms_id,data.campaign_id) to spot a repeat.
Security
- The address must be public: private-network addresses and
localhostare blocked. - The signing key is stored encrypted and is never returned in full by the API.
- The recording and transcript links in
call.completedwork without signing in. Treat them as personal data.