ThunderPhone 2.0 уже доступен.Самостоятельный запуск — от 2 ¢/мин.Читать анонс

Webhooks

Каталог событий

Все типы webhook-событий, которые отправляет ThunderPhone.

Каждое тело вебхука содержит поле type, значение которого соответствует одному из типов событий на этой странице. При подписке на эндпоинт массив events должен содержать нужные типы событий (или быть пустым для подписки на всё — кроме событий на каждом ходе telephony.turn / web.turn, которые доставляются только на эндпоинты, где они указаны явно).

Эти события передаются в двух форматах:

  • Доставки на эндпоинт всегда являются неблокирующими уведомлениями с повторными попытками: ответьте любым кодом 2xx; конверт содержит event_id для устранения дубликатов.
  • Блокирующие обмены выполняются только через устаревший вебхук с одним URL: запрос настройки telephony.incoming / web.incoming (номера в режиме вебхука и ключи виджетов, тайм-аут 10 с) и диспетчеризация инструментов в режиме вебхука. Ваш ответ влияет на текущий звонок.

Примеры полезной нагрузки ниже показывают конверт эндпоинта в порядке передачи (ключи отсортированы по алфавиту: data, event_id, type); устаревшие доставки содержат те же data без event_id.

События звонков

telephony.incoming

Отправляется, когда входящий звонок поступает на один из ваших номеров телефона. Доставки на эндпоинт — это уведомления без ожидания ответа, отправляемые для каждого входящего звонка, независимо от того, настроен ли номер для агента или вебхука. Номера без назначенного агента дополнительно получают блокирующий запрос конфигурации в устаревший вебхук — полную схему запроса и ответа см. в telephony.incoming / web.incoming.

{
  "data": {
    "call_id": 987654321,
    "from_number": "+14155550199",
    "to_number": "+15551234567"
  },
  "event_id": "3f6b2ad0-1c9e-4a57-9f2b-8f6f0f9d2f11",
  "type": "telephony.incoming"
}
ПолеТипОписание
agent_idinteger | nullАгент, обработавший звонок, если он был назначен
agent_namestring | nullАгент, обработавший звонок, если он был назначен

telephony.complete

Отправляется при завершении входящего или исходящего телефонного звонка. Неблокирующее. Включает расшифровку, URL записи при наличии и сводку по тарификации. Схему полезной нагрузки см. в telephony.complete / web.complete.

ПолеТипОписание
agent_idinteger | nullАгент, обработавший звонок, если он был назначен
agent_namestring | nullАгент, обработавший звонок, если он был назначен

telephony.tool

Отправляется после того, как телефонный звонок вызывает инструмент функции. Неблокирующее уведомление аудита — инструмент уже выполнен к моменту доставки этого события; оно охватывает ваши собственные инструменты функций и встроенный инструмент send_sms (но не другие встроенные инструменты, инструменты базы знаний, подключения приложений или MCP-инструменты). Для send_sms и arguments.to, и arguments.body имеют значение [REDACTED]. В расшифровках завершённых звонков они также скрыты; получите содержимое и получателя из SMS-ресурса в области организации, используя message_id из ответа.

{
  "data": {
    "arguments": { "date": "2026-04-21" },
    "call_id": 987654321,
    "from_number": "+14155550199",
    "response": {
      "response": { "available_slots": ["9:00 AM", "2:00 PM"] },
      "status": 200
    },
    "to_number": "+15551234567",
    "tool_name": "search_appointments"
  },
  "event_id": "1f0a7c3e-52d4-4a0e-8f4b-b1a6a1c0d9e2",
  "type": "telephony.tool"
}

