Представьте себе сценарий, знакомый каждому разработчику, работающему с голосовыми данными: у вас есть 40-минутная запись продающего звонка, папка с голосовыми заметками или пользователь, удерживающий кнопку записи в приложении. Задача очевидна — превратить этот аудиофайл в текст. Традиционный подход часто заставляет нас изобретать велосипед: поднимать собственный сервер с Whisper, подключать второй SDK для работы со speech-to-text (STT) и настраивать отдельную инфраструктуру, которая дублирует логику обработки чатов. Это усложняет архитектуру, увеличивает стоимость поддержки и создает точки отказа.
OpenRouter предлагает элегантное решение, объединяющее эти процессы. Вместо того чтобы разбивать архитектуру на изолированные сервисы, вы можете отправлять аудио напрямую на эндпоинт POST /api/v1/audio/transcriptions, используя тот же API-ключ и механизм аутентификации, что и для стандартных запросов к моделям чата. Это не просто удобство; это архитектурное преимущество. Поскольку транскрипция работает на той же платформе, что и генерация текста, модели, поддерживающие эту функцию, автоматически балансируются между несколькими провайдерами. Вы больше не привязаны к одному вендору, а ваша нагрузка распределяется оптимальным образом.
В этой статье мы подробно разберем, как эффективно использовать этот функционал. Мы рассмотрим доступные модели, структуру запросов, нюансы работы с провайдерами, ограничения системы и, что самое важное, как контролировать расходы. Это руководство поможет вам интегрировать мощные возможности распознавания речи в ваши приложения без лишней сложности.
01Как работает транскрипция в OpenRouter: базовый поток
Основной принцип работы с транскрипцией в OpenRouter сводится к трем простым шагам. Во-первых, вы кодируете аудиофайл в формат base64. Во-вторых, отправляете этот файл вместе с указанием модели и формата на эндпоинт POST /api/v1/audio/transcriptions. В-третьих, получаете обратно JSON-объект, содержащий поле text с расшифрованным текстом и объект usage с метриками использования.
Важно отметить, что этот процесс не требует асинхронных запросов, ожидания job ID или опроса сервера. Результат возвращается сразу в теле ответа. Это делает интеграцию максимально простой и предсказуемой. Вы передаете свой ключ OpenRouter в заголовке Authorization: Bearer точно так же, как при вызове Chat Completions, указываете модель и передаете аудио. Все остальное — магия платформы.
Давайте посмотрим на пример реализации на разных языках. Для начала, базовый запрос с использованием curl. Здесь мы предварительно кодируем файл meeting.mp3 в base64 и отправляем его в теле запроса. Обратите внимание на структуру поля input_audio, которое содержит данные и формат файла.
# Encode the file to base64, then POST it.
AUDIO_B64=$(base64 -i meeting.mp3 tr -d '\n')
curl https://openrouter.ai/api/v1/audio/transcriptions \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/whisper-1",
"input_audio": { "data": "'"$AUDIO_B64"'", "format": "mp3" },
"language": "en"
}'Для разработчиков на Python процесс еще более интуитивен благодаря стандартной библиотеке requests. Мы читаем файл в бинарном режиме, кодируем его и передаем в JSON-теле запроса. Код остается чистым и легко читаемым.
import base64
import os
import requests
with open("meeting.mp3", "rb") as f:
audio_b64 = base64.b64encode(f.read()).decode("utf-8")
api_key = os.environ["OPENROUTER_API_KEY"]
response = requests.post(
"https://openrouter.ai/api/v1/audio/transcriptions",
headers={"Authorization": f"Bearer {api_key}"},
json={
"model": "openai/whisper-1",
"input_audio": {"data": audio_b64, "format": "mp3"},
"language": "en"
}
)
print(response.json()["text"])Если вы используете TypeScript или Node.js, официальный SDK OpenRouter предоставляет метод stt.createTranscription, который абстрагирует работу с HTTP-запросами. Это особенно удобно, если вы уже используете SDK для других задач, так как позволяет сохранить единый стиль кода.

