Skip to main content
Every voice is named by its voice ID: the voice_id parameter on a WebSocket session and on an HTTP request, voice_id in the Python SDK’s TTSConfig, and voiceId on a JavaScript SDK session (voice_id in its HTTP requests, which take the API’s field names). It takes one of these:
  • The library slug of an AssemblyAI voice, such as aai-jane.
  • A voice’s ID, a UUID such as 49c443a4-8a1d-5f7e-b70b-98bdbd9823c3.
  • The slug of one of your account’s voices, such as a voice you cloned in the AssemblyAI dashboard.
Leave voice_id out and you get aai-jane, the default voice, which speaks English. For text in another language, name a voice recorded in that language.
The SDK reads your API key from ASSEMBLYAI_API_KEY, or from aai.settings.api_key.
The session or request echoes the voice it speaks with: Begin.configuration.voice_id on a session, which the SDKs expose on the Begin event, and the X-TTS-Voice-Id header on an HTTP response, which the SDKs expose on the result. It is the value you sent, or aai-jane when you sent none. On a session, Begin.configuration.resolved_voice.voice_id gives the voice’s UUID, also when you named it by slug.

AssemblyAI voices

The voice catalog in the AssemblyAI dashboard holds thousands of voices across the six languages the model speaks. Browse it there, listen to each voice, and copy its voice_id with Copy voice ID; the text-to-speech playground has the same action, which copies the voice_id its session sends. AssemblyAI’s voices carry slugs that begin with aai-. Each voice speaks one language, the language it was recorded in, so pick a voice in the language of your text. These are good voices to start with. The examples on these pages use Audrey: A voice you clone likewise speaks only the language of its recording.

Voice and language

language defaults to english, and it decides which model the session runs on: the default model of that language in the region, assemblyai-tts-1 for all six languages. Each voice speaks one language, the language it was recorded in, so set language to the language of the text you send and name a voice recorded in it, such as Constanza for Mexican Spanish.
With a cloned voice, leave language out and the session speaks the voice’s language; another language closes the session with 3006 before Begin. See Language and model. language takes the full English name of the language, such as spanish, not a code such as es. This differs from the STT APIs, which take short language codes such as es or en_us. The OpenAI-compatible route and the LiveKit plugin accept an ISO 639-1 code such as es as well.
The API does not detect language. Set language to the language of your text: with an AssemblyAI voice it is english unless you set it, whatever language the text is in.

Languages

language takes one of these values: A session speaks a language only where a model of the region speaks it. Both data zones serve all six languages on one model, assemblyai-tts-1, the default model of each of them, and Begin.configuration.model names the model a session runs on. A language outside this table closes the session with 3006 before Begin, with error_type invalid_parameter and param language, and the text lists the supported values. A supported language that no model of the region speaks closes with 3006, error_type invalid_request, param language and the text No voice model serves language <language> in this region.

What a wrong voice looks like

The server checks the voice when the session opens. A voice it cannot use never gets Begin: an Error frame arrives in its place, and the socket closes with the frame’s error_code. The Python SDK raises it as TTSError from the with block, the JavaScript SDK rejects connect() with a TextToSpeechError; both carry the frame’s error_type as error_code (errorCode) and its param. On the HTTP API the same refusals are 422 answers with the same codes, which the SDKs raise from synthesize() and stream().
  • No voice with this voice_id. A voice_id that names no voice your account can use on this host closes the session with 3012, error_type voice_not_found and param voice_id. A bare name such as voice_id=jane is not a library slug: it is looked up among the slugs of your own voices, and unless one of your voices has that slug, it is not found either, with a message that ends Did you mean voice_id=aai-jane?. Send aai-jane.
  • A voice the session’s model does not speak. An AssemblyAI voice that the session’s model does not speak in the session’s language closes the session with 3006, error_type invalid_request and param voice_id, and the message lists the voices available on that connection by their slugs.
With a voice_id that names no voice (voice_id=aai-nonexistent):
Fix the voice before you reconnect; retrying unchanged fails identically. Keep handling a 3006 whose param is voice_id after Begin as well: in rare cases the refusal of a voice the model does not speak arrives right after Begin, with the same text, before any audio. Read configuration.voice_id and configuration.language from Begin to confirm what the session resolved, defaults included. See Error handling.
  • Voice cloning: a voice you clone in the AssemblyAI dashboard, named by its voice_id.
  • WebSocket API basics: the connect sequence and the rules for the rest of the query string.
  • Error handling: what to do with 3006, 3012 and the other close codes.
  • Quickstart: a full session using Audrey.