Speech-to-text

Buy a transcript of an audio file. The endpoint has the shape of the OpenAI transcriptions API, so an unchanged OpenAI client works. It also reads the JSON form that OpenRouter uses.

Only a deployment that is registered to transcribe can win the job. A chat deployment never wins one.

This job is not the same as Audio input. Audio input sends a clip to a chat model that can hear. This job returns the words of the clip.

Quickstart

curl https://router.inference.ai.exchange/v1/audio/transcriptions \
  -H "Authorization: Bearer sk-liquid-..." \
  -F model=whisper-1 \
  -F [email protected] \
  -F response_format=verbose_json
from openai import OpenAI

client = OpenAI(base_url="https://router.inference.ai.exchange/v1", api_key="sk-liquid-...")

with open("meeting.mp3", "rb") as audio:
    transcript = client.audio.transcriptions.create(model="whisper-1", file=audio)
print(transcript.text)

Find a model

A control works only when an offer for the model declares it. Read the model card before you send diarize or keyterms.

See Modalities. If no offer declared a control that you sent, the answer is 400 unsupported_parameter, and param names the feature, such as transcription.diarize.

Controls

diarize and keyterms are offer features. language, timestamp_granularities and the audio limits are matched against what an offer registered.

Speakers and key terms

diarize and keyterms are offer features: transcription.diarize and transcription.keyterms. Only an offer that declared the feature can win a request that sets the field.

curl https://router.inference.ai.exchange/v1/audio/transcriptions \
  -H "Authorization: Bearer sk-liquid-..." \
  -F model=<model> \
  -F [email protected] \
  -F response_format=verbose_json \
  -F diarize=true \
  -F 'keyterms[]=Liquid Inference' \
  -F 'keyterms[]=nano-USD'

Send an https:// link in url and the exchange fetches the file.

{
  "model": "<model>",
  "input_references": [{ "type": "audio", "url": "https://example.com/call.wav" }]
}

Audio limits

The exchange reads WAV, FLAC, MP3, Ogg, WebM, M4A and AAC from the bytes of the file. It does not trust the name or the format field.

Response

json returns the text, the usage and the exchange block.

{
  "text": "Welcome to the meeting.",
  "usage": { "type": "duration", "seconds": 4 },
  "exchange": { "...": "..." }
}

verbose_json adds language, duration (the seconds that the exchange measured), segments and words. A segment or a word is present only when you asked for that granularity. A segment has id, start, end and text, and a speaker with diarize.

{ "id": 0, "start": 0.0, "end": 3.4, "text": "Welcome to the meeting.", "speaker": "speaker_0" }

text returns plain text. Its exchange block comes back as JSON in the x-liquid-exchange response header.

Billing

The price is for each second of audio. The exchange reads the length from the file, so the cap is known before dispatch. It is exactly the most that you can pay.

The provider meters the seconds that it worked on. You pay that figure, never more than the cap.

Request parameters

Send multipart/form-data with the audio in file, or JSON with the audio in input_references.

Field Type Required Description
model string Yes The model to buy, or a preset of the transcription kind.
file file Yes* The audio, in a form body.
input_references array Yes* One entry of type audio: a data:audio/ URL or an https:// link in url, or base64 in data and media_type.
response_format string No json (the default), text or verbose_json. srt and vtt are not supported.
timestamp_granularities array No segment, word or both. Only with verbose_json. An offer that cannot return them cannot win.
diarize boolean No Label each segment with its speaker. Needs verbose_json.
keyterms array No Up to 100 words or names, each up to 100 characters, that the transcript must spell as given.
language string No An ISO 639-1 code such as en. An offer that declared its languages must list it.
prompt string No A hint of vocabulary or style. At most 2,048 characters.
temperature number No From 0 to 1.
exchange object No Purchasing rules, such as cap_usd. See Purchasing rules.

* Send file or input_references. Send one audio entry only.

stream is not supported. The transcript comes whole.

Errors

Error Cause Fix
400 No audio, a file that is too large or too long, or a length that the exchange cannot read. Send a supported container under 25 MB and two hours.
400 unsupported_model The model is not a transcription model. Pick a model that lists audio input and a transcript output.
400 unsupported_parameter No offer serves your language, format or granularity, or none declared a control. Read parameters on the model card, or eligibility.excluded.

Next steps