Skip to content

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.

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.

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
}

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
}

The v1 field is answered_at; legacy uses answer_time.

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
}

Legacy → v1 field renames: hangup_time → ended_at, duration → duration_seconds, hangup_source → ended_by. New v1 field: reason.

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
}

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):

FieldAlways presentDescription
reasonyesMachine-readable platform failure slug, e.g. invalid_flow, insufficient_balance, channel_limit_exceeded, originate_failed.
codeyesNumeric Teler platform failure code (1000-series). This is not a SIP response code.
descriptionyesHuman-readable explanation of the failure.
detailsnoExtra context about the failure, when available.

On 2025-08-01 the object is { code, reason }, where reason carries the human-readable description text.

2026-06-01

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.

2026-06-01

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.

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.