Skip to main content
A cloned voice lets you speak in a specific person’s voice across every PyAI surface: text-to-speech, voicemail, IVR prompts, and live Omni agents. This guide takes you from a raw audio clip to a production voice_id, and is honest about the one thing that decides whether a clone sounds great or gets rejected: the quality of your reference clip.
Run the complete example. Scaffold this guide’s full, CI-tested code in one command, no clone:
Or browse it: voice-cloning.

How it fits together

Enrollment is quick but not instant: you upload a clip, the voice starts pending, and becomes ready once it passes the quality gate. A ready voice_id works immediately in POST /v1/audio/speech and as an Omni agent’s voice.
Voice cloning is English-only today and requires the voice:clone scope. Cloning copies a real person’s voice, only clone voices you have explicit permission to use.

What makes a good reference clip

The cloner is gated on real acoustic quality, not file metadata. The single most important requirement: the clip must carry genuine full-band audio (real energy up to ~24 kHz / a 48 kHz capture), not an 8 kHz phone call that’s been upsampled to look like a 48 kHz file. Upsampling adds samples, not bandwidth; the gate sees through it. A clip that passes cleanly is:
  • ~6-15 seconds of continuous, natural speech (not a single word, not a 3-minute monologue).
  • Genuinely wideband, recorded at 24 kHz or higher with real high-frequency content. A mid-quality phone mic in a quiet room is fine; a telephone recording is not.
  • One speaker only. No second voice, no crosstalk, no background conversation.
  • Clean, minimal background noise, no music, no reverb-heavy rooms, no compression artifacts.
  • Consistent, even volume, no clipping, no long silences.
The best clip is boring: one person reading two or three sentences in a quiet room with a decent mic. Record at 48 kHz mono WAV and don’t normalize, denoise, or add effects, let the audio be real.

Build it

1

Prepare the reference clip

Trim to a clean 6-15 second span where one person speaks continuously. Keep it as WAV/PCM if you can; avoid re-encoding a lossy file or upsampling a narrowband source, neither adds the bandwidth the gate needs.
2

Enroll the voice

POST /v1/voice/clones is a multipart upload: a name and the audio file. It returns a Voice with an id and a status, typically pending while the clip is processed.
3

Wait until it's ready

Poll GET /v1/voice/clones/{id} until status flips to ready. If the clip fails the quality gate the status goes to failed, see the rejection table below for what to fix.
4

Preview it

Synthesize a short line to sanity-check the clone before you ship it. This is just POST /v1/audio/speech with your new voice_id.
Python
Listen critically: if it sounds muffled, robotic, or off-timbre, the clip is almost always the cause, re-record per the requirements above rather than re-running enrollment on the same audio.
5

Synthesize with the cloned voice

Once you’re happy, the clone is a first-class voice everywhere TTS is accepted, pass voice: voice_abc exactly as you would a stock voice id.
6

Use the clone in an Omni agent

A ready cloned voice can be an Omni agent’s speaking voice. Pass your voice_id in the configure frame you send on connect ({"type":"configure", "voice_id":"voice_..."}), the realtime session then speaks in the cloned voice. Connect exactly as in the browser voice agent guide; only the configured voice_id differs.

Run it

Play hello.wav, it should be recognizably the speaker from your clip. Manage your clones any time with GET /v1/voice/clones (list) and delete one with DELETE /v1/voice/clones/{id}; clones are tenant-isolated, so you only ever see and touch your own.

”Why was my clip rejected?”

The most common support question, answered honestly. A failed status almost always traces to one of these:

Limits

  • Your stored clone library is capped per plan. An org can keep a limited number of clone voices at once (clone_voices_allowed on GET /v1/me), e.g. 1 on the free tier, more on paid plans. Delete unused clones to free a slot.
  • No fixed per-org cap on concurrent enrollment jobs today. Submit clones as you need them and use the readiness poll above; if you batch-enroll many at once and see throttling, back off and retry.
  • Prompt-to-voice design (POST /v1/voice/design, scope voice:design) is a separate, rolling-out surface. A 503 means design isn’t enabled for your stack yet, it does not affect clone enrollment above.

Next steps

Browser voice agent

Put your cloned voice on a live Omni agent in the browser.

Conversation intelligence

Transcribe and analyze the calls your agents handle.

Authentication & scopes

The voice:clone scope and key management.

API reference

Full /v1/voice/clones and /v1/audio/speech reference.