Speech to text

Turn speech in an audio file into text with the flux-voice models, from your agent through the Flux tools server or from your own code, on the same Flux key as your chat requests.

Send an audio file and get the words back as text. Transcription runs on the same Flux key and base URL (https://api.fluxrouter.ai/v1) as your chat requests, and it lands on the same bill.

Way inStatus
API: POST /v1/audio/transcriptionsLive
Flux tools server: the transcribe toolShipping

The endpoint is OpenAI-compatible, so if your code already calls an OpenAI-compatible transcription endpoint, moving to Flux is a base URL and key change. Transcription needs a paid plan; see What it costs.

Pick a model id

Set model to one of three ids. Leave it out and you get flux-voice.

Model idWhat it does
flux-voiceThe default. Picks per clip: it favours accuracy for clips of 10 seconds or less, and speed for longer ones.
flux-voice-accurateAlways favours accuracy.
flux-voice-fastAlways favours speed.

flux-voice never transcribes worse than flux-voice-accurate on short clips; it only decides when speed is worth more. Pin one of the other two only when you have a reason, such as a latency budget. The price is the same whichever serves.

A model id the endpoint does not know is treated as flux-voice, not refused. That keeps SDKs that send another provider's model id working, but it also means a typo silently gets the default. The x-flux-routed-model response header always names the id that actually served.

From your agent

Add the Flux tools server to your agent once, then ask it to transcribe. The tool is called transcribe.

Built into Murage, which decides which abilities it uses. Nothing to set up here. See murage.ai.

The tool takes exactly one of these:

  • audio_url: a public https:// address. Flux downloads it for you, following up to 3 redirects. Private, local and plain http:// addresses are refused.
  • audio_base64: the file itself, base64-encoded, with an optional filename. Use this for a file on your own machine.

It also takes an optional language and prompt, the same as the API. It returns text, billed_seconds and cost_usd. The file limit is 8 MB either way.

From code

Send the file as multipart/form-data with a file field. OpenAI-compatible SDKs do this for you through their audio transcription method.

bash
curl https://api.fluxrouter.ai/v1/audio/transcriptions \
  -H "Authorization: Bearer sk-YOUR-FLUX-KEY" \
  -F "file=@meeting.m4a" \
  -F "model=flux-voice"

The full list of request fields and the exact response shapes are in the endpoint reference.

Response formats and timestamps

Choose the shape of the answer with response_format:

  • json (the default): {"text": "..."}.
  • text: the transcript as a plain text body, not JSON.
  • verbose_json: text plus task, language, duration and segments, each segment with its start and end time.

For word-level timestamps, send response_format=verbose_json with timestamp_granularities[]=word. The response then adds a words list, which helps with captions, cursor placement in dictation apps and word-level editing.

bash
curl https://api.fluxrouter.ai/v1/audio/transcriptions \
  -H "Authorization: Bearer $FLUX_API_KEY" \
  -F "file=@note.ogg" \
  -F "model=flux-voice" \
  -F "response_format=verbose_json" \
  -F "timestamp_granularities[]=word"

Subtitle formats (srt, vtt) are not offered, and there is no streaming: the whole transcript comes back in one response. Build subtitles from the verbose_json segments instead.

Languages

Transcription handles most major languages and detects the language by itself. Pass language with an ISO-639-1 code (for example en or de) to pin one, which helps with short clips and mixed-language audio. verbose_json reports the language it heard.

To help with names, jargon or spellings, pass a short prompt, such as a list of product names. Prompts longer than 2,000 characters are cut to that length.

Audio formats

Flux reads the format from the file's contents, not its name or extension. It accepts wav, mp3, mp4 and m4a, ogg (including Opus), webm and flac. A file that is not one of these is refused with 400 unsupported_file_format before anything is billed.

For audio recorded in a browser, the default webm or an ogg/Opus recording works as it is. There is no need to convert it.

Limits

  • File size: up to 8 MB a request. Larger files get 413 file_too_large. Split long recordings into parts.
  • Time: a transcription that takes longer than 60 seconds ends with a 504, and you are not charged.
  • Rate: up to 60 requests a minute per account, shared with speech and search, and an hourly audio budget of 36,000 seconds of audio an hour, shared with speech. Over either, you get 429; wait and retry.

What it costs

Transcription is billed per second of audio, rounded up, with a minimum of 10 seconds a file. Price: $0.10 per minute heard. It rolls up to the same bill as the rest of your Flux usage.

Every successful response carries its receipt in the headers:

HeaderMeaning
x-flux-routed-modelThe model id that served: flux-voice, flux-voice-accurate or flux-voice-fast
x-flux-billed-secondsThe seconds you were billed for
x-flux-cost-usdWhat this request cost, in US dollars

The live price for each model id is on GET /v1/models, in the list_price_microcents and min_billed_units fields of the flux-voice rows. See How billing works.

A key without a paid plan gets 402 with code premium_locked, and nothing is sent for transcription or billed. A 401 means the key itself was not accepted. Handle the two separately in a client: a 402 is a prompt to upgrade, not a broken key. See Plans.

Next