Звонки
Звонки
Звонок завершён
call.completedОтправляется, когда завершается принятый звонок. Несёт финальную запись звонка с итоговой длительностью разговора. Для звонков, на которые так и не ответили, вместо этого приходит call.missed. Если звонок записывался, следом придёт отдельное событие call.recording_ready, когда запись будет обработана.
HTTP-запрос
AISAR отправляет подписанный POST-запрос на ваш webhook_url:
http
POST {webhook_url}
Content-Type: application/json
X-AISAR-Signature: sha256=...
{
"event": "call.completed",
"event_id": "evt_01JXXXXXXXXXXXXXXXXXXXXX",
"timestamp": "2026-06-06T12:02:38.000000Z",
"company_id": 1,
"data": {
"call_id": 123,
"direction": "inbound",
"status": "completed",
"from_number": "12025550187",
"to_number": "12025550187",
"contact_id": 42,
"conversation_id": 100,
"channel_id": 5,
"external_call_id": "wacall_abc123",
"duration_sec": 150,
"started_at": "2026-06-06T12:00:00+00:00",
"answered_at": "2026-06-06T12:00:08+00:00",
"ended_at": "2026-06-06T12:02:38+00:00",
"routing": {
"scheme_id": 7,
"scheme_name": "Основная линия",
"ivr_selections": [
{ "menu_node_id": "n_menu", "digit": "2", "label": "Отдел продаж", "attempt": 2, "at": "2026-06-06T12:00:09+00:00" }
],
"final_step": { "type": "ring_group", "node_id": "n_sales", "result": "offered", "team_ids": [3] },
"answered_by": { "assignee_type": "operator", "user_id": 17 },
"path": [
{ "seq": 1, "node_id": "n_hours", "type": "schedule", "result": "work", "at": "2026-06-06T12:00:00+00:00" },
{ "seq": 2, "node_id": "n_menu", "type": "ivr_menu", "result": "invalid", "attempt": 1, "digit": "9", "at": "2026-06-06T12:00:05+00:00" },
{ "seq": 3, "node_id": "n_menu", "type": "ivr_menu", "result": "digit", "digit": "2", "attempt": 2, "label": "Отдел продаж", "at": "2026-06-06T12:00:09+00:00" },
{ "seq": 4, "node_id": "n_sales", "type": "ring_group", "result": "offered", "attempt": 1, "team_ids": [3], "at": "2026-06-06T12:00:09+00:00" }
],
"truncated": false
}
}
}Заголовок X-AISAR-Signature содержит HMAC-SHA256 подпись тела запроса — используйте её, чтобы убедиться, что запрос пришёл от AISAR.
Пример payload
json
{
"event": "call.completed",
"event_id": "evt_01JXXXXXXXXXXXXXXXXXXXXX",
"timestamp": "2026-06-06T12:02:38.000000Z",
"company_id": 1,
"data": {
"call_id": 123,
"direction": "inbound",
"status": "completed",
"from_number": "12025550187",
"to_number": "12025550187",
"contact_id": 42,
"conversation_id": 100,
"channel_id": 5,
"external_call_id": "wacall_abc123",
"duration_sec": 150,
"started_at": "2026-06-06T12:00:00+00:00",
"answered_at": "2026-06-06T12:00:08+00:00",
"ended_at": "2026-06-06T12:02:38+00:00",
"routing": {
"scheme_id": 7,
"scheme_name": "Основная линия",
"ivr_selections": [
{ "menu_node_id": "n_menu", "digit": "2", "label": "Отдел продаж", "attempt": 2, "at": "2026-06-06T12:00:09+00:00" }
],
"final_step": { "type": "ring_group", "node_id": "n_sales", "result": "offered", "team_ids": [3] },
"answered_by": { "assignee_type": "operator", "user_id": 17 },
"path": [
{ "seq": 1, "node_id": "n_hours", "type": "schedule", "result": "work", "at": "2026-06-06T12:00:00+00:00" },
{ "seq": 2, "node_id": "n_menu", "type": "ivr_menu", "result": "invalid", "attempt": 1, "digit": "9", "at": "2026-06-06T12:00:05+00:00" },
{ "seq": 3, "node_id": "n_menu", "type": "ivr_menu", "result": "digit", "digit": "2", "attempt": 2, "label": "Отдел продаж", "at": "2026-06-06T12:00:09+00:00" },
{ "seq": 4, "node_id": "n_sales", "type": "ring_group", "result": "offered", "attempt": 1, "team_ids": [3], "at": "2026-06-06T12:00:09+00:00" }
],
"truncated": false
}
}
}Поля payload
| Поле | Тип | Описание |
|---|---|---|
call_id | integer | Внутренний ID звонка (одинаковый во всех событиях жизненного цикла этого звонка) |
direction | string | inbound (от контакта) или outbound (инициирован оператором) |
status | string | Статус звонка: completed |
from_number | string | Номер вызывающего. Для входящих — клиент; для исходящих — ваш номер WhatsApp Business |
to_number | string | Номер вызываемого. Для входящих — ваш номер WhatsApp Business; для исходящих — клиент |
contact_id | integer|null | ID контакта |
conversation_id | integer|null | ID диалога |
channel_id | integer | ID канала WhatsApp Business |
external_call_id | string|null | ID звонка на стороне провайдера (WhatsApp/SIP) |
duration_sec | integer | Длительность разговора в секундах (от ответа до завершения) |
started_at | string|null | Метка времени начала вызова в формате ISO 8601 |
answered_at | string | Метка времени соединения в формате ISO 8601 |
ended_at | string | Метка времени завершения звонка в формате ISO 8601 |
routing | object|null | Маршрут звонка по схеме входящих звонков: нажатия в меню, итоговый шаг, кто ответил и полный путь. null, если звонок шёл без схемы |
routing.scheme_id | integer|null | ID схемы, по которой шёл звонок |
routing.scheme_name | string|null | Название схемы на момент звонка |
routing.ivr_selections | array | Принятые нажатия в голосовом меню, по порядку. Неверные нажатия и тишина сюда не попадают, они видны в path. Пустой массив, если меню не было |
routing.ivr_selections[].menu_node_id | string|null | Идентификатор узла меню на момент звонка |
routing.ivr_selections[].digit | string|null | Нажатая цифра |
routing.ivr_selections[].label | string|null | Подпись пункта меню (подпись ребра в схеме), если задана |
routing.ivr_selections[].attempt | integer|null | Номер попытки в меню, с 1 (меню может повторяться) |
routing.ivr_selections[].at | string|null | Время нажатия, ISO 8601 |
routing.final_step | object|null | Последний значимый шаг маршрута: ring_group, responsible_manager, queue, ai_agent, voicemail, transfer или ai_escalation. Шаг hangup попадает сюда, только если до него не было ничего значимого. Формат как у элемента path, без seq и at |
routing.answered_by | object|null | Кто ответил: { assignee_type, user_id }. assignee_type: operator или ai_agent; user_id задан для оператора. null, если на звонок не ответили (всегда для call.missed) |
routing.path | array | Полный путь по схеме, не больше 50 шагов. Шаг: seq (с 1), node_id (идентификатор узла на момент звонка; null у шагов вне графа), type, result, at (ISO 8601) и необязательные digit, attempt, label, team_ids, operator_ids, reason, from_user_id, to_user_id. Пары type и result: schedule: work | off; client_check: known | new; play: played | skipped; ivr_menu: digit | invalid | no_input | skipped; ring_group: offered; responsible_manager: offered | no_target; queue: offered | timeout; ai_agent: offered | failed | escalated | no_answer; voicemail: offered; hangup: hangup (в reason причина); transfer: transferred (from_user_id, to_user_id); ai_escalation: handed_to_operator (to_user_id) |
routing.truncated | boolean | true, если путь упёрся в потолок 50 шагов и остальные шаги не записаны |