webhooks

A leg is ringing. DELIVERED TWICE on a call that reaches a bridge: once when the business is dialed (previous_state "created") and again when the consumer is dialed after a human was confirmed (previous_state "converse", "human" or "prep_line"). Use `state` to tell the two apart; do not count deliveries.

Sent when a session enters one of: dialing_business, dialing_consumer. Authenticate it with the HMAC signature described on BridgeWebhookEvent before trusting any field. Respond 2xx as soon as you have durably accepted it; any non-2xx, or a response slower than the per-attempt timeout, is treated as a failure and retried.

postWebhookbridge.dialing

Payload

event_idstring required

Stable and unique per transition; the idempotency key you dedupe on. Format vbe_{session_id}_{n}. In the rare case where the underlying event row could not be persisted we still deliver terminal notices, with the suffix replaced by s-{state}, so dedupe on the whole string, and fall back to (session_id, state) if you see that form.

session_idinteger required
type'bridge.dialing' | 'bridge.human_detected' | 'bridge.bridged' | 'bridge.completed' | 'bridge.failed' required

Semantic event type. CLOSED set: these five and no others.

state'created' | 'dialing_business' | 'ivr_nav' | 'amd_verdict' | 'human' | 'voicemail' | 'prep_line' | 'converse' | 'dialing_consumer' | 'bridging' | 'bridged' | 'completed' | 'failed' required

The state just entered. In practice only the delivered states appear here (dialing_business, dialing_consumer, human, bridged, completed, failed); the enum is the full roster so that this field and the one on BridgeStatus deserialize identically. These states are never delivered as a webhook: created, ivr_nav, amd_verdict, voicemail, prep_line, converse, bridging.

previous_state'created' | 'dialing_business' | 'ivr_nav' | 'amd_verdict' | 'human' | 'voicemail' | 'prep_line' | 'converse' | 'dialing_consumer' | 'bridging' | 'bridged' | 'completed' | 'failed' required

The state we came from. Use it to detect out-of-order arrivals.

amd_resultstring nullable required

Answering-machine detection verdict when one had been reached, else null.

failure_reasonstring nullable required

Populated on bridge.failed, null otherwise. An OPEN string, exactly as on BridgeStatus: new reasons are added without a version bump, so do not validate it against a closed list.

customer_refstring nullable required

Your correlation id from metadata.customer_ref at create time, echoed back. Null when you did not send one.

occurred_atstring date-time required

When we recorded the transition. This is our clock after webhook processing, not the carrier's clock at the moment the event happened, and it can trail the real instant by seconds under queue lag. Do not difference two of these to compute a call duration.

Example payload

{
  "event_id": "vbe_4021_88213",
  "session_id": 4021,
  "type": "bridge.bridged",
  "state": "bridged",
  "previous_state": "bridging",
  "amd_result": "human"
}

Response

Accepted. Any 2xx is treated as success.

Changes

Webhooks have no change history: a webhook is keyed by its event name rather than a path and method, so no recorded change can name it.