import { OpenRouter } from '@openrouter/sdk';
import { readFileSync } from 'fs';
const openRouter = new OpenRouter({ apiKey: process.env.OPENROUTER_API_KEY });
const audioB64 = readFileSync('meeting.mp3').toString('base64');
const result = await openRouter.stt.createTranscription({
sttRequest: {
model: 'openai/whisper-1',
inputAudio: { data: audioB64, format: 'mp3' },
language: 'en'
},
});
console.log(result.text);02Доступные модели для распознавания речи
При выборе модели для транскрипции важно понимать, что они делятся на два основных семейства, различающихся не только качеством, но и моделью ценообразования. Первое семейство — это модели класса Whisper, такие как openai/whisper-1. Они тарифицируются по длительности аудио, то есть вы платите за каждую секунду обработки. Это классический подход, знакомый многим по прямому использованию API OpenAI.
Второе семейство — это новые модели speech-to-text (STT), которые тарифицируются по количеству токенов. Это может быть более выгодно для коротких записей или записей с большим количеством пауз, где количество сгенерированного текста (и, следовательно, токенов) меньше, чем эквивалентная стоимость в секундах. Выбор между ними зависит от ваших требований к точности, языкового состава аудио и бюджета.
Ключевой момент, который часто вызывает путаницу: идентификаторы STT-моделей не отображаются в каталоге моделей по умолчанию (/api/v1/models). Это сделано намеренно, так как транскрипция является отдельной модальностью вывода. Чтобы найти доступные модели для распознавания речи, необходимо использовать фильтр output_modalities.
curl "https://openrouter.ai/api/v1/models?output_modalities=transcription" \
-H "Authorization: Bearer $OPENROUTER_API_KEY"Этот запрос вернет список всех доступных моделей для транскрипции с их текущими ценами. Аналогичный список доступен в коллекции "Speech-to-Text" на сайте OpenRouter и в каталоге моделей, где отображаются живые ставки. Если вы хотите протестировать модель перед интеграцией, используйте OpenRouter Playground, где можно загрузить файл и получить результат прямо в браузере.
03Структура запроса: детали и нюансы
Понимание структуры запроса критически важно для успешной интеграции. Основной объект запроса содержит поле model (обязательное), объект input_audio (обязательный) и ряд опциональных параметров. В объекте input_audio поле data должно содержать сырые байты в формате base64. Важно не добавлять префикс типа URI (например, data:audio/mp3;base64,), так как API ожидает только строку с закодированными данными.
Поле format также обязательно. Оно сообщает модели, как декодировать переданные байты. Поддерживаемые форматы включают wav, mp3, flac, m4a, ogg, webm и aac. Выбор формата влияет на размер полезной нагрузки и скорость обработки. Сжатые форматы, такие как MP3, создают меньшие и более быстрые запросы, но WAV остается самым надежным выбором для максимальной совместимости.
https://openrouter.ai/api/v1. OpenRouter поддерживает формат загрузки multipart/form-data (файл + модель), что позволяет использовать существующий код с минимальными изменениями. Однако этот метод ограничен файлами до 25 МБ. Для больших файлов используйте путь base64 JSON.Параметр language опционален. Если вы его не укажете, модель попытается определить язык автоматически. Однако для коротких или зашумленных записей явное указание языка (в формате ISO-639-1, например, en или es) помогает устранить неоднозначности и повысить точность.

