Console
API reference

Audio

Transcribe audio and generate speech.

POST/v1/audio

Turn speech into text, and text into speech. These routes follow the OpenAI Audio API, so client.audio.transcriptions.create and client.audio.speech.create work unchanged with the base URL https://demo-api.routerplus.com/v1.

RouteAliasWhat it does
POST /v1/audio/transcriptionsPOST /audio/transcriptionsReturns the text of an audio file
POST /v1/audio/speechPOST /audio/speechReturns spoken audio for a text, streamed as it is made

Examples

bash
curl https://dev2-api.routerplus.com/v1/audio/transcriptions \
  -H "Authorization: Bearer $ROUTERPLUS_API_KEY" \
  -F model=whisper-1 \
  -F response_format=srt \
  -F [email protected]
bash
curl https://dev2-api.routerplus.com/v1/audio/speech \
  -H "Authorization: Bearer $ROUTERPLUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "gpt-4o-mini-tts", "input": "Your order has shipped.", "voice": "coral"}' \
  --output speech.mp3
python
from openai import OpenAI

client = OpenAI(base_url="https://demo-api.routerplus.com/v1", api_key="tm_vk_...")

with open("meeting.mp3", "rb") as f:
    transcript = client.audio.transcriptions.create(model="gpt-4o-transcribe", file=f)
print(transcript.text)

with client.audio.speech.with_streaming_response.create(
    model="tts-1", voice="alloy", input="Your order has shipped."
) as response:
    response.stream_to_file("speech.mp3")

Send your key as Authorization: Bearer tm_vk_... or as x-api-key: tm_vk_.... A missing or invalid key returns 401.

Models

ModelRoutePriceBilled on
gpt-4o-transcribetranscriptions$2.50 per 1M input tokens, $10.00 per 1M output tokensusage.input_tokens and usage.output_tokens
gpt-4o-mini-transcribetranscriptions$1.25 per 1M input tokens, $5.00 per 1M output tokensusage.input_tokens and usage.output_tokens
whisper-1transcriptions$0.006 per minute ($0.0001 per second)seconds of audio, rounded up
gpt-4o-mini-ttsspeech$0.60 per 1M input tokens, $12.00 per 1M audio output tokensthe tokens the provider reports
tts-1speech$15.00 per 1M characterscharacters of input
tts-1-hdspeech$30.00 per 1M characterscharacters of input

OpenAI serves all six models. GET /v1/models?output_modalities=transcription lists the transcription models, and ?output_modalities=audio lists the speech models.

POST /v1/audio/transcriptions

Request

The body is multipart/form-data. The audio file is at most 25 MiB. A larger file is a 413. RouterPlus checks every rule below before it reserves money or calls a provider. A refused request has no ledger row and no charge.

FieldTypeBehavior
filefile, requiredThe audio: flac, mp3, mp4, mpeg, mpga, m4a, ogg, wav or webm.
modelstring, requiredA transcription model id. A speech, chat, image, video, decision or embeddings model is a 400 that names its own route. An id that is not in the catalog is a 404.
response_formatstringjson (the default), text, verbose_json, srt or vtt. gpt-4o-transcribe and gpt-4o-mini-transcribe take json and text only.
languagestringThe language of the audio as an ISO-639-1 code, for example en.
promptstringText that guides the style or spelling of the transcript.
temperaturenumberFrom 0 to 1.
timestamp_granularities[]stringsegment or word. With whisper-1 and verbose_json only.
providerJSON stringRouting controls. See Provider routing.

RouterPlus drops any other field and names it in the x-tm-dropped-params header. With provider.require_parameters: true, a dropped field is a 400. stream=true is a 400: the route returns one response.

Response

json:

json
{
  "text": "Hello there.",
  "usage": { "type": "tokens", "input_tokens": 1500, "output_tokens": 40, "total_tokens": 1540, "cost": 0.00415 }
}

whisper-1 reports the billed seconds:

json
{
  "text": "Hello there.",
  "usage": { "type": "duration", "seconds": 62, "cost": 0.0062 }
}
FormatContent typeBody
jsonapplication/jsontext and usage
verbose_jsonapplication/jsontext, language, duration, segments (and words when asked for), and usage
texttext/plainThe transcript
srttext/plainSubRip subtitles, one cue per segment
vtttext/vttWebVTT subtitles, one cue per segment

usage.cost is the charge in USD for the request. The text, srt and vtt formats do not carry it. GET /v1/generation shows it for every request.

POST /v1/audio/speech

Request

The body is JSON, at most 1 MB.

ParameterTypeBehavior
modelstring, requiredA speech model id.
inputstring, requiredThe text to speak. At most 4,096 characters.
voicestring, requiredA voice name, for example alloy, coral or nova.
response_formatstringmp3 (the default), opus, aac, flac, wav or pcm.
speednumberFrom 0.25 to 4. The default is 1.
instructionsstringHow to speak, for example "calm and slow". gpt-4o-mini-tts only. The tokens count as input. Another model drops the field.
stream_formatstringaudio only. Any other value is a 400.
providerobjectRouting controls. See Provider routing.

Response

The body is the audio file in response_format. RouterPlus sends each part of the audio when it arrives from the provider, so playback can start before the speech is complete.

FormatContent type
mp3audio/mpeg
opusaudio/opus
aacaudio/aac
flacaudio/flac
wavaudio/wav
pcmaudio/pcm (raw 24 kHz, 16-bit, mono samples)

The response does not carry the cost. GET /v1/generation shows it.

Billing

  1. 01
    Before the call, RouterPlus holds an estimate of the cost on your balance.
  2. 02
    After the call, it charges the billed units from the Models table and releases the rest of the hold.
  3. 03
    If the provider reports no usage, RouterPlus charges the estimate it held.

The hold for each model:

ModelHold
gpt-4o-transcribe, gpt-4o-mini-transcribe16,000 input tokens and 2,000 output tokens
whisper-1The length of the audio. For a wav or mp3 file, RouterPlus reads the length from the file. For another format, it assumes 1,000 bytes per second.
gpt-4o-mini-ttsThe input text at 3 bytes per token, and 2 audio tokens per character divided by speed
tts-1, tts-1-hdThe characters of input

A failed attempt costs nothing.

Routing and failover

RouterPlus picks the provider with the same rules as chat. Guardrails apply: a model your guardrail does not allow is a 403 with error_type: "guardrail_blocked".

If a provider fails before it answers (a 5xx, a 429 or a timeout), RouterPlus tries the next provider of the model. For speech, failover stops at the first byte of audio. After that byte, the answer comes from that provider. x-tm-attempts gives the number of attempts. x-tm-provider names the provider that answered.

For agents: /docs/api-audio.md and /llms.txt