Overview
GoModel exposes the OpenAI-compatible audio endpoints for text-to-speech (TTS) and speech-to-text (STT). Clients and SDKs that already call OpenAI’s/v1/audio/* routes can point at GoModel unchanged.
Requests route by model through the same registry used for chat and
embeddings, so model selection, provider hints, virtual models, per-key model
access rules (user paths), and budgets all apply. Audio is
served by OpenAI and the OpenAI-compatible providers (OpenRouter, Azure OpenAI,
vLLM, Oracle, Z.ai), plus providers whose native audio APIs GoModel translates
behind the same endpoints: Xiaomi MiMo (TTS and ASR via chat
completions), Cohere (transcription), and
MiniMax (TTS via its native t2a_v2 API). A provider that
doesn’t support audio returns a clear error rather than mis-routing.
Supported endpoints
JSON transcription and translation bodies are normalized to the OpenAI shape:
Groq’s vendor
x_groq member is removed from json and verbose_json
responses, so a client written against OpenAI sees the same fields everywhere.
Text-to-speech
model, input, and voice are required. Optional fields — instructions,
response_format (mp3 default, plus opus, aac, flac, wav, pcm), and
speed — are forwarded to the provider. The response Content-Type is derived
from response_format (for example wav → audio/wav).
Speech-to-text
file and model are required. Optional form fields — language, prompt,
response_format, temperature, and timestamp_granularities[] — are forwarded.
response_format controls the response shape: json and verbose_json return a
JSON object; text, srt, and vtt return a text/plain body.
Cost tracking
Every/v1/audio/* call is recorded in usage tracking
under its own endpoint path. Audio models are priced by the unit the provider
bills, not by tokens:
- Speech (
/v1/audio/speech) records the input character count (input_characters, priced withper_character_input, astts-1is billed) and the duration of the synthesized audio (audio_output_seconds, priced withper_second_output, asgpt-4o-mini-ttsis billed). Duration is measured from the returnedwav,pcm, ormp3; other codecs (opus,aac,flac) cannot be measured without decoding, and the row carries a cost caveat saying so. - Transcriptions and translations are priced by the duration of the uploaded
audio (
audio_seconds, priced withper_second_input). GoModel takes the duration the provider reports inusage.secondsorverbose_json’sduration, and otherwise measures the upload itself — so the cost does not depend on theresponse_formatthe client asked for, and providers that report no usage at all (Groq, ElevenLabs) are still metered. - Token-billed transcription models (
gpt-4o-transcribeand similar) report tokenusageand are priced withinput_per_mtok/output_per_mtokinstead. A model that publishes both a token rate and a per-second rate is billed by whichever unit the provider reported, never both.
m4a, ogg, flac, webm) —
the usage row is flagged with a cost-calculation caveat instead of a $0 cost.
Limitations
The audio endpoints are a thin, model-routed pass to the provider and do not run through the full inference orchestrator. Compared with/v1/chat/completions:
- No failover, guardrails, or response cache — these stages are skipped.
Requests are still authorized, budget-checked, metered (see
cost tracking), and written to the
audit log under their
/v1/audio/*path. - OpenAI request shape in, provider dialect out — clients always send OpenAI’s audio format. OpenAI-compatible upstreams receive it unchanged; Xiaomi MiMo, Cohere, and MiniMax requests are translated to each provider’s native audio contract. Providers beyond those are not adapted behind this endpoint.
- Realtime voice-to-voice (the WebSocket realtime API) is not supported.
/p/{provider}/v1/audio/...) to
forward bytes verbatim to that upstream.
Audit logging
Audio requests appear in the audit log like any other model interaction. Because audio payloads are binary and large, their bodies are gated by a dedicated setting,LOGGING_LOG_AUDIO_BODIES
(default false), which refines LOGGING_LOG_BODIES — it has no effect
unless body logging is enabled:
- Body logging off (
LOGGING_LOG_BODIES=false) — no audio body is stored, regardless of this setting. - Body logging on, audio off (the default) — the audio response is recorded
as a lightweight
{__audio__, content_type, bytes, stored: false}placeholder; no audio bytes are stored. - Body logging on, audio on —
/v1/audio/speechstores its text input and the generated audio (base64, capped at 8 MB) so the dashboard renders an inline player, and/v1/audio/transcriptionsstores the uploaded audio (base64, capped at 8 MB, also playable in the dashboard) alongside the upload metadata (filename, model, params).