Перейти к содержанию

API и интеграции

Страница для разработчиков и администраторов, которые подключают к платформе другую систему: CRM, телефонию, хранилище записей. Она объясняет, чем ключ отличается от входа человека, какие методы доступны интеграции, как отправить звонок и получить результат, как проверить подпись колбэка.

Адрес API в примерах записан как https://<адрес-API>: это домен сервиса tgt-api, не домен панели. Ключ записан как <ключ>.

Ключи и вход человека

Ключ API Вход человека
Кто пользуется интеграция сотрудник в панели
Как передаётся заголовок X-API-Key: <ключ> или Authorization: Bearer <ключ> cookie tgt_session после POST /v1/auth/login
Кто создаёт владелец: «Настройки → Система → API-ключи → Создать ключ» владелец или руководитель создаёт пользователя
Что видит данные всех отделов то, что разрешено роли и правам
Журнал чтение ключом в журнал не пишется чтение пишется

Ключ начинается с tgt_ и показывается один раз при создании: скопируйте его сразу, повторно увидеть нельзя. В базе хранится только хеш. Название ключа должно говорить, чья это интеграция. Если нужно перестать доверять ключу, нажмите «Отозвать» в списке ключей: он перестаёт работать сразу, и это нельзя отменить. В списке видно, когда ключ использовали в последний раз.

Что ключ может, а что нет:

  • может создавать, повторять, отменять и удалять записи, читать записи, расшифровки, звук, очереди, статистику, отчёты, состояние забора и состояние подключения к Битрикс24;
  • не может создавать людей и ключи, менять права, отделы, настройки забора и автоматического режима, управлять очередями, читать журнал, запускать загрузки из Битрикс24.

Такой вызов получает 403 Your role does not allow this.

Внимание

Ключ видит данные всех отделов и скачивает звук. Дайте каждой интеграции отдельный ключ, храните его как пароль и отзывайте при смене подрядчика.

Документация Swagger

Описание всех методов открыто без входа: https://<адрес-API>/docs (интерфейс) и https://<адрес-API>/docs-json (OpenAPI в JSON). У каждого метода указаны уровень доступа (x-access: public, self, owner, ownerOrKey, ownerOrHead или scoped), права, коды ответов и пример схемы. Чтобы попробовать метод, нажмите «Authorize» и введите ключ.

Страница описывает только устройство методов и не показывает данных.

Какие методы нужны интеграции

Группа Метод Что делает Ответ
Запись POST /v1/recordings загрузить файл (multipart, часть file) и поля звонка 201
POST /v1/recordings/from-url скачать запись по ссылке url 201
POST /v1/recordings/from-storage поставить файл, который уже лежит в хранилище, по storageKey 201
Результат GET /v1/recordings/{id} состояние записи, прогресс, расшифровка 200
GET /v1/recordings/{id}/transcript?format=json\|txt\|srt\|vtt скачать расшифровку (по умолчанию json) 200, 409 пока не готова
GET /v1/recordings/{id}/audio звук, поддерживает Range 200, 206
GET /v1/recordings/{id}/deals сделки Битрикс24, связанные со звонком 200
GET /v1/recordings, /catalog, /facets список, каталог по годам и месяцам и счётчики 200
Тексты пачкой GET /v1/transcripts страницы расшифровок, order=asc держит порядок стабильным 200
GET /v1/transcripts/export?format=zip\|csv\|jsonl один файл с расшифровками 200
Управление POST /v1/recordings/{id}/retry, /cancel повторить или отменить запись 200
POST /v1/recordings/retry-failed повторить все записи с ошибкой 200
DELETE /v1/recordings/{id} удалить запись и расшифровку 204
Очередь GET /v1/queue, /v1/queues, /v1/queues/{name}/jobs что ждёт и что в работе 200
Состояние GET /v1/stats/overview, /v1/system, /v1/ingestion нагрузка по дням, версии и модель, состояние забора 200
Отчёты GET /v1/analytics/..., GET /v1/recordings/{id}/analysis продажи, качество, отказы, недельный отчёт, проверка звонка 200
Здоровье GET /healthz, GET /readyz живость и готовность, без ключа 200

