Skip to main content
A voice configuration takes one of two shapes. Never both.

Composed

Three named provider/model pairs, wired together for you:
All three stages are required. Defaulting a missing one would silently bill you for a model you never chose. Which models you can name, why they must come from one family, and what each costs is on Compose a voice engine.

Realtime

One model that does the whole conversation (audio in, audio out, with the reasoning inside the provider):
These two shapes are mutually exclusive. A realtime model has no separate speech-to-text step to name, so asking you to supply one would mean inventing model ids that do not exist.

What a call costs

Prices are per connected minute at typical speech rates, including the flat $0.012 orchestration fee. Telephony is not included and not marked up: calls run over your own SIP trunk. The table is generated from the same price book the meter bills against, so it cannot drift from what you are actually charged.

The voice your caller hears

voice on the tts block (composed engines) or on realtime (realtime engines) is the speaker: the actual voice, not the model that drives it. Omit it and the engine uses its own default, which is rarely the one you want in production. Each engine draws from a different roster, so a voice id is only meaningful alongside its engine: An id from the wrong roster is refused when the agent is created, with the valid ones listed. It is the same rule as an unpriced model, and for the same reason: discovering it on your customer’s call is far worse. To make an agent speak in a voice cloned from your own recordings, see Voice cloning. An ElevenLabs clone speaks on classic and deepgram_agent, and a Sarvam clone on sarvam. Gemini Live cannot speak in a cloned voice.

Discovering what is available

Three endpoints, so you never have to hardcode any of this:
GET /v1/engines is the list to check before hardcoding model ids: an engine whose provider is degraded disappears from it before your calls start failing, which turns a runtime outage into a visible capability change. GET /v1/engines/{engine}/languages answers what the engine can actually hold a conversation in. For a composed engine that is the intersection of its two speech stages: a language your speech-to-text transcribes but your text-to-speech cannot say back is not one the engine supports end to end, and listing it would be a promise the pipeline cannot keep. Each entry names the components that serve it:
Regional variants of a listed code are accepted, so en-GB works wherever en is listed. multi (composed engines) and auto (Gemini) are modes rather than languages: they detect the caller’s language instead of pinning one. GET /v1/engines/{engine}/voices answers who it can speak as. Sarvam and Gemini publish fixed rosters; the ElevenLabs-backed engines are fetched from ElevenLabs and cached. Your own cloned voices, made with POST /v1/voices, are listed first, with "category": "cloned", on the engines that can speak them. No other account’s clones appear.
If the voice list comes back with "stale": true, the provider could not be reached and you are seeing the last list that was fetched, with refreshed_at saying when. The endpoint prefers a slightly old answer to an error: a provider outage should not break your voice picker.
A listed engine always answers both endpoints, even when available is false. That is deliberate: you still need the lists to render a picker while a provider is degraded.

Turn taking

interrupt_sensitivity governs how readily the agent stops talking when your caller speaks. high makes it deferential and easy to talk over; low makes it finish its sentence. Short acknowledgements like “yes” or “mm-hm” never interrupt at any setting; they are queued and answered when the agent finishes.