Skip to main content

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 wavaudio/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.
The bracketed timestamp_granularities[] form key is canonical, but GoModel also accepts the unbracketed timestamp_granularities for client compatibility.

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 with per_character_input, as tts-1 is billed) and the duration of the synthesized audio (audio_output_seconds, priced with per_second_output, as gpt-4o-mini-tts is billed). Duration is measured from the returned wav, pcm, or mp3; 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 with per_second_input). GoModel takes the duration the provider reports in usage.seconds or verbose_json’s duration, and otherwise measures the upload itself — so the cost does not depend on the response_format the client asked for, and providers that report no usage at all (Groq, ElevenLabs) are still metered.
  • Token-billed transcription models (gpt-4o-transcribe and similar) report token usage and are priced with input_per_mtok / output_per_mtok instead. A model that publishes both a token rate and a per-second rate is billed by whichever unit the provider reported, never both.
When nothing billable is available — the provider reported no usage and the upload is in a container GoModel cannot measure (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.
For a provider whose native audio API differs from OpenAI’s, use the passthrough API (/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/speech stores its text input and the generated audio (base64, capped at 8 MB) so the dashboard renders an inline player, and /v1/audio/transcriptions stores the uploaded audio (base64, capped at 8 MB, also playable in the dashboard) alongside the upload metadata (filename, model, params).
Last modified on September 12, 2026