response — это результат выполнения: {"status": <http status>, "response": <your endpoint's JSON>} при успехе или {"status": <status>, "error": "<message>"} при ошибке.

ПолеТипОписание
agent_idinteger | nullАгент, обработавший звонок, если он был назначен
agent_namestring | nullАгент, обработавший звонок, если он был назначен

telephony.turn

Отправляется во время активного звонка, по одному разу для каждого речевого хода по мере его появления — для озвученных ответов агента и расшифрованных ходов звонящего. Позволяет отслеживать разговор в реальном времени через обычные вебхуки вместо опроса GET /v1/calls/{call_id}/transcript. Неблокирующее.

{
  "data": {
    "call_id": 987654321,
    "entry_type": "completion",
    "from_number": "+14155550199",
    "position": 7,
    "role": "assistant",
    "start_ms": 15200,
    "text": "How many employees does your company have?",
    "to_number": "+15551234567"
  },
  "event_id": "8d3f5a2c-7b1e-4c9a-b6d0-2e4f6a8c0d1e",
  "type": "telephony.turn"
}
ПолеТипОписание
agent_idinteger | nullАгент, обработавший звонок, если он был назначен
agent_namestring | nullАгент, обработавший звонок, если он был назначен
positionintegerИндекс хода в истории звонка — стабильный идентификатор для сортировки
rolestringassistant (речь агента) или user (речь звонящего)
textstringТекст расшифровки хода, известный на момент отправки
entry_typestringТип базовой записи истории: completion (агент) или user_turn / span (звонящий)
start_ms, end_msintegerСмещения аудио в мс от начала звонка; присутствуют только если время воспроизведения уже было известно на момент отправки

web.incoming

Эквивалент telephony.incoming для веб-канала, отправляемый при запуске сеанса веб-виджета или тестового звонка микрофона в конструкторе. Доставки на эндпоинт выполняются без ожидания ответа для каждого веб-сеанса. Публикуемые ключи в mode="webhook" дополнительно получают блокирующий запрос конфигурации в устаревший вебхук — этот блокирующий запрос имеет другую структуру (origin_domain, publishable_key_prefix; без номеров телефона). См. telephony.incoming / web.incoming.

{
  "data": {
    "call_id": 987654322,
    "from_number": "web",
    "origin_domain": "https://example.com",
    "publishable_key_prefix": "pk_live_a1b2",
    "to_number": "+15551234567"
  },
  "event_id": "9a2b4c6d-8e0f-4a1b-9c2d-3e4f5a6b7c8d",
  "type": "web.incoming"
}

from_number всегда имеет буквальное значение "web". Для сеансов виджета в режиме вебхука to_number пусто (номер агента для сеанса назначается после конфигурации); для тестовых звонков микрофона в конструкторе origin_domain и publishable_key_prefix пусты.

ПолеТипОписание
agent_idinteger | nullАгент, обработавший звонок, если он был назначен
agent_namestring | nullАгент, обработавший звонок, если он был назначен

web.complete

Эквивалент telephony.complete для веб-канала, охватывающий звонки веб-виджета (direction: "web") и тестовые звонки микрофона в конструкторе (direction: "test"). Неблокирующее. Та же структура полезной нагрузки, что и у telephony.complete, плюс origin_domain, при этом from_number имеет значение "web".

ПолеТипОписание
agent_idinteger | nullАгент, обработавший звонок, если он был назначен
agent_namestring | nullАгент, обработавший звонок, если он был назначен

web.tool

Эквивалент telephony.tool для веб-канала. data содержит origin_domain вместо from_number / to_number.

ПолеТипОписание
agent_idinteger | nullАгент, обработавший звонок, если он был назначен
agent_namestring | nullАгент, обработавший звонок, если он был назначен

web.turn

Эквивалент telephony.turn для веб-канала, охватывающий звонки веб-виджета и тестовые звонки микрофона в конструкторе. Та же структура полезной нагрузки, но с origin_domain вместо from_number / to_number. Как и telephony.turn, требует явной подписки — событие никогда не доставляется через пустой массив events.

ПолеТипОписание
agent_idinteger | nullАгент, обработавший звонок, если он был назначен
agent_namestring | nullАгент, обработавший звонок, если он был назначен

События SMS

События SMS описывают сообщения, отправленные через подключённую учётную запись Twilio или Telnyx организации. Текст сообщения опускается, а to скрывается. Получите сообщение в рамках организации через GET /v1/sms/{message_id}, если нужны его содержимое или получатель.

sms.sent

Отправляется, когда оператор клиента принимает запрос на исходящее SMS. Это не подтверждение доставки на устройство.

{
  "data": {
    "accepted_at": "2026-09-19T15:42:10.113Z",
    "agent_id": 12,
    "call_id": 987654321,
    "created_at": "2026-09-19T15:42:09.901Z",
    "direction": "outbound",
    "error_code": null,
    "error_message": null,
    "from_number": "+15551234567",
    "id": "313a3117-827b-46e9-a01a-ac1493838724",
    "provider": "twilio",
    "provider_id": "SM0123456789abcdef0123456789abcdef",
    "segment_count": 1,
    "source": "agent_tool",
    "status": "accepted",
    "to": "[REDACTED]"
  },
  "event_id": "0ae347b4-1716-45bb-9a0e-b52373586e37",
  "type": "sms.sent"
}

sms.failed

Отправляется после постоянного отклонения оператором, после исчерпания временных повторных попыток или когда результат окончательно неизвестен. error_code — это стабильный код ThunderPhone, а error_message указывает действие клиента, если оно доступно. status: "unknown" означает, что оператор мог принять SMS; сверяйте его в журнале оператора, поскольку ThunderPhone не отправит его повторно автоматически.

sms.received

Зарезервировано для поддержки входящих SMS. В текущем релизе события sms.received не отправляются. Настройка вебхуков входящих сообщений от операторов и проверка подписей будут выпущены отдельно.


Голосовые события

Создание пользовательского голоса выполняется асинхронно. Эти неблокирующие события позволяют реагировать на конечный результат вместо опроса эндпоинта сведений о клоне.

voice.ready и voice.failed доставляются только на конечную точку всей организации с events: []. Их нельзя выбрать как явные фильтры событий.

voice.ready

Отправляется, когда пользовательский голос завершает обработку и может быть назначен агенту.

{
  "data": {
    "voice": {
      "created_at": "2026-07-30T14:12:08.317Z",
      "display_name": "Support voice",
      "failure_reason": "",
      "gender": "female",
      "id": "cv_2f6f90b0e9a34ee8b39be7d1",
      "language": "en",
      "name": "custom:cv_2f6f90b0e9a34ee8b39be7d1",
      "status": "ready",
      "updated_at": "2026-07-30T14:13:31.605Z"
    }
  },
  "event_id": "2d5f0a61-e9b5-4a3c-b684-29d7d9e4b214",
  "type": "voice.ready"
}

voice.failed

Отправляется, когда обработка пользовательского голоса завершается постоянной ошибкой.

{
  "data": {
    "reason": "audio sample could not be processed",
    "voice": {
      "created_at": "2026-07-30T14:12:08.317Z",
      "display_name": "Support voice",
      "failure_reason": "audio sample could not be processed",
      "gender": "female",
      "id": "cv_2f6f90b0e9a34ee8b39be7d1",
      "language": "en",
      "name": "custom:cv_2f6f90b0e9a34ee8b39be7d1",
      "status": "failed",
      "updated_at": "2026-07-30T14:13:31.605Z"
    }
  },
  "event_id": "3493e985-1a75-4f77-a10a-e74af440cd31",
  "type": "voice.failed"
}
ПолеТипОписание
voice.idstringПубличный идентификатор пользовательского голоса
voice.namestringЗначение голоса агента в формате custom:<public_id>
voice.display_namestringНазвание голоса, отображаемое для организации
voice.languagestringКод единственного языка клона
voice.genderstringmale, female или пустая строка
voice.statusstringready для voice.ready; failed для voice.failed
voice.failure_reasonstringПусто при успехе; подробности ошибки обработки при сбое
voice.created_at, voice.updated_attimestampМетки времени ISO 8601
reasonstringПодробности ошибки; присутствует только в voice.failed

События качества

call.graded

Отправляется при завершении запуска оценки ИИ для звонка. Неблокирующее.

{
  "data": {
    "call_id": 987654321,
    "grade": {
      "call_outcome": "success",
      "created_at": "2026-04-20T18:25:11.002Z",
      "detected_issues": [],
      "graded_at": "2026-04-20T18:25:11.002Z",
      "grader_model": "heuristic-v1",
      "id": 5512,
      "score": 92,
      "status": "completed",
      "summary": "Caller asked about their policy and got a full answer…"
    }
  },
  "event_id": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
  "type": "call.graded"
}
ПолеТипОписание
agent_idinteger | nullАгент, обработавший звонок, если он был назначен
agent_namestring | nullАгент, обработавший звонок, если он был назначен
grade.idintegerИдентификатор оценки
grade.scoreinteger | null0–100
grade.call_outcomestringsuccess, failure, unknown или no_conversation
grade.summarystringСводка в один абзац
grade.detected_issuesarrayСтроки с проблемами, найденными оценщиком
grade.statusstringВсегда completed — отправляются только завершённые запуски
grade.grader_modelstringОценщик, создавший результат (например, heuristic-v1)
grade.graded_at, grade.created_attimestamp

call.data_extracted

Отправляется при успешном завершении извлечения структурированных данных, включая позднюю повторную попытку после telephony.complete / web.complete или повторный ручной запуск через POST /v1/calls/{call_id}/extract. Неблокирующее.

В блокирующем режиме извлечения событие завершения обычно ожидает не более 75-секундного лимита на извлечение. Если процесс обработки извлечения потерян, финализирующая обработка в продакшене (каждые пять минут) отправляет событие завершения, у которого истёк blocking_deadline_at, прежде чем начать ещё одну попытку извлечения. Последующий успешный результат доставляется отдельно в виде этого события.

{
  "data": {
    "call_id": 987654321,
    "agent_id": 12,
    "agent_name": "Acme intake",
    "extracted_data": {
      "status": "completed",
      "fields": {
        "customer_name": "Alex Morgan",
        "appointment_date": "2026-04-23"
      },
      "evidence": {
        "customer_name": {
          "quote": "My name is Alex Morgan",
          "speaker_role": "caller",
          "turn_index": 4
        },
        "appointment_date": {
          "quote": "April 23 works for me",
          "speaker_role": "caller",
          "turn_index": 7
        }
      },
      "verification": "verified",
      "field_reasons": {},
      "schema_version": "92850758e231a3c95a..."
    },
    "extracted_at": "2026-04-20T18:25:11.002Z",
    "model": "gemini-2.5-flash"
  },
  "event_id": "4d79ef1d-c2b1-4ed6-85b8-8326bd2895ef",
  "type": "call.data_extracted"
}
ПолеТипОписание
agent_idinteger | nullАгент, обработавший звонок, если он был назначен
agent_namestring | nullАгент, обработавший звонок, если он был назначен
extracted_data.statusstringДля этого события всегда completed
extracted_data.fieldsobjectЗначения с ключами настроенных полей извлечения; недоступные значения имеют null
extracted_data.evidenceobjectДоказательства с ключами полей извлечения. Значение, не равное null, содержит точную структурно проверенную цитату (не более 1 000 символов), speaker_role (caller или agent) и turn_index; более длинные цитаты, возвращённые моделью, отклоняются, а не обрезаются, а доказательство имеет null, когда его поле имеет null
extracted_data.verificationstringverified только если независимая проверка доказательств вернула ровно один действительный вердикт для каждого поля-кандидата. unavailable означает, что проверка не удалась, превысила время ожидания, не получила достаточного лимита или вернула некорректный либо неполный результат. Полностью недоступная проверка сохраняет структурно обоснованные значения для проверки клиентом. Для частичного результата применяются действительные вердикты, а каждое поле-кандидат без ровно одного действительного вердикта получает null
extracted_data.field_reasonsobjectПричины с ключами полей, получивших null из-за структурного обоснования или независимого проверяющего
extracted_data.schema_versionstringХеш точной схемы полей, использованной для этого извлечения
extracted_attimestampВремя завершения в формате ISO 8601
modelstringМодель, использованная для извлечения

campaign.completed

Отправляется один раз, когда кампания переходит из running в completed: когда заканчивается её расписание или все контакты достигают конечных состояний. Повторные попытки обработчика не отправляют ещё одно событие. Это событие жизненного цикла на уровне организации доставляется только на конечные точки с областью действия организации, а не на конечные точки с областью действия агента. Неблокирующее.

{
  "data": {
    "campaign_id": "3f6b2c9e-2a0d-4c63-b6d6-a708dc98f403",
    "name": "May win-back",
    "agent_id": 12,
    "status": "completed",
    "started_at": "2026-04-20T17:00:00Z",
    "completed_at": "2026-04-20T18:25:11Z",
    "counts": {
      "contacts_total": 150,
      "completed": 121,
      "failed": 11,
      "no_answer": 18,
      "remaining": 0
    }
  },
  "event_id": "8d8f52ce-6b46-423f-9dde-cea0b91ec135",
  "type": "campaign.completed"
}

Четыре счётчика результатов не пересекаются и в сумме дают contacts_total: completed содержит успешные контакты; no_answer содержит завершённые неудачные или исчерпанные контакты, чьим последним результатом был отсутствие ответа; failed содержит все остальные завершённые неудачные или исчерпанные контакты; а remaining содержит ожидающие, запланированные или звонящие в данный момент контакты. Контакт, ожидающий повторной попытки, относится к remaining, даже если последняя попытка не получила ответа. Выполняющиеся звонки сверяются перед однократным снимком завершения. started_at — это настроенное время начала кампании или время создания кампании, если время начала не было настроено.

issue.reported

Отправляется при создании отчёта о проблеме — либо пользователем в панели управления (source: "user"), либо автоматически при оценке звонка (source: "system"). Неблокирующее.

{
  "data": {
    "call_id": 987654321,
    "issue_report": {
      "created_at": "2026-04-20T18:25:11.002Z",
      "description": "Five-second silence before responding to the main question.",
      "id": 4321,
      "severity": "warning",
      "source": "system",
      "status": "open",
      "title": "Agent paused too long"
    }
  },
  "event_id": "5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b",
  "type": "issue.reported"
}
ПолеТипОписание
agent_idinteger | nullАгент, обработавший звонок, если он был назначен
agent_namestring | nullАгент, обработавший звонок, если он был назначен
issue_report.severitystringcritical, warning или info
issue_report.statusstringopen или resolved
issue_report.sourcestringuser (отправлен из панели управления) или system (создан при оценке)

issue.escalated

Отправляется, когда шаблон проблемы передаётся в ThunderPhone для проверки сотрудниками: после Отправить в ThunderPhone или когда функция «Исправить с помощью ИИ» не может подтвердить исправление на стороне клиента и автоматически перенаправляет проблему. Это событие получают только конечные точки уровня организации.

{
  "data": {
    "automatic": false,
    "cluster_id": "7ac2844c-2df0-4fa8-a560-7378da649e19",
    "escalation_id": "ec99f52b-c8c0-41dd-a4f2-dd8a07b10894",
    "status": "open"
  },
  "event_id": "d8f8f420-7a42-45ba-bcf1-b747f9bbecda",
  "type": "issue.escalated"
}
ПолеТипОписание
automaticbooleantrue для автоматической эскалации; false для ручной эскалации
cluster_idUUIDЭскалированный шаблон проблемы
escalation_idUUIDЗапись об эскалации
statusstringopen в момент отправки события

Это уведомление, а не набор доказательств. Используйте cluster_id, чтобы сопоставить его с шаблоном проблемы. См. Отправить в ThunderPhone.


События тестовых звонков

test-call.completed

Отправляется, когда запуск тестового звонка достигает конечного статуса — completed или failed, включая запуски, которые завершились ошибкой при старте и не создали звонок. Не блокирует выполнение. Полезно для интеграции пакетных запусков CI с системами чатов и уведомлений.

{
  "data": {
    "test_call_run": {
      "call_id": 987654321,
      "completed_at": "2026-04-20T18:25:04.822Z",
      "error_message": "",
      "id": 7110,
      "status": "completed",
      "target_id": 12,
      "target_type": "agent"
    }
  },
  "event_id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
  "type": "test-call.completed"
}
ПолеТипОписание
agent_idinteger | nullАгент, обработавший звонок, если он был назначен
agent_namestring | nullАгент, обработавший звонок, если он был назначен
test_call_run.target_typestringagent или phone_number
test_call_run.target_idintegerИдентификатор агента или номера телефона, на который был нацелен запуск, соответствует target_type
test_call_run.statusstringcompleted или failed
test_call_run.call_idinteger | nullnull, если запуск завершился ошибкой до совершения звонка
test_call_run.error_messagestringПусто при успешном выполнении

События предупреждений

alert.triggered

Отправляется, когда правило предупреждения с включённым каналом Доставлять в вебхуки разработчика превышает свой порог. Не блокирует выполнение. Правило срабатывает один раз, а затем соблюдает период ожидания, поэтому продолжительное нарушение создаёт одно событие на каждое окно периода ожидания.

{
  "data": {
    "comparator": "lt",
    "event_id": "b8e6a1d4-2c3f-4a5b-9c8d-7e6f5a4b3c2d",
    "fired_at": "2026-04-20T18:00:00+00:00",
    "metric": "success_rate",
    "metric_value": 71.4,
    "rule_id": "d2c3b4a5-6f7e-4d8c-9b0a-1c2d3e4f5a6b",
    "rule_name": "Success rate below 80%",
    "threshold": 80.0,
    "window_hours": 24
  },
  "event_id": "4d5e6f7a-8b9c-4d0e-9f1a-2b3c4d5e6f7a",
  "type": "alert.triggered"
}
ПолеТипОписание
event_id (в data)UUIDИдентификатор срабатывания предупреждения — отличается от event_id доставки в оболочке
rule_id, rule_nameUUID, stringСработавшее правило
metricstringsuccess_rate, failure_rate, avg_score, call_volume или suite_regression
comparatorstringlt, lte, gt или gte
metric_valuenumberЗначение метрики за окно на момент срабатывания правила
thresholdnumberНастроенный порог
window_hoursintegerПредшествующее окно оценки
fired_attimestamp

См. руководство по предупреждениям, чтобы создавать правила, настраивать метрики, периоды ожидания и каналы по email / Slack.


Связанные материалы