Отдельные звонки
POST /v1/calls/phone
Один исходящий звонок: платформа регистрирует звонок, сразу отвечает и набирает номер из устойчивой очереди набора через указанный транк, подключая опубликованного агента, когда абонент ответит.
Нормализация номера. Из
to_number убираются все нецифровые символы ("+1 (555) 123-4567" → "15551234567"). Номер без цифр отклоняется с 400. Если группа задаёт префикс набора, он добавляется к нормализованному номеру; разрешённые направления проверяются по нормализованному номеру до префикса.
Порядок проверок. Потолок очереди набора (429 dial_queue_full) проверяется первым, до всякой валидации. Затем синхронно и до регистрации звонка: транк и грант (404), группа и привязка агента (404/409/403), номер звонящего (400), политика направлений (403), лимиты группы (429), ring_duration (400) и в конце — опубликованная версия агента (409). Отказ на любом из этих шагов не оставляет звонка. Поскольку лимиты проверяются до проверки публикации, 429 не говорит вам, опубликован ли агент.
Заголовок Idempotency-Key здесь рекомендуется (и фактически обязателен после 429): повтор с тем же ключом возвращает уже созданный звонок вместо второго набора. Ключи помнятся сутки и ограничены вашим API-ключом и эндпоинтом. Переигровка возвращает объект звонка в том виде, в котором он был при создании (status: "queued"), а не его текущее состояние — для этого опрашивайте GET /v1/calls/{call_id}.
Успех —
202 Accepted, а не 201. Звонок зарегистрирован и поставлен в очередь набора; сам набор происходит асинхронно после ответа. Сохраните call_id: это ключ сопоставления для опроса и для каждого вебхука.Объект звонка
Приходит вPOST /v1/calls/phone, GET /v1/calls/{call_id} и POST /v1/calls/{call_id}/end.
Жизненный цикл:
queued (набор инициирован, дозвона ещё нет) → ringing → ongoing (абонент ответил) → ended (разговор состоялся, включая сообщения на автоответчик и переводы) либо failed.
Веб-звонки пропускают ringing и failed: они идут queued → ongoing (первая реплика истории) → ended.
Асинхронные поля заполняются после завершения звонка: call_analysis — когда закончится пост-анализ, recording_url — когда финализируется запись. Вебхук call_analyzed сообщает, когда готово и то, и другое, — опрос это запасной путь, а не основной механизм.
Чтение и завершение звонка
GET /v1/calls/{call_id} возвращает полный объект звонка; на неизвестный идентификатор — 404 call_not_found.
POST /v1/calls/{call_id}/end завершает живой звонок — телефонный звонок, ещё стоящий в очереди набора, отменяется до набора — и возвращает объект звонка.
GET /v1/calls/{call_id}/turns отдаёт метрики задержек по тёрнам завершённого телефонного или веб-звонка: массив {"turn", "metrics": {"vad_ms", "asr_ms", "eou_wait_ms", "classifier_ms", "llm_ms", "tts_ms", "turn_ms", …, "estimated"?: true}, "interrupted"?: true, "merged_from"?: number}. Диагностическая поверхность для нагрузочных тестов; 404 на неизвестные идентификаторы и на сессии, не являющиеся звонком.
merged_from появляется у тёрна абонента, чью фразу расколола пауза и которую склеили обратно: это число обрывков, а фазы тёрна взяты у первого из них. Ключ аддитивный: клиент, который его не читает, разбирает ответ обычным образом. Метрики llm_first_sentence_ms в ответе нет.
GET /v1/calls — список звонков
Ответ:
{calls: [...], has_more, next_cursor}. Элементы списка — сводки без транскрипта; полный объект — GET /v1/calls/{call_id}. Идите по страницам, передавая next_cursor как cursor, пока has_more не станет false. В списке только телефонные и веб-звонки; тестовые сессии редактора и чаты в него не попадают.