Call webhooks
Receive an event when a call rings, ends or fails on a phone or WhatsApp number, and when a WhatsApp user answers a call-permission request.
Call events cover every call on your numbers, regular phone (PSTN) and WhatsApp, from ring to hangup. Subscribe with POST /v1/webhooks/settings and the event names below (first event). Call events need inbox access: without it that call returns a 403 with code feature_not_available, so the subscription is refused rather than silently empty. Delivery, retries and signatures are the same for every event (how webhooks behave).
Events
| Event | Description |
|---|---|
call.received | A call was set up: an inbound call (phone or WhatsApp) reaching one of your numbers, or an outbound WhatsApp call placed through the API. |
call.ended | A call (phone or WhatsApp) ended; carries duration, end reason and the cost breakdown. |
call.failed | A call (phone or WhatsApp) failed with a hard error before or during bridging. |
call.permission_request | A WhatsApp user accepted or rejected your call-permission request. |
How it behaves
Which events fire, in what order
Zernio ends every call with exactly one of call.ended or call.failed. call.permission_request sits outside these sequences: it reports a reply to a permission prompt, not a call. Whether a call.received precedes the ending event depends on the direction and channel:
| Call | Sequence |
|---|---|
| Inbound, phone or WhatsApp | call.received at ring time, then call.ended or call.failed |
| Outbound WhatsApp (through the API) | call.received with direction: "outbound" at origination, then call.ended or call.failed |
| Outbound phone (API or browser softphone) | call.ended or call.failed only |
call.received fires at ring time
Zernio sends call.received before anyone answers. A call nobody picks up still emits it, followed by call.ended with endReason: "no_answer".
Unanswered calls end with call.ended
Zernio reports no-answer, busy and rejected calls with call.ended; branch on endReason. call.failed is reserved for hard errors before or during bridging.
Permission requests are independent of any call
Zernio sends call.permission_request when a WhatsApp user responds to a call-permission request. It gates the outbound WhatsApp row above: Meta permits a business-initiated call only after the consumer taps Allow, and the accept can land days before the call.
call.received
A call was set up on one of your numbers: an inbound call, phone (PSTN) or WhatsApp, reaching the number and routed to its configured destination (an AI voice agent, a SIP endpoint or a phone number), or an outbound WhatsApp call placed through the API, in which case direction is "outbound". The payload carries the Zernio call id, the caller and business numbers, the destination snapshot (forwardTo), and contactId and conversationId links into the inbox, so you can message the caller during or after the call with the regular send endpoints.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Webhook payload for the call.received event. Fires for both
inbound (UIC) and outbound (BIC) calls; branch on
call.direction to tell them apart.
Response Body
Example Requests
Webhook payload for the call.received event. Fires for both
inbound (UIC) and outbound (BIC) calls; branch on
call.direction to tell them apart.
/call.receivedcall.ended
A call (phone or WhatsApp) ended. The payload carries durationSeconds, the endReason (hangup, no_answer, rejected, error) and a cost breakdown under call.billing. When recording is enabled it also carries recordingUrl, a signed URL that expires at recordingExpiresAt; for a fresh URL later, call GET /v1/calls/{id}/recording with call.id. A missed-call follow-up is one endReason: "no_answer" check, then a text to the caller over the linked conversationId.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Webhook payload for the call.ended event. Fires on call hangup
with the duration and a zero-markup billing breakdown.
Response Body
Example Requests
Webhook payload for the call.ended event. Fires on call hangup
with the duration and a zero-markup billing breakdown.
/call.endedcall.failed
A call (phone or WhatsApp) failed with a hard error before or during bridging, for example the destination rejected the SIP INVITE. The payload carries the platform error code and message.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Webhook payload for the call.failed event. Fired when a call
setup or in-progress call fails.
Response Body
Example Requests
Webhook payload for the call.failed event. Fired when a call
setup or in-progress call fails.
/call.failedcall.permission_request
A WhatsApp user responded to your call-permission request, which business-initiated calls require. The payload carries the user's number, their response (accept or reject), whether it is permanent, and the expiry when it is not.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Webhook payload for the call.permission_request event. Fires
when a consumer accepts or rejects an interactive
call_permission_request message.
Response Body
Example Requests
Webhook payload for the call.permission_request event. Fires
when a consumer accepts or rejects an interactive
call_permission_request message.
/call.permission_requestRelated
- Webhooks: create an endpoint, retries, signatures.
- Voice history: calls and recordings on demand.
- WhatsApp calling: call permissions and business-initiated calls.
- Phone numbers: provision the numbers these calls land on.
Ads webhooks
Receive an event when an ads account finishes its first sync, when an ad account stops or resumes syncing, when a Meta Lead Gen form gets a lead, and when an ad object changes status.
WhatsApp webhooks
Receive an event when Meta reviews a WhatsApp template or display name, changes a number's quality or messaging limit, restricts or alerts on the account, when a contact's WhatsApp identity changes, and when Meta detects a lead or purchase in a Click-to-WhatsApp conversation.