Еще один мощный инструмент — объект provider. Он позволяет передавать специфичные для провайдера опции. Например, Groq принимает параметр prompt для указания ожидаемой лексики. Это особенно полезно для технических терминов или имен собственных, которые модель может исказить. Вы передаете эти опции через вложенный объект, ключом которого является slug провайдера:
{
"model": "openai/whisper-large-v3",
"input_audio": { "data": "", "format": "wav" },
"provider": {
"options": {
"groq": {
"prompt": "Expected vocabulary: OpenRouter, API, transcription"
}
}
}
} 04Ответ и учет затрат
Ответ от сервера всегда приходит в формате JSON. Основное поле text содержит саму транскрипцию. Но самое ценное для разработчиков — это объект usage. Он предоставляет детальную статистику, необходимую для точного мониторинга расходов.
{
"text": "Thanks everyone for joining. Let's start with the Q3 numbers.",
"usage": {
"seconds": 9.2,
"total_tokens": 113,
"input_tokens": 83,
"output_tokens": 30,
"cost": 0.000508
}
}В объекте usage вы найдете длительность аудио в секундах, количество входных и выходных токенов, а главное — поле cost. Это поле содержит фактическую стоимость запроса в долларах США. Оно рассчитывается на основе тарифов модели и длины аудио. Используя это поле, вы можете внедрить точный учет расходов в своем приложении, не полагаясь на приблизительные оценки.
Также обратите внимание на заголовок ответа X-Generation-Id. Сохраняйте этот ID для каждого запроса. Он понадобится вам для отладки, если возникнут проблемы с конкретным вызовом API, или для аудита истории запросов.
05Транскрипция vs. Аудио-ввод vs. Текст-в-речь
В экосистеме OpenRouter существует три разных способа работы с аудио, и важно не путать их, чтобы использовать правильный эндпоинт для вашей задачи.
- POST /api/v1/audio/transcriptions: Используйте этот эндпоинт, когда ваша цель — получить текст из аудио. Это идеальный вариант для создания заметок по встречам, голосовых команд, субтитров в реальном времени или архивирования подкастов. Результат — чистый текст и метрики использования.
- input_audio в /chat/completions: Если вам нужно, чтобы модель "поняла" аудио, проанализировала его или ответила на вопросы по его содержанию, используйте параметр
input_audioв типе контента для чата. Это позволяет модели рассуждать об аудио, определять настроение или отвечать на вопросы (Q&A). Это мультимодальный подход. - Text-to-Speech (TTS): Это отдельный эндпоинт, предназначенный для преобразования текста в речь. Он не связан с транскрипцией напрямую.
Простое правило: хотите текст? Используйте /audio/transcriptions. Хотите, чтобы ИИ проанализировал или ответил на аудио? Используйте input_audio в чате.

06Маршрутизация провайдеров и контроль
Одним из главных преимуществ OpenRouter является маршрутизация. Когда модель транскрипции доступна у нескольких провайдеров, платформа автоматически распределяет запросы между ними, балансируя по цене и доступности. Это защищает вас от простоев и позволяет выбирать лучшие цены.
Однако, в отличие от запросов к чатам, на эндпоинте транскрипции недоступны некоторые параметры маршрутизации, такие как order, allow_fallbacks, data_collection и sort. Вы не можете вручную указать порядок предпочтения провайдеров или разрешить фоллбэки на этом эндпоинте. Вместо этого объект provider используется исключительно для передачи специфичных опций (как в примере с Groq выше).
Если вам нужно зафиксировать конкретного провайдера или применить строгую политику данных на уровне запроса, эта функция пока не реализована для транскрипции. Но есть альтернатива: Bring-Your-Own-Key (BYOK). Если у вас уже есть договоренность с провайдером (например, с собственным ключом OpenAI или Groq), вы можете использовать BYOK. В этом случае вы платите только комиссию платформы за обработку запроса, а не стоимость самой модели. Для тарифного плана pay-as-you-go первые 1 миллион запросов в месяц с BYOK бесплатны.
07Ограничения и лимиты
При проектировании системы транскрипции необходимо учитывать четыре ключевых ограничения платформы:
- Тайм-аут 60 секунд: Это лимит времени обработки на стороне провайдера, а не жесткий лимит длины аудио. Однако на практике это означает, что длинные или несжатые записи могут превысить это время. Если у вас есть запись длительностью в час, ее необходимо разбить на сегменты (например, по 30-40 секунд), транскрибировать каждый отдельно, а затем склеить тексты. Обратите внимание: тайм-аут зависит от сложности обработки, а не только от длительности файла.
- Отсутствие поддержки URL: Вы не можете передать аудио по ссылке. Файл должен быть закодирован в base64 в JSON-теле запроса или передан через multipart/form-data. Максимальный размер для multipart — 25 МБ. Для файлов большего размера используйте base64.
- Нет вывода SRT/VTT: API не возвращает готовые файлы субтитров в форматах SRT или VTT. Запросы с
response_format: "srt"или"vtt"будут отклонены с ошибкой 400. Однако вы можете получить временные метки, используя форматverbose_json, и самостоятельно сгенерировать файл субтитров на основе этих данных. - Поддержка форматов: Хотя список поддерживаемых форматов широк, конкретный провайдер или модель могут не поддерживать все из них. WAV является самым безопасным выбором для совместимости.
Работа с временными метками
Если вам нужны субтитры, установите response_format: "verbose_json". Это вернет сегментные временные метки. Для получения меток на уровне слов добавьте параметр timestamp_granularities: ["word"]. Это создаст массив words с точными временными метками для каждого слова. Эта функция доступна только на провайдерах, совместимых с OpenAI (OpenAI, Groq, Together). Другие провайдеры могут отклонить этот формат с ошибкой 400.
08Что это значит на практике
Интеграция транскрипции через OpenRouter меняет подход к работе с голосовыми данными. Вместо создания сложной инфраструктуры с собственными серверами Whisper, вы получаете масштабируемое, многопровайдерное решение, которое работает в рамках единой системы аутентификации и биллинга.

