Расшифровать аудио

POST /v1/audio/transcriptions

Преобразует аудиофайл в текст через Whisper Large v3 Turbo — без подключения BYOK. Расшифровка учитывается в AI-квоте портала по длительности аудио: в рамках квоты тарифа деньги с баланса не списываются, сверх квоты расход списывается с денежного баланса портала по базовой цене модели. Принимает файл через multipart/form-data. Формат запроса и ответа совместим с POST /v1/audio/transcriptions из OpenAI API.

Ответ приходит в сыром OpenAI-формате.

Обёртки {success, data}, которая используется в остальных эндпоинтах Вайбкод — /v1/deals, /v1/tasks и других, — здесь нет.

Так сделано для совместимости с OpenAI SDK. Если у вас единый клиент с проверкой if (!response.success), добавьте для AI Router исключение.

Поля запроса (form-data)

Поле Тип Обяз. По умолч. Описание
file file да Аудиофайл. Поддерживаются mp3, mp4, mpeg, mpga, m4a, wav, webm, flac, ogg. Максимальный размер — 25 МБ
model string нет deepdml/faster-whisper-large-v3-turbo-ct2 ID Whisper-модели. Префикс bitrix/ опционален и автоматически удаляется
language string нет автоопределение Код языка по ISO 639 (2-3 буквы): ru, en, de, fr, zh и т. п. Указание языка ускоряет распознавание
prompt string нет Контекстная подсказка: тема разговора, стиль, правильное написание терминов. До 2000 символов, модель учитывает последние ~224 токена
hotwords string нет Спец-слова и термины через запятую — повышают точность распознавания редких названий и брендов. До 500 символов
temperature number нет 0 Температура декодера от 0 до 1. 0 — детерминированный результат, выше — больше вариативности. Значения вне диапазона отклоняются
vad_filter boolean нет true включает VAD-фильтр: модель вырезает тишину перед распознаванием — меньше галлюцинаций на записях с паузами
timestamp_granularities[] string нет segment Детализация таймстампов: word или segment (поле можно повторять). Только с response_format=verbose_json. С word каждый сегмент дополняется массивом words с таймингом и вероятностью каждого слова
response_format string нет json Формат результата: json, text, srt, vtt, verbose_json

Примеры

curl — личный ключ

Terminal
curl -X POST https://vibecode.bitrix24.tech/v1/audio/transcriptions \
  -H "X-Api-Key: YOUR_API_KEY" \
  -F "file=@call-recording.mp3" \
  -F "language=ru" \
  -F "response_format=json"

curl — OAuth-приложение

Terminal
curl -X POST https://vibecode.bitrix24.tech/v1/audio/transcriptions \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -F "file=@call-recording.mp3" \
  -F "language=ru" \
  -F "response_format=json"

JavaScript — личный ключ

javascript
const formData = new FormData()
formData.append('file', audioFile)  // объект File или Blob
formData.append('language', 'ru')
formData.append('response_format', 'json')

const res = await fetch('https://vibecode.bitrix24.tech/v1/audio/transcriptions', {
  method: 'POST',
  headers: { 'X-Api-Key': 'YOUR_API_KEY' },
  body: formData,
})

const result = await res.json()
console.log('Распознанный текст:', result.text)

JavaScript — OAuth-приложение

javascript
const formData = new FormData()
formData.append('file', audioFile)
formData.append('language', 'ru')

const res = await fetch('https://vibecode.bitrix24.tech/v1/audio/transcriptions', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
  },
  body: formData,
})

const result = await res.json()
console.log('Текст:', result.text)

Поля ответа

Структура ответа зависит от response_format. Формат json (по умолчанию) — самый компактный, verbose_json — с таймингами.

`response_format: json`

Поле Тип Описание
text string Распознанный текст целиком

`response_format: text`

Ответ — обычная строка с распознанным текстом, без JSON-обёртки.

`response_format: verbose_json`

Поле Тип Описание
task string Тип задачи: transcribe
language string Код определённого или указанного языка
duration number Длительность аудио в секундах
text string Распознанный текст целиком
usage object | null Метаданные использования модели. null, если модель их не возвращает
words array Пословные тайминги на уровне всего ответа. Пустой массив, если пословные тайминги не запрошены
segments array Сегменты с таймингами и метаданными распознавания
segments[].id number Порядковый номер сегмента
segments[].seek number Внутренний сдвиг окна распознавания Whisper
segments[].start number Начало сегмента в секундах
segments[].end number Конец сегмента в секундах
segments[].text string Текст сегмента
segments[].tokens array Токены модели для текста сегмента (целые числа)
segments[].temperature number Температура декодирования, применённая моделью
segments[].avg_logprob number Средняя логарифмическая вероятность токенов сегмента — метрика уверенности
segments[].compression_ratio number Коэффициент сжатия текста сегмента
segments[].no_speech_prob number Вероятность того, что в сегменте нет речи
segments[].words array Пословные тайминги внутри сегмента. Пустой массив, если не запрошены
segments[].emotion string | null Определённая эмоция сегмента. null, если не определена

`response_format: srt` / `vtt`

Ответ — субтитры в формате SubRip Text или WebVTT.

Пример ответа

response_format: json:

JSON
{
  "text": "Здравствуйте, ООО Вектор. Хотим CRM на 50 пользователей, бюджет до 500 тысяч в месяц."
}

