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". Дальше есть два способа получить результат.
- Подождать колбэк на
callbackUrl(см. ниже). - Опрашивать
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.
См. также¶
- Журнал, ключи и аккаунты: создание и отзыв ключей в интерфейсе.
- Подключение Битрикс24: входящий и исходящий вебхуки.
- Персональные данные и хранение: что видит ключ и что уходит в колбэк.
- Выгрузка и загрузка: то же из интерфейса.