Ключевые выводы для разработчиков:
- Простота интеграции: Используйте тот же API-ключ и структуру запросов, что и для чатов. Это снижает порог входа и упрощает поддержку кодовой базы.
- Гибкость выбора моделей: Доступ к множеству провайдеров позволяет выбирать между классическими Whisper-моделями (тарификация за секунды) и новыми STT-моделями (тарификация за токены) в зависимости от задачи и бюджета.
- Точный контроль затрат: Поле
usage.costв ответе позволяет внедрить точный учет расходов в реальном времени. Вы всегда знаете, сколько стоит каждый запрос. - Оптимизация под ограничения: Учитывайте 60-секундный тайм-аут для длинных записей и необходимость ручной генерации SRT/VTT из
verbose_json. Используйте сжатые форматы аудио для уменьшения размера полезной нагрузки. - Масштабируемость: Автоматическое балансирование нагрузки между провайдерами обеспечивает высокую доступность и отказоустойчивость вашего сервиса транскрипции.
Для начала работы зайдите в OpenRouter Playground, выберите модель из коллекции Speech-to-Text, загрузите тестовый файл и изучите структуру ответа. Затем интегрируйте вызов в свое приложение, используя примеры кода выше, и настройте мониторинг через поле usage.cost. Это позволит вам быстро запустить надежный сервис распознавания речи, сосредоточившись на бизнес-логике, а не на инфраструктурных сложностях.
09Часто задаваемые вопросы (FAQ)
Как транскрибировать аудиофайлы с помощью OpenRouter?
Отправьте аудио, закодированное в base64, на эндпоинт POST /api/v1/audio/transcriptions, указав модель и объект input_audio (с полями data и format). В ответе вы получите JSON с текстом транскрипции и объектом usage, содержащим метрики. Аутентификация осуществляется через тот же Bearer-ключ, что и для чатов.
Поддерживает ли OpenRouter Whisper?
Да, модели класса Whisper доступны для транскрипции. Используйте slug openai/whisper-1. Обратите внимание, что STT-модели не отображаются в стандартном каталоге, поэтому используйте фильтр ?output_modalities=transcription или просмотрите коллекцию "Speech-to-Text". Whisper тарифицируется по секундам, в то время как новые STT-модели — по токенам.
Какие форматы аудио поддерживает OpenRouter?
Поддерживаются: wav, mp3, flac, m4a, ogg, webm и aac. Указывайте формат в поле input_audio.format. Поддержка может варьироваться в зависимости от модели и провайдера, поэтому WAV является самым надежным выбором для совместимости, а MP3 обеспечивает меньший размер payload.
Может ли OpenRouter возвращать временные метки или субтитры SRT/VTT?
Временные метки — да. Установите response_format: "verbose_json" для получения сегментных меток и добавьте timestamp_granularities: ["word"] для меток на уровне слов. Это работает на провайдерах, совместимых с OpenAI (OpenAI, Groq, Together). Готовые файлы SRT/VTT не поддерживаются, поэтому их необходимо генерировать самостоятельно на основе полученных меток.
Какова максимальная длина аудио?
Практическое ограничение определяется тайм-аутом обработки провайдера (около 60 секунд), а не жестким лимитом длины файла. Короткие и средние записи обрабатываются за один запрос. Для длинных записей (например, часовых встреч) необходимо разбивать аудио на сегменты, транскрибировать каждый отдельно и затем объединять тексты.
Сколько стоит транскрипция в OpenRouter?
Вы платите тариф модели из каталога без наценки со стороны OpenRouter. Поле usage.cost в ответе показывает точную стоимость каждого запроса. Whisper-модели тарифицируются по секундам, новые STT-модели — по токенам. Транскрипция через API требует наличия баланса на вашем аккаунте.
Источник: OpenRouter ↗
