Audio
Three endpoints in OpenAI's shape. The model is <provider>/<model>, for example
openai/tts-1, openai/whisper-1 or openrouter/openai/whisper-large-v3-turbo.
| Endpoint | Unit | Providers |
|---|---|---|
POST /v1/audio/speech | 1,000 input characters | openai, openrouter, together, nanogpt, pollinations |
POST /v1/audio/transcriptions | minute of audio | openai, groq, openrouter |
POST /v1/audio/translations | minute of audio | openai, groq |
1curl https://api.aile.sh/v1/audio/speech \2-H "Authorization: Bearer $AILE_KEY" \3-H "Content-Type: application/json" \4-d '{ "model": "openai/tts-1", "voice": "alloy", "input": "Hello from Aile." }' \5--output hello.mp367curl https://api.aile.sh/v1/audio/transcriptions \8-H "Authorization: Bearer $AILE_KEY" \9-F model=openai/whisper-1 \10-F [email protected]
Speech
inputis up to 4,096 characters.stream_format: "audio"streams the audio as it is made.stream_format: "sse"answers onespeech.audio.deltaand aspeech.audio.doneonce the audio is finished.stream: trueis a400. Usestream_format.- OpenRouter speech models take
response_formatmp3(the default) orpcm.
Transcription and translation
- Upload is
multipart/form-data, up to 25 MB. OpenRouter's JSON body (input_audio: { data, format }) is accepted too. response_formatisjson(the default),text,verbose_json,srtorvtt. A model that returns onlyjsonstill answersverbose_json, with no segments, and refusestimestamp_granularities[]=word.stream: truereturns the finished transcript astranscript.text.deltaandtranscript.text.doneevents.- A JSON answer's
usageis{ "type": "duration", "seconds": … }, the reported length.
Billing
- Speech bills its input characters. A stream is billed in full once any audio reaches you, and not at all if the provider fails mid-stream.
- Transcription holds an estimate from the upload's size and bills the duration the provider reports, up to the hold.
- A response with no audio, or a transcript with no duration, is a
502and is not charged. - A call with no answer by the deployment's buffered deadline (at most 120 seconds) is voided with a
504. For transcription, the upload's time counts. - A
502or504arrives as503with the real code inx-aile-status. - A provider refusal you can fix (
400,404,413,422…) passes through. One about the lender's account is a502saying you were not charged. - A key's pins and the routing headers choose the lender here too.
x-aile-providermust match the model's prefix, andx-aile-max-pricedoes not apply to a per-character or per-minute price. - Where the deployment enables it, speech also takes keyless x402, buffered only (
stream_format: "audio"needs a key). Transcription and translation need an API key. - Audio is sent to the provider as uploaded. Aile does not inspect it.