Webhooks

Subscribe to masked-call lifecycle events instead of polling. Signed JSON is POSTed to your endpoint on every state transition.

Webhooks

Subscribe to call lifecycle events instead of polling. We POST signed JSON to your endpoint at each state transition. Failed deliveries retry with exponential backoff, and every payload includes an HMAC SHA-256 signature for verification.

Configure your webhook endpoint URL on the portal.

Events

Event Description
call.initiated Party A is being dialed. Call has not yet connected.
call.ringing Party A's phone is ringing.
call.answered Party A answered. We are now dialing Party B to bridge.
call.bridged Both parties are connected and talking.
call.completed Call ended normally. Includes duration and recording URL.
call.failed Call failed. Includes hangup_cause for diagnostics.
call.no-answer Party A did not answer within the timeout window.
recording.ready Recording is processed and available for download.

Sample payload (call.completed)

{
  "event": "call.completed",
  "call_sid": "d28be7cd-9840-4b23-9627-199f1ef81fc6",
  "data": {
    "caller_number": "917969002802",
    "target_number": "9876543210",
    "masked_number": "917969002802",
    "direction": "click_to_call",
    "status": "completed",
    "started_at": "2026-05-11T08:30:00Z",
    "answered_at": "2026-05-11T08:30:08Z",
    "ended_at": "2026-05-11T08:31:42Z",
    "duration_sec": 94,
    "bill_duration_sec": 120,
    "price": 3.0,
    "recording_url": "recordings/2026/05/11/d28be7cd.wav"
  }
}

Verifying signatures

Each request includes an HMAC SHA-256 signature computed over the raw request body using your webhook signing secret (from the portal). Recompute the HMAC on your side and compare it to the signature header before trusting the payload. Always respond with a 2xx status quickly; do any heavy processing asynchronously so deliveries are not retried unnecessarily.