GET /v1/voices is your library, every
entry has an id like ev_1a2b3c4d, and that one id is what every surface reads
— synthesis, a live session, an interpreted call.
The invariant
The synthesis model conditions the speaker on audio, not on a name. Given nothing to condition on, its auto mode samples a new speaker on every generation: in a batch job you would notice an odd timbre, and in a live session you get an agent that changes voice between sentences. So every entry in the library points at audio. A cloned voice stores the clip you uploaded. A built-in voice is designed once from a text vocabulary and the generated clip is frozen as its reference. Naming avoice_id is how you get
the same speaker twice.
Two consequences worth holding on to:
- A long document does not drift. Splitting text across many
POST /v1/audio/speechcalls is safe, because each call resolves the same clip. See Text to speech. - Describing a voice is not the same as naming one. The
instructionsfield takes a voice-design description, and it is read only whenvoicedoes not resolve to a stored clip. A description constrains the speaker; it does not pin it.
Where a voice_id is read
The retired omni realtime id did not support cloned voices. Its adapter sent no
reference audio upstream, so an
ev_… id there has no effect rather than an
error — the session runs in the model’s own voice. Check supports_cloning on
GET /v1/audio/models before you assume a voice will carry.Clone a voice
Cloning is amultipart/form-data upload of a few seconds of clean speech.
Cloning is asynchronous
The voice appears at once withstatus: "processing" and moves to ready when
its reference clip has been trimmed, transcribed and encoded — or to failed,
with the reason in error. Poll GET /v1/voices/{voice_id}, or watch the
library.
Using a voice before it is ready is a 400 that names the status, not a wait:
ref_text no longer does what it looks like
This is deliberate, and it fixed a bad failure. The synthesis model concatenates
the reference transcript with your input and crops by the clip’s duration, so
the transcript has to be the words that are actually in the audio the encoder
sees. The console used to send the unread prompt script instead, and every
synthesis in those voices spoke the script rather than the requested sentence.
Transcribing the trimmed clip is the only way to keep the two in step.
The consequence for you: a clip that transcribes to nothing fails the clone
outright, with status: "failed". That is a recording problem, and the fix is a
better clip rather than a better field. See
Voice cloning.
Consent is checked before the audio is read
consent_attested=true is required, and it is checked before the upload is even
read: audio there is no right to clone is audio that is never taken. The
timestamp lands on the voice as consent_attested_at.
An attestation records your claim. Nothing verifies who is speaking on the clip,
so keep your own evidence of the speaker’s permission, and read
Compliance before you clone somebody who is not you.
Hear it before you commit
POST /v1/voices/{voice_id}/preview synthesizes one fixed sentence and
streams back mp3. You do not choose the text, and that is the point: two voices
previewed on the same sentence are comparable, where two voices reading their
own best lines are not. There is no SDK method, so call it directly:
GET /v1/voices/{voice_id}/sample is the cheaper sibling. It returns a
short-lived signed URL for the reference clip itself — the recording for a
clone, the frozen design output for a built-in — so playing a voice in a library
list costs a storage read rather than a GPU pass:
voice set to the id.
Rename, and delete
A cloned voice is erased automatically three years after its last use. Using it
resets the clock, so a voice in production never expires out from under you, but
one cloned once and shelved will go, along with its reference audio. Built-in
voices are synthesized rather than recorded from a person and have no such
clock.
Designing a voice instead of cloning one
When you do not need a specific person, describe a voice rather than recording one. The accepted vocabulary is a fixed list the serving model publishes rather than free text, so read it instead of guessing:instructions on
POST /v1/audio/speech, with voice left as auto. A described voice carries
no likeness rights and no retention clock, and it is also not a stable speaker:
if you want the same voice tomorrow, the built-in library is where designed
voices live once they have been frozen to a clip.
Cost and limits
Next
Voice cloning
What makes a clip good, and what a bad one sounds like.
Clone a voice
Upload, preview, and use the id in both places.
Text to speech
Where the
voice field goes.Live
Setting the voice on a live session.