[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"docs-ai\u002Faudio\u002Ftranscriptions":3,"docs-tabs-ai\u002Faudio\u002Ftranscriptions":6},{"content":4,"lastmod":5},"\n## Расшифровать аудио\n\n`POST \u002Fv1\u002Faudio\u002Ftranscriptions`\n\nПреобразует аудиофайл в текст через Whisper Large v3 Turbo — без подключения BYOK. Расшифровка учитывается в AI-квоте портала по длительности аудио: в рамках квоты тарифа деньги с баланса не списываются, сверх квоты расход списывается с денежного баланса портала по базовой цене модели. Принимает файл через `multipart\u002Fform-data`. Формат запроса и ответа совместим с `POST \u002Fv1\u002Faudio\u002Ftranscriptions` из OpenAI API.\n\n> **Ответ приходит в сыром OpenAI-формате.**\n>\n> Обёртки `{success, data}`, которая используется в остальных эндпоинтах Вайбкод — `\u002Fv1\u002Fdeals`, `\u002Fv1\u002Ftasks` и других, — здесь нет.\n>\n> Так сделано для совместимости с OpenAI SDK. Если у вас единый клиент с проверкой `if (!response.success)`, добавьте для AI Router исключение.\n\n## Поля запроса (form-data)\n\n| Поле | Тип | Обяз. | По умолч. | Описание |\n|------|-----|:-----:|-----------|----------|\n| `file` | file | да | — | Аудиофайл. Поддерживаются `mp3`, `mp4`, `mpeg`, `mpga`, `m4a`, `wav`, `webm`, `flac`, `ogg`. Максимальный размер — 25 МБ |\n| `model` | string | нет | `deepdml\u002Ffaster-whisper-large-v3-turbo-ct2` | ID Whisper-модели. Префикс `bitrix\u002F` опционален и автоматически удаляется |\n| `language` | string | нет | автоопределение | Код языка по `ISO 639` (2-3 буквы): `ru`, `en`, `de`, `fr`, `zh` и т. п. Указание языка ускоряет распознавание |\n| `prompt` | string | нет | — | Контекстная подсказка: тема разговора, стиль, правильное написание терминов. До 2000 символов, модель учитывает последние ~224 токена |\n| `hotwords` | string | нет | — | Спец-слова и термины через запятую — повышают точность распознавания редких названий и брендов. До 500 символов |\n| `temperature` | number | нет | `0` | Температура декодера от `0` до `1`. `0` — детерминированный результат, выше — больше вариативности. Значения вне диапазона отклоняются |\n| `vad_filter` | boolean | нет | — | `true` включает VAD-фильтр: модель вырезает тишину перед распознаванием — меньше галлюцинаций на записях с паузами |\n| `timestamp_granularities[]` | string | нет | `segment` | Детализация таймстампов: `word` или `segment` (поле можно повторять). Только с `response_format=verbose_json`. С `word` каждый сегмент дополняется массивом `words` с таймингом и вероятностью каждого слова |\n| `response_format` | string | нет | `json` | Формат результата: `json`, `text`, `srt`, `vtt`, `verbose_json` |\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X POST https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Faudio\u002Ftranscriptions \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -F \"file=@call-recording.mp3\" \\\n  -F \"language=ru\" \\\n  -F \"response_format=json\"\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X POST https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Faudio\u002Ftranscriptions \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\" \\\n  -F \"file=@call-recording.mp3\" \\\n  -F \"language=ru\" \\\n  -F \"response_format=json\"\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst formData = new FormData()\nformData.append('file', audioFile)  \u002F\u002F объект File или Blob\nformData.append('language', 'ru')\nformData.append('response_format', 'json')\n\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Faudio\u002Ftranscriptions', {\n  method: 'POST',\n  headers: { 'X-Api-Key': 'YOUR_API_KEY' },\n  body: formData,\n})\n\nconst result = await res.json()\nconsole.log('Распознанный текст:', result.text)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst formData = new FormData()\nformData.append('file', audioFile)\nformData.append('language', 'ru')\n\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Faudio\u002Ftranscriptions', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n  },\n  body: formData,\n})\n\nconst result = await res.json()\nconsole.log('Текст:', result.text)\n```\n\n## Поля ответа\n\nСтруктура ответа зависит от `response_format`. Формат `json` (по умолчанию) — самый компактный, `verbose_json` — с таймингами.\n\n### `response_format: json`\n\n| Поле | Тип | Описание |\n|------|-----|----------|\n| `text` | string | Распознанный текст целиком |\n\n### `response_format: text`\n\nОтвет — обычная строка с распознанным текстом, без `JSON`-обёртки.\n\n### `response_format: verbose_json`\n\n| Поле | Тип | Описание |\n|------|-----|----------|\n| `task` | string | Тип задачи: `transcribe` |\n| `language` | string | Код определённого или указанного языка |\n| `duration` | number | Длительность аудио в секундах |\n| `text` | string | Распознанный текст целиком |\n| `usage` | object \\| null | Метаданные использования модели. `null`, если модель их не возвращает |\n| `words` | array | Пословные тайминги на уровне всего ответа. Пустой массив, если пословные тайминги не запрошены |\n| `segments` | array | Сегменты с таймингами и метаданными распознавания |\n| `segments[].id` | number | Порядковый номер сегмента |\n| `segments[].seek` | number | Внутренний сдвиг окна распознавания Whisper |\n| `segments[].start` | number | Начало сегмента в секундах |\n| `segments[].end` | number | Конец сегмента в секундах |\n| `segments[].text` | string | Текст сегмента |\n| `segments[].tokens` | array | Токены модели для текста сегмента (целые числа) |\n| `segments[].temperature` | number | Температура декодирования, применённая моделью |\n| `segments[].avg_logprob` | number | Средняя логарифмическая вероятность токенов сегмента — метрика уверенности |\n| `segments[].compression_ratio` | number | Коэффициент сжатия текста сегмента |\n| `segments[].no_speech_prob` | number | Вероятность того, что в сегменте нет речи |\n| `segments[].words` | array | Пословные тайминги внутри сегмента. Пустой массив, если не запрошены |\n| `segments[].emotion` | string \\| null | Определённая эмоция сегмента. `null`, если не определена |\n\n### `response_format: srt` \u002F `vtt`\n\nОтвет — субтитры в формате `SubRip Text` или `WebVTT`.\n\n## Пример ответа\n\n`response_format: json`:\n\n```json\n{\n  \"text\": \"Здравствуйте, ООО Вектор. Хотим CRM на 50 пользователей, бюджет до 500 тысяч в месяц.\"\n}\n```\n\n`response_format: verbose_json`:\n\n```json\n{\n  \"task\": \"transcribe\",\n  \"language\": \"ru\",\n  \"duration\": 8.42,\n  \"text\": \"Здравствуйте, ООО Вектор. Хотим CRM на 50 пользователей, бюджет до 500 тысяч в месяц.\",\n  \"usage\": null,\n  \"words\": [],\n  \"segments\": [\n    {\n      \"id\": 0,\n      \"seek\": 0,\n      \"start\": 0.0,\n      \"end\": 3.2,\n      \"text\": \"Здравствуйте, ООО Вектор.\",\n      \"tokens\": [50365, 2425, 11, 341, 307],\n      \"temperature\": 0.0,\n      \"avg_logprob\": -0.38,\n      \"compression_ratio\": 1.12,\n      \"no_speech_prob\": 0.02,\n      \"words\": [],\n      \"emotion\": null\n    },\n    {\n      \"id\": 1,\n      \"seek\": 320,\n      \"start\": 3.2,\n      \"end\": 8.42,\n      \"text\": \"Хотим CRM на 50 пользователей, бюджет до 500 тысяч в месяц.\",\n      \"tokens\": [50414, 1003, 13767, 295, 1500],\n      \"temperature\": 0.0,\n      \"avg_logprob\": -0.41,\n      \"compression_ratio\": 1.20,\n      \"no_speech_prob\": 0.01,\n      \"words\": [],\n      \"emotion\": null\n    }\n  ]\n}\n```\n\n## Пример ответа при ошибке\n\n`400 no_file` — поле `file` не передано:\n\n```json\n{\n  \"error\": {\n    \"message\": \"Audio file is required. Send as multipart\u002Fform-data with field \\\"file\\\".\",\n    \"type\": \"invalid_request_error\",\n    \"code\": \"no_file\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|----------|\n| 400 | `no_file` | Поле `file` не передано в `multipart\u002Fform-data` |\n| 400 | `empty_file` | Поле `file` передано, но файл пустой (0 байт). Частая причина: `curl -F \"file=path\"` без префикса `@` — curl отправляет строку пути вместо содержимого файла |\n| 400 | `invalid_prompt` | Поле `prompt` длиннее 2000 символов |\n| 400 | `invalid_hotwords` | Поле `hotwords` длиннее 500 символов |\n| 400 | `invalid_temperature` | Поле `temperature` не число или вне диапазона 0..1 |\n| 400 | `invalid_vad_filter` | Поле `vad_filter` не `true` и не `false` |\n| 400 | `invalid_timestamp_granularities` | Значение не `word`\u002F`segment`, либо формат ответа не `verbose_json` |\n| 400 | `invalid_language` | Код языка не соответствует формату `ISO 639` (2-3 буквы) |\n| 402 | `ai_credentials_not_configured` | На платформе не настроен Bitrix-провайдер |\n| 402 | `insufficient_balance` | PREPAY-счёт ушёл за овердрафт — проверяется ДО вызова распознавания (только PLATFORM\u002FPORTAL-ключи; BYOK бесплатен и не проверяется). Полностью замороженный счёт отклоняется раньше кодом `ACCOUNT_FROZEN` |\n| 402 | `ai_quota_exhausted` | Месячная AI-квота портала исчерпана — см. «Известные особенности» ниже |\n| 403 | `scope_missing` | API-ключу не хватает скоупа `vibe:ai` |\n| 502 | `ai_provider_unavailable` | Whisper-сервис вернул ошибку или недоступен |\n| 503 | `ai_provider_timeout` | Whisper не ответил в течение 15 минут — файл слишком длинный или сервис перегружен. Для записей длиннее ~30 минут разбивайте на части |\n| 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` |\n| 429 | `ai_congested` | Пул AI-кластера перегружен. Запрос не выполнялся, списания нет, повторите его по заголовку `Retry-After`. Ответ несёт заголовок `X-AI-Admission: shed`, а не `X-RateLimit-Scope` |\n| 429 | `ai_pacing_limited` | Превышено суточное или недельное окно равномерного расходования квоты. Это не исчерпание квоты — повторите запрос по заголовку `Retry-After`. Подробнее — [«Равномерное расходование»](\u002Fdocs\u002Fai\u002Fconsumption\u002Fquota#равномерное-расходование-pacing) |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Известные особенности\n\n**Подсказки повышают точность на редких терминах.** Поле `prompt` задаёт контекст — тему разговора, стиль, правильное написание терминов. Поле `hotwords` перечисляет через запятую спец-слова, на которые декодер получает повышенный приоритет. Разница на фразе «обсуждаем интеграцию NeuralDeep с Kimi и подход RAG»:\n\n| Запрос | Результат |\n|---|---|\n| Без подсказок | «…интеграцию нейролдипскими и подход рак для поиска…» |\n| С `hotwords` | «…интеграцию NeuralDeep с Kimi и подход RAG для поиска…» |\n\n\n**В рамках квоты — без списаний, сверх квоты — по базовой цене модели.** Whisper работает на инфраструктуре Битрикс24. Расшифровка тарифицируется по длительности аудио и учитывается в месячной AI-квоте портала. Пока расход укладывается в квоту тарифа, деньги с баланса портала не списываются. Сверх квоты расход списывается с денежного баланса портала по базовой цене модели из каталога. На порталах с включённым контролем квоты запрос может вернуть `402 ai_quota_exhausted`, когда месячный лимит исчерпан. Поле `reason` различает три случая: `breaker` — сработал часовой предохранитель расходов сверх квоты, `wallet_empty` — квота исчерпана и на балансе портала нет средств, `wallet_off` — расход сверх квоты для портала недоступен. Поле `resetAt` — момент, когда запросы снова начнут проходить, для `wallet_off` оно может отсутствовать.\n\n**Лимит размера — 25 МБ.** Для длинных записей разбивайте файл на части до 25 МБ и склеивайте результаты на стороне клиента. Один час `mp3` 128 кбит\u002Fс примерно 60 МБ — придётся резать.\n\n**Тайм-аут запроса — 15 минут.** Расшифровка длится примерно 5-15 % от длины аудио. Файл на 5 минут (5-7 МБ `mp3`) расшифровывается за 15-45 секунд. При превышении тайм-аута возвращается `503 ai_provider_timeout`.\n\n## Смотрите также\n\n- [Распознавание речи](\u002Fdocs\u002Fai\u002Faudio)\n- [Создать чат-комплишен](\u002Fdocs\u002Fai\u002Fchat\u002Fcompletions)\n- [AI Router](\u002Fdocs\u002Fai)\n","2026-07-14",{}]