Остальные методы закрыты для ключей: они нужны панели. Полный перечень и уровни доступа читайте в Swagger.

Поля звонка при создании записи

Все поля необязательны, кроме файла, ссылки или ключа хранилища. Неизвестное поле отклоняется ответом 400.

Поле Что значит
externalCallId идентификатор звонка в вашей системе, уникальный. Повтор получает 409, поэтому повторная отправка не создаст дубль
phoneNumber номер клиента
managerName имя менеджера
direction INBOUND или OUTBOUND
callStartedAt время начала звонка в формате ISO 8601, лучше с часовым поясом
priority от 0 до 10, чем больше, тем раньше в очереди (по умолчанию 0)
decoder greedy или beam_search; по умолчанию как у сервиса распознавания
callbackUrl адрес http или https, на который придёт колбэк по готовности

Статусы записи: QUEUED, PROCESSING, DONE, FAILED, CANCELLED. У записи с ошибкой, которую повтор не исправит, поле errorCode равно AUDIO_MISSING, UNSUPPORTED_AUDIO или AUDIO_TOO_LONG.

Звонки, которые платформа загружает из Битрикс24 сама, получают externalCallId равным идентификатору звонка в портале. Если ваша система отправляет те же звонки, используйте тот же идентификатор: дубль будет отклонён.

Пример: отправить звонок и получить результат

Отправьте файл вместе с тем, что знаете о звонке:

curl -X POST "https://<адрес-API>/v1/recordings" \
  -H "X-API-Key: <ключ>" \
  -F "file=@call.mp3" \
  -F "externalCallId=<идентификатор-звонка>" \
  -F "phoneNumber=<номер-клиента>" \
  -F "managerName=<имя-менеджера>" \
  -F "direction=INBOUND" \
  -F "priority=3" \
  -F "callbackUrl=https://<ваш-адрес>/hooks/transcripts"

Ответ содержит id и "status": "QUEUED". Дальше есть два способа получить результат.

  1. Подождать колбэк на callbackUrl (см. ниже).
  2. Опрашивать GET /v1/recordings/{id}, пока status не станет DONE или FAILED. Для запроса нужен тот же заголовок ключа.

Когда запись готова, скачайте текст:

curl -H "X-API-Key: <ключ>" \
  "https://<адрес-API>/v1/recordings/<id>/transcript?format=txt"

Забрать все расшифровки за период, страницами и одним файлом:

curl -G "https://<адрес-API>/v1/transcripts" \
  -H "X-API-Key: <ключ>" \
  --data-urlencode "dateFrom=2026-09-01T00:00:00+03:00" \
  --data-urlencode "dateTo=2026-09-30T23:59:59+03:00" \
  -d "minDurationSeconds=30" -d "page=1" -d "pageSize=100" -d "order=asc"

curl -G "https://<адрес-API>/v1/transcripts/export" \
  -H "X-API-Key: <ключ>" \
  --data-urlencode "dateFrom=2026-09-01T00:00:00+03:00" \
  -d "format=zip" -d "limit=10000" -OJ

Страницы читайте, пока page × pageSize меньше total в ответе. Ответ выгрузки несёт заголовки X-Transcripts-Matching (сколько подошло) и X-Transcripts-Exported (сколько в файле). Фильтры те же, что в «Звонки»: q, source, dateFrom, dateTo, createdFrom, createdTo, minDurationSeconds, maxDurationSeconds, direction, manager, phone, externalCallId, scoreBelow; тексты есть только у готовых записей. Полнотекстовый поиск q учитывает не больше 2000 лучших совпадений.

Колбэки

Запись, созданная с callbackUrl, получает POST с JSON, когда расшифровка завершилась:

{ "event": "recording.done", "recording": { "id": "…", "status": "DONE", "transcript": { "text": "…" } } }

Поле event равно recording.done или recording.failed, а recording это тот же объект, что отдаёт GET /v1/recordings/{id}. Для отменённой записи колбэк не отправляется.

