voice_id. The frames, audio formats and limits are those of an AssemblyAI voice.
Create a voice
In the voice catalog, choose Create voice clone, then record or upload a sample:- One person, speaking the voice’s language. Pick the language in the dialog and have the speaker read in it: a speaker reading English into a voice set to French is cloned on the wrong sounds.
- Ten to thirty seconds of speech. The dashboard uses up to thirty seconds of a recording under two minutes long, and shows when a recording is long enough. Read the script it offers, calm or excited, or your own text at a natural pace.
- Consent. You attest that the speaker consented to the clone, and your account must have accepted the biometric data terms on the dashboard’s data controls page.
voice_id; send a slug in lowercase. Copy voice ID on the voice copies the ID.
Speak with it
Name the voice invoice_id and leave out language. The programs below read your API key and the voice’s ID from the environment, open a session with the voice, print what Begin resolved and speak one sentence; the cURL tab does the same as one HTTP request. Set the two variables first:
- Python SDK
- JavaScript SDK
- cURL
aai.TTSError from the with, with the refusal’s error_type as error_code, such as voice_not_found, and the close code in body["close_code"].Begin.configuration.voice_id is the value you sent, and resolved_voice.voice_id is the voice’s UUID, also when you sent its slug. voice_expires_at is when the voice’s consent period ends. The other keys a cloned voice adds to Begin are in Message frames. On the OpenAI-compatible route, the voice goes in voice as {"id": "<voice ID or slug>"}.
Language and model
A cloned voice speaks the language of its recording, and nothing else. Leavelanguage out and the session speaks that language, which Begin.configuration.language shows; the default of english does not apply. A language that is not the voice’s own closes the session with 3006 before Begin, error_type invalid_parameter and param language, and the text says to omit it.
Leave model_id out as well: the session runs on the default model of the voice’s language, assemblyai-tts-1 today, and Begin.configuration.model names it. A voice is prepared for each model it speaks on, which the errors call a pairing; see Errors for a voice that is not ready yet.
Data zones
A cloned voice belongs to the data zone it was created in, and only that zone’s host can use it: a voice of the US data zone ontts.us.assemblyai.com, a voice of the EU data zone on tts.eu.assemblyai.com. On the other zone’s host the voice is not found. Set the SDK’s host accordingly: aai.settings.tts_base_url in Python, ttsBaseUrl on the JavaScript client.
Consent period
A cloned voice can be used for 60 days after its consent was last given, untilvoice_expires_at, a Unix timestamp in seconds that Begin, the HTTP response headers and the SDK results carry. After that, sessions and requests with the voice are refused with voice_expired. An expired voice cannot be renewed or used again: create the voice again from a new consented recording, which gives it a new ID. Renew a voice you want to keep before it expires.
Renew consent
The voice’s owner renews its biometric consent, which starts the 60 days again, by settingextend_biometric_consent to true on a session or request that uses the voice. Setting it attests renewed consent on behalf of your account, so send it only when your account can make that attestation. Only the account that owns the voice may set it, with its API key or a temporary token minted with that key; another account is refused with not_owner.
- Python SDK
- JavaScript SDK
- cURL
Termination.voice_expires_at and in X-TTS-Voice-Expires-At on a buffered HTTP response; a streamed response’s headers leave with the first audio and still show the old expiry. A renewal within a day of the last one leaves the expiry as it is, and Begin.configuration.extend_biometric_consent echoes the flag without promising that the expiry moved. Compare the expiry before and after when you need to know.
Errors
A voice the session cannot use is refused beforeBegin, with an Error frame in its place; over HTTP the same refusals are 422 answers with the same codes, except where noted, and the SDKs raise them as the tabs above describe. Branch on the code, not the text:
voice_not_found(close3012): no voice with this ID or slug that your account can use on this host. It does not exist, was deleted, belongs to another account, or belongs to the other data zone. Check the ID and the host.voice_expired(close3012): the consent period ended. Create the voice again.voice_blocked(close3012): the voice is blocked. Contact support.voice_not_paired(close3014): the voice is not ready on the session’s model, usually because it was just created. Try again shortly; if it keeps failing, check the voice in the dashboard. The texts of this refusal are in Error handling.not_owner(close3006):extend_biometric_consentwas set on a voice another account owns. Leave it out.biometric_terms_not_accepted(close3006,403over HTTP): your account has not accepted the biometric data terms. Accept them on the dashboard’s data controls page.invalid_parameteronlanguage(close3006): thelanguageis not the voice’s own. Leave it out.model_not_found,model_retired(close3006,3014) andfeature_not_enabled(close3006,400over HTTP): amodel_idthe region does not know, a retired model, or a host where cloned voices are not available. Leavemodel_idout, and connect totts.us.assemblyai.comortts.eu.assemblyai.com.
voice_not_paired once the voice is ready. A session refused for its voice still counts toward your account’s new sessions per minute. Error handling has every close code and what to do about it.
Related
- Voices: the voice catalog and the AssemblyAI voices to start with.
- WebSocket API basics: how
voice_idandextend_biometric_consentare checked at connect. - Error handling: every close code and what to do about it.
- OpenAI compatibility: a cloned voice through the OpenAI SDKs.
- Cloud endpoints and data residency: the US and EU hosts.