response_format: verbose_json:

JSON
{
  "task": "transcribe",
  "language": "ru",
  "duration": 8.42,
  "text": "Здравствуйте, ООО Вектор. Хотим CRM на 50 пользователей, бюджет до 500 тысяч в месяц.",
  "usage": null,
  "words": [],
  "segments": [
    {
      "id": 0,
      "seek": 0,
      "start": 0.0,
      "end": 3.2,
      "text": "Здравствуйте, ООО Вектор.",
      "tokens": [50365, 2425, 11, 341, 307],
      "temperature": 0.0,
      "avg_logprob": -0.38,
      "compression_ratio": 1.12,
      "no_speech_prob": 0.02,
      "words": [],
      "emotion": null
    },
    {
      "id": 1,
      "seek": 320,
      "start": 3.2,
      "end": 8.42,
      "text": "Хотим CRM на 50 пользователей, бюджет до 500 тысяч в месяц.",
      "tokens": [50414, 1003, 13767, 295, 1500],
      "temperature": 0.0,
      "avg_logprob": -0.41,
      "compression_ratio": 1.20,
      "no_speech_prob": 0.01,
      "words": [],
      "emotion": null
    }
  ]
}

Пример ответа при ошибке

400 no_file — поле file не передано:

JSON
{
  "error": {
    "message": "Audio file is required. Send as multipart/form-data with field \"file\".",
    "type": "invalid_request_error",
    "code": "no_file"
  }
}

Ошибки

HTTP Код Описание
400 no_file Поле file не передано в multipart/form-data
400 empty_file Поле file передано, но файл пустой (0 байт). Частая причина: curl -F "file=path" без префикса @ — curl отправляет строку пути вместо содержимого файла
400 invalid_prompt Поле prompt длиннее 2000 символов
400 invalid_hotwords Поле hotwords длиннее 500 символов
400 invalid_temperature Поле temperature не число или вне диапазона 0..1
400 invalid_vad_filter Поле vad_filter не true и не false
400 invalid_timestamp_granularities Значение не word/segment, либо формат ответа не verbose_json
400 invalid_language Код языка не соответствует формату ISO 639 (2-3 буквы)
402 ai_credentials_not_configured На платформе не настроен Bitrix-провайдер
402 insufficient_balance PREPAY-счёт ушёл за овердрафт — проверяется ДО вызова распознавания (только PLATFORM/PORTAL-ключи; BYOK бесплатен и не проверяется). Полностью замороженный счёт отклоняется раньше кодом ACCOUNT_FROZEN
402 ai_quota_exhausted Месячная AI-квота портала исчерпана — см. «Известные особенности» ниже
403 scope_missing API-ключу не хватает скоупа vibe:ai
502 ai_provider_unavailable Whisper-сервис вернул ошибку или недоступен
503 ai_provider_timeout Whisper не ответил в течение 15 минут — файл слишком длинный или сервис перегружен. Для записей длиннее ~30 минут разбивайте на части
401 MISSING_API_KEY Не передан заголовок X-Api-Key
429 ai_congested Пул AI-кластера перегружен. Запрос не выполнялся, списания нет, повторите его по заголовку Retry-After. Ответ несёт заголовок X-AI-Admission: shed, а не X-RateLimit-Scope
429 ai_pacing_limited Превышено суточное или недельное окно равномерного расходования квоты. Это не исчерпание квоты — повторите запрос по заголовку Retry-After. Подробнее — «Равномерное расходование»

Полный список общих ошибок API — Ошибки.

Известные особенности

Подсказки повышают точность на редких терминах. Поле prompt задаёт контекст — тему разговора, стиль, правильное написание терминов. Поле hotwords перечисляет через запятую спец-слова, на которые декодер получает повышенный приоритет. Разница на фразе «обсуждаем интеграцию NeuralDeep с Kimi и подход RAG»:

Запрос Результат
Без подсказок «…интеграцию нейролдипскими и подход рак для поиска…»
С hotwords «…интеграцию NeuralDeep с Kimi и подход RAG для поиска…»

В рамках квоты — без списаний, сверх квоты — по базовой цене модели. Whisper работает на инфраструктуре Битрикс24. Расшифровка тарифицируется по длительности аудио и учитывается в месячной AI-квоте портала. Пока расход укладывается в квоту тарифа, деньги с баланса портала не списываются. Сверх квоты расход списывается с денежного баланса портала по базовой цене модели из каталога. На порталах с включённым контролем квоты запрос может вернуть 402 ai_quota_exhausted, когда месячный лимит исчерпан. Поле reason различает три случая: breaker — сработал часовой предохранитель расходов сверх квоты, wallet_empty — квота исчерпана и на балансе портала нет средств, wallet_off — расход сверх квоты для портала недоступен. Поле resetAt — момент, когда запросы снова начнут проходить, для wallet_off оно может отсутствовать.

Лимит размера — 25 МБ. Для длинных записей разбивайте файл на части до 25 МБ и склеивайте результаты на стороне клиента. Один час mp3 128 кбит/с примерно 60 МБ — придётся резать.

Тайм-аут запроса — 15 минут. Расшифровка длится примерно 5-15 % от длины аудио. Файл на 5 минут (5-7 МБ mp3) расшифровывается за 15-45 секунд. При превышении тайм-аута возвращается 503 ai_provider_timeout.

Смотрите также