Skip to main content
A webhook sends the result of a call to your server when the call ends. You do not need to poll. There are two events:
Registered webhooks also get call.completed when a web session ends. In that payload, call_sid and to_number are null. Use conversation_id to identify the session. The per-call webhook_url field exists only on phone calls and batches.

Add a webhook

You can add a webhook in two ways.
Register a URL once. It gets every matching event in your workspace until you delete it.
  • If you leave out events, the URL gets both events.
  • If you register the same URL again, you get the existing webhook back. No duplicate is created.
  • A workspace can have up to 20 webhooks.
If a URL is registered and also passed as webhook_url, it gets the event only once.

Payloads

In transcript, role is model for the agent and user for the person. timestamp is a Unix time in seconds. If the agent called any tools, the payload also has a tool_calls list.
The values above are examples. The field names are exact.

Verify the signature

Every webhook has an X-Webhook-Signature header. It is an HMAC-SHA256 of the raw request body, hex-encoded, signed with your workspace’s webhook secret.
1

Get your secret

The response is {"webhook_secret": "..."}. You can fetch it again at any time.
2

Sign the raw body

Compute the HMAC over the exact bytes you received. Do not parse the JSON and convert it back to a string first. That can change the bytes and break the check.
3

Compare in constant time

Use a constant-time compare, such as hmac.compare_digest or crypto.timingSafeEqual. A normal == can leak timing information.

Delivery

Know these rules before you depend on webhooks:
  • One attempt only. If your server is down or returns an error, the webhook is not sent again. Use GET /api/v1/calls/{call_id} to fill any gaps.
  • 10 second timeout. Reply quickly. Do slow work after you respond.
  • Redirects are not followed. Give the final URL.
  • It can arrive unsigned. In rare cases the secret cannot be loaded, and the webhook is sent without a signature. Reject any request with a missing or wrong signature.

Manage webhooks

See the Webhooks API reference for full schemas.