Call events
Call events fire as a call moves through its lifecycle. Use them to update your CRM, log call metadata, or trigger downstream automation.
Every event body’s shape depends on the webhook version pinned on the owning Voice App or SIP Trunk. Each payload below has a version toggle: pick your version once and every example on this page switches to match. Field names change across versions; the API versioning page has the full rename table.
Lifecycle
Section titled “Lifecycle”Multi-leg operations like dial also emit leg.created →
leg.answered → leg.completed on each participant leg. These per-leg
events are 2026-06-01-only.
call.initiated
Section titled “call.initiated”Fires the moment Teler creates the call, before the callee’s phone rings.
{ "id": "evt_...", "type": "call.initiated", "api_version": "2026-06-01", "occurred_at": "2026-06-01T11:30:45.100Z", "account_id": "acc_...", "voice_app_id": "va_...", "sip_trunk_id": null, "call_id": "cs_...", "leg_id": "cl_...", "data": { "call_id": "cs_...", "from": "+91XXXXXXXXXX", "to": "+91XXXXXXXXXX", "direction": "outbound", "start_time": "2026-06-01T11:30:45.100Z" }, "previous_attributes": null}{ "event": "call.initiated", "account_id": "<uuid>", "call_app_id": "<uuid>", "data": { "call_id": "<fs-uuid>", "from": "+91XXXXXXXXXX", "to": "+91XXXXXXXXXX", "direction": "outbound", "start_time":"2026-04-27T11:30:45Z" }}call.answered
Section titled “call.answered”Fires when the called party picks up. Not delivered if the call fails before answer.
{ "id": "evt_...", "type": "call.answered", "api_version": "2026-06-01", "occurred_at": "2026-06-01T11:30:48.412Z", "account_id": "acc_...", "voice_app_id": "va_...", "sip_trunk_id": null, "call_id": "cs_...", "leg_id": "cl_...", "data": { "call_id": "cs_...", "from": "+91XXXXXXXXXX", "to": "+91XXXXXXXXXX", "direction": "outbound", "start_time": "2026-06-01T11:30:45.100Z", "answered_at": "2026-06-01T11:30:48.412Z" }, "previous_attributes": null}{ "event": "call.answered", "account_id": "<uuid>", "call_app_id": "<uuid>", "data": { "call_id": "<fs-uuid>", "from": "+91XXXXXXXXXX", "to": "+91XXXXXXXXXX", "direction": "outbound", "start_time": "2026-04-27T11:30:45Z", "answer_time": "2026-04-27T11:30:48Z" }}The v1 field is answered_at; legacy uses answer_time.
call.completed
Section titled “call.completed”Fires when an answered call ends normally.
{ "id": "evt_...", "type": "call.completed", "api_version": "2026-06-01", "occurred_at": "2026-06-01T11:32:18.501Z", "account_id": "acc_...", "voice_app_id": "va_...", "sip_trunk_id": null, "call_id": "cs_...", "leg_id": "cl_...", "data": { "call_id": "cs_...", "from": "+91XXXXXXXXXX", "to": "+91XXXXXXXXXX", "direction": "outbound", "start_time": "2026-06-01T11:30:45.100Z", "ended_at": "2026-06-01T11:32:18.501Z", "duration_seconds": 90, "reason": "normal", "ended_by": "callee" }, "previous_attributes": null}{ "event": "call.completed", "account_id": "<uuid>", "call_app_id": "<uuid>", "data": { "call_id": "<fs-uuid>", "from": "+91XXXXXXXXXX", "to": "+91XXXXXXXXXX", "direction": "outbound", "start_time": "2026-04-27T11:30:45Z", "answer_time": "2026-04-27T11:30:48Z", "hangup_time": "2026-04-27T11:32:18Z", "duration": 90, "hangup_source": "callee" }}Legacy → v1 field renames: hangup_time → ended_at, duration → duration_seconds, hangup_source → ended_by. New v1 field: reason.
call.failed
Section titled “call.failed”Fires when a call cannot be completed. Replaces call.completed for
unsuccessful calls.
{ "id": "evt_...", "type": "call.failed", "api_version": "2026-06-01", "occurred_at": "2026-06-01T11:30:55.220Z", "account_id": "acc_...", "voice_app_id": "va_...", "sip_trunk_id": null, "call_id": "cs_...", "leg_id": "cl_...", "data": { "call_id": "cs_...", "from": "+91XXXXXXXXXX", "to": "+91XXXXXXXXXX", "direction": "outbound", "start_time": "2026-06-01T11:30:45.100Z", "ended_at": "2026-06-01T11:30:55.220Z", "duration_seconds": 0, "reason": "flow_error", "ended_by": "system", "failure": { "reason": "invalid_flow", "code": 1007, "description": "Invalid flow." } }, "previous_attributes": null}{ "event": "call.failed", "account_id": "<uuid>", "call_app_id": "<uuid>", "data": { "call_id": "<fs-uuid>", "from": "+91XXXXXXXXXX", "to": "+91XXXXXXXXXX", "direction": "outbound", "duration": 0, "start_time": "2026-04-27T11:30:45Z", "hangup_time": "2026-04-27T11:30:55Z", "failure": { "code": 1007, "reason": "Invalid flow." } }}The failure object is included only when the call fails at the Teler
platform level — for example an invalid flow, insufficient balance,
channel-limit rejection, or an origination error. Its fields (2026-06-01):
| Field | Always present | Description |
|---|---|---|
reason | yes | Machine-readable platform failure slug, e.g. invalid_flow, insufficient_balance, channel_limit_exceeded, originate_failed. |
code | yes | Numeric Teler platform failure code (1000-series). This is not a SIP response code. |
description | yes | Human-readable explanation of the failure. |
details | no | Extra context about the failure, when available. |
On 2025-08-01 the object is { code, reason }, where reason carries the
human-readable description text.
Per-leg events
Section titled “Per-leg events”Multi-leg operations like dial fire these events on each
participant leg. Envelope leg_id identifies the leg.
leg.created:
{ "type": "leg.created", "leg_id": "cl_...", "data": { "role": "dial_target", "direction": "outbound", "from": "+14155550000", "to": "+14155550123", "parent_leg_id": null }}leg.answered:
{ "type": "leg.answered", "leg_id": "cl_...", "data": { "answered_at": "2026-06-01T11:30:48.412Z" }}leg.completed:
{ "type": "leg.completed", "leg_id": "cl_...", "data": { "ended_at": "2026-06-01T11:32:18.501Z", "reason": "normal", "ended_by": null, "duration_seconds": 87 }}reason values: normal, no_answer, busy, canceled,
unreachable, rejected, flow_error, system_failure. A failure
object is included when the leg ends abnormally.
Transfer events
Section titled “Transfer events”A call transfer emits these events as the
target is originated and bridged. Envelope leg_id is the caller’s leg, and
data.transfer_id (op_<ULID>) ties the sequence together.
Every transfer event’s data carries transfer_id, mode, caller_leg_id,
target_leg_id (null until a target leg exists), and initiated_by
("api" when triggered via the control API, "flow" when returned from a
flow document).
call.transfer.initiated:
{ "type": "call.transfer.initiated", "leg_id": "cl_...", "data": { "transfer_id": "op_...", "mode": "cold", "caller_leg_id": "cl_...", "target_leg_id": null, "initiated_by": "api" }}call.transfer.bridged:
{ "type": "call.transfer.bridged", "leg_id": "cl_...", "data": { "transfer_id": "op_...", "mode": "cold", "caller_leg_id": "cl_...", "target_leg_id": "cl_...", "initiated_by": "api", "bridged_at": "2026-06-01T11:30:52.100Z" }}call.transfer.failed:
{ "type": "call.transfer.failed", "leg_id": "cl_...", "data": { "transfer_id": "op_...", "mode": "cold", "caller_leg_id": "cl_...", "target_leg_id": null, "initiated_by": "api", "reason": "no_answer", "on_failure_executed": true }}reason values: no_answer, user_busy, rejected, channel_limit_exceeded,
invalid_target, forbidden, not_found, unsupported_action, sip_error,
network_error, temporary_failure, caller_hung_up, internal_error,
failed, unknown_error. A failed transfer may also carry sip_response_code
and raw_hangup_cause (the underlying SIP/FreeSWITCH cause); on_failure_executed
indicates whether the on_failure nested action ran.
Timestamps
Section titled “Timestamps”All timestamps are ISO-8601 UTC strings (e.g. "2026-06-01T11:30:45.100Z").
Fields may be absent when they don’t apply; treat missing as unset,
not as falsy.