voice configuration takes one of two shapes. Never both.
Composed
Three namedprovider/model pairs, wired together for you:
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:
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.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.
