Developers working on speech transcription have long been troubled by a sense of fragmentation: chat with OpenRouter, but transcribe with another Whisper server, or integrate with a third-party SDK for audio-to-text. On July 22, OpenRouter smoothed this gap — it launched the POST /api/v1/audio/transcriptions endpoint on its platform, allowing users to send base64-encoded audio with the same Bearer key used for Chat Completions and receive a JSON response containing the transcribed text and usage details. Chat and transcription now share one ticket.

The core of this convenience is reuse. You don't need a new SDK or separate service, as the transcription feature runs on the same platform as chat traffic, with models from multiple providers automatically load balancing between each other rather than being locked into a single vendor. For teams that already use OpenRouter as their main platform, this integration means fewer maintenance steps and fewer keys to remember.

image.png

On the model side, OpenRouter offers two approaches. One is Whisper-like models such as openai/whisper-1, billed by audio duration, i.e., per second; the other is newer speech-to-text (STT) models, billed by tokens. It's worth noting that STT model IDs won't appear in the default /api/v1/models directory, as they belong to an output modality requiring active filtering — through the ?output_modalities=transcription parameter, you can filter out these models and their current pricing. If you want to try before integrating, the OpenRouter Playground also allows direct file upload and transcription within the browser.

The call method is simple enough to close the loop in one request. Encode the file in base64, POST it along with the model and format, then read the text and usage fields from the response. The data field takes raw base64 bytes, not a data: URI, so don't add the data:audio/mp3;base64 prefix; the format field is required to tell the upstream model how to decode these bytes. If you already have a client written for OpenAI's /v1/audio/transcriptions, simply point the base URL to https://openrouter.ai/api/v1 to use it directly with zero changes. The endpoint also accepts OpenAI-style multipart/form-data uploads, with files and models, up to a 25MB limit.

Regarding field specifications, model, input_audio.data, and input_audio.format are required fields. The format can be one of wav, mp3, flac, m4a, ogg, webm, or aac; language is an ISO-639-1 language code, which will be detected automatically if omitted; temperature controls sampling, with values ranging from 0 to 1; response_format defaults to json, and setting it to verbose_json gives additional information about the task, language, duration, and segment timestamps. With timestamp_granularities set to word, you can even get word-level timestamps. However, these features are only available on providers compatible with OpenAI, such as OpenAI, Groq, and Together, while other providers will return a 400 error directly. The provider block is used to pass through each provider's private parameters, for example, Groq can pass expected vocabulary via provider.options.groq.prompt to help the model correctly handle proper nouns, avoiding mispronouncing technical terms.

The response is a JSON object, with the text string containing the transcription result, and the usage object allowing costs to be measured by request rather than estimated. In an example, a 9.2-second audio produced 113 tokens, 83 inputs, and 30 outputs, with a cost of $0.000508 — this number comes from the document example, not an actual quote, and the real cost depends on the selected model and audio length. The response header also includes an X-Generation-Id, which helps you record and track a specific request.

The routing logic follows the same system as chat. When a transcription model is hosted by multiple providers, OpenRouter performs load balancing based on price, distributing requests among them to avoid being tied to a single vendor. However, the transcription endpoint currently does not support route control per request. Fields like order, only, allow_fallbacks, data_collection, and sort, familiar in chat calls, do not work here. The provider block only carries provider-specific options. OpenRouter explicitly does not mark up provider pricing, and the listed price is your actual payment price. The zero-fallback insurance means that failed transcriptions will not be charged; if you have your own provider agreement, the BYOK feature allows using your own keys for routing, paying only the platform fee and eliminating the variable model cost. Additionally, the platform fee for the first 1 million requests per month is waived under the variable billing model.

Before actually building, there are four constraints that must be considered in the architecture. First, a 60-second upstream timeout — this refers to processing time, not audio length, so large or uncompressed recordings may time out; long audio should be split into segments and the text concatenated. Second, audio URLs are not supported; the endpoint only accepts base64 JSON or OpenAI-style multipart files not exceeding 25MB. Third, SRT/VTT format outputs are not supported; srt, vtt, and text will be rejected with a 400 error, and timestamps can only be obtained via verbose_json, with subtitles needing to be manually assembled using timestamps. Fourth, format support varies by provider, with wav being the most compatible safe default, while compressed formats like mp3 can generate smaller and faster payloads. A recording lasting several hours, like a night-long gaming session, cannot be handled in a single call and must be processed in chunks.

Finally, putting transcription in the right place. When you just need to convert audio into text, use /audio/transcriptions; when you want the model to reason about the audio content, such as sentiment analysis of customer service calls, answering questions about audio, or combining audio with other modalities in the same prompt, use the input_audio content type in /chat/completions. Text-to-speech is a third independent endpoint. OpenRouter's comparison is straightforward: for a transcription, go to the transcription endpoint to get JSON text and usage; for a model that understands audio, go to chat completion to get a single conversation result. With one key covering both conversations and sound, the barrier for implementing voice capabilities in applications has been quietly lowered again.