The voice lives on config.tts — one provider, one model, one voice id from that provider’s roster. Browse the roster with GET /v1/catalog/voices before you write an id, because every provider names its voices differently and a wrong id fails at synthesis time, on a live call. Speech-to-speech agents pick a voice too, on config.realtime instead of config.tts. Everything below about browsing applies; the settings differ, and are called out where they do.

The tts object

string
default:"sarvam"
A text-to-speech provider from GET /v1/catalogelevenlabs, deepgram, openai, sarvam, raya, soniox or xai.
string
default:"bulbul:v3"
A model that provider offers, such as eleven_flash_v2_5. The provider/model pair must appear in the catalog and must list voice (or video) among its channels, or the write is refused.
string | null
The voice id, as GET /v1/catalog/voices returns it. null falls back to that model’s catalog default_voice.
string | null
A display label for the dashboard. It is stored and shown, never sent to the provider — the id is what speaks.
number
default:"1.0"
Speaking rate. The field accepts 0.5–2.0, and then the model’s own range applies on top: publishing 1.4 on a model that stops at 1.2 is refused. Models that declare no speed control accept 1.0 and nothing else.
number | null
ElevenLabs only, 0.0–1.0. The picked voice’s own value — see the ElevenLabs step. Setting it on any other model is refused.
number | null
ElevenLabs only, 0.0–1.0, and the same story as stability.
boolean
default:"false"
Lets the agent write delivery tags into its own speech. Only on models that declare a tag dialect — see expressive delivery.
object | null
A second provider/model to switch to mid-call if the first starts failing. It carries its own voice, speed and voice settings. See model fallbacks.
There is no language on tts. The agent carries one language for the whole pipeline — see language.

Browsing voices

GET /v1/catalog/voices takes a provider and returns that provider’s roster plus the filter options it supports. model scopes the list where a provider’s voices belong to one model; search matches free text against a voice’s name, id and description and works on every provider; language, accent and gender narrow it further where the provider has them.
Each voice carries id, name and whatever attributes the provider publishes: gender, language, accent, country, locale, description, sample_url (an audio preview), image_url, tier and owner_id. Only id goes on the agent. The response also echoes back the facets that provider actually has — languages, accents, genders. An empty list means that provider exposes no such filter, not that nothing matched. accents stays empty until you pick a language, because an accent only means something inside one.
If your workspace has a provider key saved for the provider, the listing runs on your key and workspace_key comes back true — for ElevenLabs that means your own account’s voices lead the first page. Without a key you see the provider’s public roster.

What each provider offers

Raya and Soniox voices belong to exactly one model — a Raya m1 voice is rejected by standard, and vice versa — so pass the model you are going to run or the picker will offer ids that fail at synthesis. Deepgram is a special case: the voice id is the Deepgram model string (aura-2-thalia-en), and the language is baked into it. aura-2 and aura-1 on the agent are the billing ids; the voice decides what is spoken and in which language. For a speech-to-speech agent, add kind=realtime. Those models have their own voice rosters — OpenAI’s realtime models offer 10 of the 13 OpenAI TTS voices, and Gemini Live offers 30 of its own.

Speed

speed is clamped by the model, not by the field. Ask for something outside the range and the write is refused with the range in the message (TTS speed for 'elevenlabs/eleven_flash_v2_5' must be between 0.8 and 1.2). Eleven v3 expresses pace through delivery tags rather than a speed parameter, which is why it takes no speed at all.

ElevenLabs voices need a second call

An ElevenLabs voice set without stability and similarity_boost does not speak in its author’s tuning. It speaks in ElevenLabs’ generic default, on every call, with nothing anywhere to say why.
ElevenLabs applies a voice’s own settings only to a request that carries no overrides at all. Talqing always sends a speed, so a voice_settings object is always on the wire — and any key that object omits falls back to ElevenLabs’ global default (stability 0.5, similarity boost 0.75), never to the voice’s own. There is no way to inherit one field and override another. So the two numbers have to travel with the agent. Read them once, when you pick the voice, and store them on the same tts object.
1

Find the voice

GET /v1/catalog/voices?provider=elevenlabs. A voice already in your workspace’s ElevenLabs account comes back with no owner_id — use its id directly and skip the next step. A shared-library voice carries an owner_id.
2

Save a shared-library voice

POST /v1/catalog/voices/elevenlabs/add with the voice’s voice_id and owner_id. It is saved into your workspace’s own ElevenLabs account and the response returns the id to use from here on — which may differ from the library id. An agent on your key cannot synthesize with a voice that is not in your account.
3

Read the voice's settings

GET /v1/catalog/voices/elevenlabs/{voice_id}/settings, with the id the previous step returned. It answers { "stability": …, "similarity_boost": … }. Called with a library id that was never saved, it returns 404 telling you to save it first.
4

Write both onto the agent

Set tts.voice, tts.stability and tts.similarity_boost together, and publish.
The dashboard’s voice picker does all four steps when you click a voice. It is only over the API that you have to sequence them yourself.
stability and similarity_boost may legitimately come back null — that means the voice stores no override of its own, and leaving them unset on the agent is then exactly right.

The settings belong to that voice, not to the agent

They describe one voice’s tuning and mean nothing on another. Two rules follow:
  • Change the voice, re-read the settings. Carrying one voice’s numbers onto another is worse than having none.
  • Change to a model that has no such setting, and clear them. Publishing stability on, say, sarvam/bulbul:v3 is refused outright: text-to-speech model 'sarvam/bulbul:v3' has no stability setting - clear it, or pick one of: elevenlabs/eleven_turbo_v2_5, elevenlabs/eleven_flash_v2_5, elevenlabs/eleven_v3. It fails at publish rather than being dropped silently, because a setting that quietly does nothing is the failure this whole step exists to prevent.
A fallback voice carries its own stability and similarity_boost and is checked the same way.

Reference: text-to-speech models

supports_voice_settings is the catalog flag that decides whether stability and similarity_boost are allowed at all. Only ElevenLabs sets it. Every entry above runs on voice and video. Most are priced per character; openai/gpt-4o-mini-tts bills text input and audio output tokens instead. All of it goes to your own provider key — see costs.

Next

Expressive delivery

Let the agent write laughs, whispers and pauses into what it says.

Language

One setting, every model, and what Auto really means.

Model fallbacks

A second voice for when the first provider stops answering.