02/Model Gateway

Audio

OpenAI-compatible gateway endpoints for text-to-speech (TTS) and speech-to-text (STT).


The gateway exposes three OpenAI-compatible audio endpoints, using the same model-group resolution and node selection as chat completions: text-to-speech and speech-to-text.

#Endpoints

EndpointWhat it does
POST /v1/audio/speechTTS — converts text to audio, returns audio bytes (default mp3).
POST /v1/audio/transcriptionsSTT — transcribes audio into text in the language it was spoken.
POST /v1/audio/translationsSTT — translates audio into English text, regardless of the source language.

Request/response shapes follow OpenAI's audio API: a JSON body for /speech (model, input, voice, response_format, speed); a multipart form for /transcriptions and /translations (file, model, optional language/response_format).

#Which nodes serve it

Audio nodes come from the regular node catalog: any node whose service_key maps to a service in the tts/stt/audio category of the AI-service catalog is an audio node. Added from the Nodes page by choosing "Custom Audio".

ServiceCategory
OpenAI Audioaudio — both TTS and STT.
Groq Audioaudio — both TTS and STT.
Deepgramstt.
AssemblyAIstt.
ElevenLabstts — translated to a native API (see below).
Cartesiatts.
Fish Audiotts.
Custom Audioaudio — a custom host for any OpenAI-compatible TTS/STT endpoint.

#Model selection and groups

When an audio request arrives, the model name is resolved through the same model-group resolution used by chat completions, then routed to a node with the same node-selection logic (health/priority/weight). A TTS or STT model can therefore be a model-group member and get failover/load balancing.

See the Nodes page for node-selection logic and Models & Groups for model groups.

#Adding models (by hand)

Audio APIs typically don't serve a /models endpoint, so models on audio nodes are added/removed by hand on the Audio page; a model_mapping is created so the gateway can route to it, and the model row is marked metadata_locked so a later model sync won't overwrite this hand-entered data.

The model's tts/stt capability is not derived automatically: in the Add Model dialog the admin picks a Type (TTS / STT / Both, defaulting to TTS), which is written into the capabilities field. But the Type isn't constrained to the node's own category — pick one that doesn't match it (e.g. STT on a tts-category node) and the backend adds the node's own category tag alongside your choice, so the model ends up with both capabilities. This can't happen on the audio-category services (OpenAI Audio, Groq Audio, Custom Audio) — the fallback only checks for tts/stt.

TTS models can carry a list of voices — each with an id/label and a default flag, editable from the panel. When a test request doesn't specify a voice, the model's default voice (or, failing that, the first voice in the list) is used.

#Provider translation: the ElevenLabs example

ElevenLabs does not offer an OpenAI-compatible /v1/audio/speech — it has its own native API (POST /v1/text-to-speech/{voice_id}). A /v1/audio/speech request routed to a node on this service is translated by the gateway into that native shape: the request's model maps to ElevenLabs' model_id field, and voice maps to voice_id.

Every other audio service speaks OpenAI's /v1/audio/speech and /v1/audio/transcriptions shape directly; provider translation only happens for ElevenLabs.
Model access and user limits (requests/tokens) go through the same mechanism as chat completions — a request to a model the user can't access returns 403, exceeding a limit returns 429.