Заголовок Значение
X-TGT-Event recording.done или recording.failed
X-TGT-Delivery идентификатор доставки; при повторной попытке тот же
X-TGT-Timestamp время отправки в секундах Unix (только если задан CALLBACK_SIGNING_SECRET)
X-TGT-Signature sha256= и HMAC-SHA256 в виде hex (только если задан CALLBACK_SIGNING_SECRET)

Правила доставки:

  • Ответ 2xx считается принятым. Таймаут 15 секунд.
  • Сетевые ошибки, 5xx, 408, 425 и 429 повторяются: всего шесть попыток с паузами 30 секунд, 1, 2, 4 и 8 минут.
  • Остальные ответы 3xx и 4xx считаются окончательным отказом и не повторяются. Перенаправления не выполняются: указывайте конечный адрес.
  • Адреса частной сети, localhost и link-local запрещены, если на сервере не включён ALLOW_PRIVATE_NETWORK_DOWNLOADS.
  • Если колбэк не дошёл, результат всегда можно забрать запросом GET /v1/recordings/{id}.

Как проверить подпись

Подпись считается по строке <X-TGT-Timestamp>.<тело запроса> секретом CALLBACK_SIGNING_SECRET. Тело берите в том виде, в каком оно пришло, до разбора JSON.

import { createHmac, timingSafeEqual } from 'node:crypto'

export function isGenuine(rawBody, timestamp, signatureHeader, secret) {
  const expected = createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest('hex')
  const received = signatureHeader.replace('sha256=', '')
  return received.length === expected.length && timingSafeEqual(Buffer.from(received), Buffer.from(expected))
}
import hashlib
import hmac


def is_genuine(raw_body: bytes, timestamp: str, signature_header: str, secret: str) -> bool:
    message = timestamp.encode() + b'.' + raw_body
    expected = hmac.new(secret.encode(), message, hashlib.sha256).hexdigest()
    received = signature_header.removeprefix('sha256=')
    return hmac.compare_digest(received, expected)

Отклоняйте запросы, у которых X-TGT-Timestamp старше нескольких минут, и по X-TGT-Delivery пропускайте доставки, которые уже обработали. При каждой попытке время и подпись пересчитываются, поэтому проверяйте именно присланные значения.

Формат ошибки

Все ошибки приходят в одном виде:

{ "statusCode": 409, "message": "A recording with this call id or storage key is already registered", "error": "Conflict" }

Если не прошла проверка полей, message это массив строк, по одной на поле.

Код Когда
400 не прошла проверка полей, нет части file, неизвестное поле, недоступная ссылка
401 ключ не передан, неверен или отозван (Missing or invalid credentials)
403 метод недоступен ключу или роли (Your role does not allow this)
404 записи нет или она вне доступа; для from-storage нет файла в хранилище
409 повтор externalCallId или ключа хранилища; расшифровка ещё не готова; запись нельзя повторить или отменить в этом состоянии
413 файл больше MAX_UPLOAD_MB
429 слишком много неудачных входов (только вход человека; заголовок Retry-After)

Ограничения

Что Предел
Размер файла MAX_UPLOAD_MB, по умолчанию 512 МБ
Длина записи 3 часа, длиннее получает AUDIO_TOO_LONG
Тело JSON 1 МБ
Страница списка pageSize от 1 до 100, по умолчанию 25
Выгрузка расшифровок limit по умолчанию 10 000, не больше 50 000, самые старые записи первыми
Частота запросов ограничения нет

Большие и медленные загрузки отправляйте прямо на домен API по ключу, а не через панель: запрос через панель должен уложиться в 5 минут. Ссылки в from-url и callbackUrl проверяются: адреса частной сети, localhost и link-local отклоняются по имени, по литералу адреса и при перенаправлении.

События завершённых звонков из Битрикс24 принимает метод POST /v1/integrations/bitrix24/events: он открыт, но требует токен приложения исходящего вебхука. Настройка описана в Подключение Битрикс24.

См. также