# Voice clone
> Clone a reusable voice from an authorized audio sample.

Clone a reusable voice from an authorized audio sample.

## Primary agent path

Use the Universal Skill with the MCP tool `beatra.voices.clone`. The tool is
billable, consent-gated, and returns an asynchronous task.

1. Confirm with the user that they hold the rights to this voice. Set
   `consent_attested: true` only after that explicit confirmation.
2. Upload the local sample with `beatra.assets.upload` and use its artifact ID.
   10 seconds to 5 minutes of clean, single-speaker audio works best.
3. Create one opaque `client_request_id` and submit the final arguments once.
4. Poll the returned task with `beatra.tasks.get`; the terminal response
   returns the new `voice_id`.

## AI guide

AI integration guide: https://docs.beatra.ai/llms/voices-clone.md

## Tool arguments

```json
{
  "sample": { "type": "artifact", "artifact_id": "artifact_01JX..." },
  "display_name": "Brand narration - female",
  "consent_attested": true,
  "client_request_id": "voice-clone-opaque-1"
}
```

`sample` accepts an artifact, HTTPS URL, or data URI. `display_name` is
required (≤255 characters). A request without `consent_attested: true` is
rejected.

## Optional quality prompt

For a higher-similarity clone, add `prompt`: a short excerpt (shorter than 8
seconds) of the same voice plus its verbatim transcript. The engine aligns the excerpt
character for character to sharpen the cloned timbre — useful when the main
sample is long or slightly noisy.

```json
{
  "sample": { "type": "artifact", "artifact_id": "artifact_01JX..." },
  "prompt": {
    "sample": { "type": "artifact", "artifact_id": "artifact_prompt..." },
    "text": "Verbatim transcript of the prompt excerpt."
  },
  "display_name": "Brand narration - female",
  "consent_attested": true,
  "client_request_id": "voice-clone-opaque-1"
}
```

`prompt.sample` accepts the same reference kinds as `sample`; `prompt.text`
(≤2,000 characters) must match the excerpt exactly and end with a punctuation
mark. An excerpt measured at 8 seconds or longer, or a transcript without
ending punctuation, is rejected before billing. Omit `prompt` to clone from
the main sample only — the prompt adds no extra charge.

## Models, controls, and cost

Omit `model` (or use `auto`) unless the user names one. `beatra.models.list`
with `capability: "voice_clone"` is the current source for selectable models,
accepted sample kinds, and the fixed price.

With `auto` (and every model whose card sets
`constraints.automatic_formal_activation: true`), voice cloning has one fixed
charge when the activated voice is created successfully. Success means Beatra
already ran a short formal synthesis to activate the clone — that activation
is included in the charge; later speech synthesis is billed separately. A
failed clone or activation does not retain the charge.

## Models that need a separate activation

A few explicitly selected models clone in two steps: cloning makes a free
preview, and a separate paid activation makes the voice usable for speech.
They never take part in `auto`, and `beatra.models.list` lists them only when
called with `include_activation_required: true` (their cards set
`constraints.automatic_formal_activation: false`). Use one only when the user
asks for it by name.

`doubao-voice-clone-2.0`:

- `language` is required and must be the language spoken in the sample: `zh`,
  `en`, `ja`, `ko`, `es`, `es-MX`, `pt`, `pt-BR`, `id`, `ms`, `th`, `vi`,
  `fil`, `de`, `fr`, `ru` or `ar`. A missing or unlisted value is rejected
  with 422 `unsupported_option`.
- The sample must be WAV, MP3, OGG, M4A or AAC audio of at most 10 MiB, or it
  is rejected with 422 `voice_sample_rejected` before anything is charged.
  14–30 seconds of one person speaking works best; by default only the first
  25 seconds are used. `prompt` is ignored with an `option_ignored` warning.
- Cloning and the preview are free. The task succeeds with
  `output.status: "pending_activation"`, a `preview` (a fixed sentence in the
  chosen language read in the cloned voice), `activation.price_credits`,
  `activation.quote` (the activation quote, see below), and `expires_at`. Play
  the preview to the user.
- A waiting voice cannot be used for speech: synthesis returns 422
  `voice_activation_required`. It can be renamed but not made the default.
  If it is not activated by `expires_at` (normally 7 days after cloning), it
  becomes `expired` (422 `voice_preview_expired`) and the voice must be cloned
  again.
- Limits per account: 10 voices waiting for activation (409
  `voice_limit_reached`; activate or delete one), 20 clones per UTC day
  (429 `rate_limited`, `details.reason: voice_training_daily_limit`), and one
  clone in progress at a time (429 `rate_limited`,
  `details.reason: voice_training_in_progress`; retry when it finishes). While
  cloning is busy for everyone the reason is `voice_training_busy`; retry after
  about 30 seconds.

Optional `model_options.doubao` tunes the training. Values are checked before
anything is charged; an unknown key or a value out of range is rejected with
422 `unsupported_option`.

| Key | Type and range | Effect |
| --- | --- | --- |
| `sample_text` | string, at most 1,000 characters | The words spoken in the sample. A sample whose speech differs too much is rejected (`voice_sample_rejected`, `details.reason: sample_text_mismatch`). Checked for `zh`, `en`, `ja`, `ko`, `es`, `es-MX`, `pt`, `pt-BR`, `id`, `fr` and `ru` only; ignored with an `option_ignored` warning for the other languages. |
| `enable_audio_denoise` | boolean (default `false`) | Remove background noise before training. |
| `enable_audio_denoise_with_snr` | boolean | Remove noise only when the sample's signal-to-noise ratio is below `denoise_max_snr_thresh`. |
| `denoise_max_snr_thresh` | integer, 1–99 (default 50) | The signal-to-noise ratio below which noise is removed. |
| `reject_min_snr_thresh` | number, greater than 0 and less than 100 (default 5) | Reject a sample whose signal-to-noise ratio is lower. |
| `voice_clone_denoise_model_id` | `SpeechInpaintingV2` (default) or `VocalDiffusionV2VocalDiffusionV2_44k` | The noise-removal model. |
| `voice_clone_enable_mss` | boolean | Separate the voice from background music before training. |
| `enable_crop_by_asr` | boolean | Pick the training segment by speech recognition instead of taking the first 25 seconds. |
| `enable_check_prompt_text_quality` | boolean | Check the quality of `sample_text` before training. |
| `enable_check_audio_quality` | boolean | Check the sample's audio quality before training. |
| `disable_volume_normalization` | boolean | Keep the sample's recorded volume. |

```json
{
  "sample": { "type": "artifact", "artifact_id": "artifact_01JX..." },
  "display_name": "My voice",
  "model": "doubao-voice-clone-2.0",
  "language": "zh",
  "model_options": { "doubao": { "enable_audio_denoise": true } },
  "consent_attested": true,
  "client_request_id": "voice-clone-opaque-2"
}
```

## Activating a voice

`beatra.voices.activate` makes a waiting voice usable for speech. The clone
result already carries the quote, so one call activates:

1. The clone result's `activation.quote` carries `price_credits`,
   `balance_credits`, `sufficient_balance`, the `preview`, `terms` in `zh`,
   `en` and `ja`, `terms_version`, a `confirmation_token`, and
   `token_expires_at` (24 hours).
2. Tell the user the price and the terms and get their explicit consent. Never
   activate automatically.
3. Call it with `voice_id`, `confirmation_token` and `confirm_credits` (the
   quoted `price_credits`). The price is charged once and the call returns an
   asynchronous task; poll it with `beatra.tasks.get`. When it succeeds the
   voice is `ready`; its output carries the voice, with a final preview when
   one could be made.

Called without `confirmation_token` (the token is gone or older than 24
hours), it returns a new quote and charges nothing.

```json
{
  "voice_id": "voice_01JX...",
  "confirmation_token": "<from activation.quote>",
  "confirm_credits": 100000,
  "client_request_id": "voice-activate-opaque-1"
}
```

- An expired token, a price that changed, or a `confirm_credits` that differs
  from the quote returns 422 `price_confirmation_required` with a new quote in
  `details.quote`; nothing is charged. Show the new quote and ask again.
- A failed activation is refunded automatically; a successful one is not
  refunded. An activated voice cannot take a new recording: to change it,
  clone a new voice and activate that one.
- Limits per account: one activation in progress at a time (429
  `rate_limited`, `details.reason: voice_activation_in_progress`) and 3
  activations per UTC day. A fourth returns 429
  `voice_activation_daily_limit`: nothing is charged, and the user is asked to
  contact support.
- When activation cannot run, the error is `internal_error`, nothing is
  charged (or the charge is fully refunded), and the message asks the user to
  contact support with the `request_id`.
- Calling it for a voice that is already `ready`, including every voice cloned
  with `auto` and every preset voice, charges nothing and changes nothing.
- While an activation runs, the voice cannot be deleted (409 `conflict`,
  `details.reason: voice_operation_in_progress`).

The price is in the clone card (`pricing`, `billing_basis:
successful_activated_voice`) and in every quote. Deleting an activated voice
cannot be undone and the activation charge is not refunded; speech tasks
already submitted for it still finish.

An activated Doubao clone speaks with `doubao-seed-tts-2.0`, long text
included, in the language it was trained in. A `language` it does not read
(for a Chinese clone, anything other than Chinese, English or `auto`) gets an
`option_ignored` warning that names the language the voice was cloned from,
and a Chinese clone refuses it on the long-text path (send parts of up to 3,000
characters, or clone a voice from a recording in that language); the text
itself is not checked. Subtitles, pauses, and readings follow the rules of a
preset voice in that language. `emotion`, `direction`, and `previous_text` are
sent to the model as for the voices that follow them; how they come through
depends on the Doubao model.

## ElevenLabs: explicit, ready-on-success cloning

Specify `model: "elevenlabs-voice-clone"` explicitly. It never participates in
clone `auto` or the default clone-capability listing. When available to your
account, inspect its card with `GET /v1/catalog/models/elevenlabs-voice-clone`;
the full `/v1/models` list also includes it. Internal acceptance does not make
the model available to ordinary accounts.

A successful clone costs **7,270 credits once** and is immediately `ready` for
`elevenlabs-v4-turbo` and `elevenlabs-v4`. The clone task creates the voice only:
it does not synthesize speech, generate a preview, or require activation. A later
speech request is separately quoted and charged. When you explicitly select the free preview in the account or desktop interface, the platform synthesizes a fixed sentence in your cloned voice and saves it for later playback. A failed preview does not change the clone's result or charge, and the original recording is not substituted as the cloned result. Custom text or different synthesis settings require a separately confirmed speech quote. Calling activate on an already ready voice is a free no-op.

- Use an authorized single-speaker WAV, MP3, M4A, AAC, or OGG recording, at least
  10 seconds and at most 20 MiB; 1–2 minutes is recommended and more than
  3 minutes does not improve the recommendation. `prompt` and specialized clone
  options are ignored with a warning.
- At most 3 successful or in-progress new clones per account per UTC day
  (08:00 Beijing reset). Failure releases the daily slot. Replaying the same
  request does not create another clone or consume another slot.
- Clones remain owned by the account under the same `voice_id`. The original
  recording is retained until deletion for free internal reconstruction when
  needed; the name and compatible models do not change. Reconstruction may add
  time and does not promise identical waveforms after model changes.
- Temporary creation/reconstruction capacity errors do not charge a newly
  rejected request. A failed accepted speech request refunds only that speech
  charge. A permanently rejected saved sample returns `voice_unavailable` and
  asks you to contact support; it does not refund a historical successful clone.
- Deleting the voice also deletes its retained sample after already accepted
  speech tasks finish. Deletion cannot be undone and does not refund the clone.

## Task status and recovery

`queued` and `running` are not failures. Keep polling the same `task_id`; never
submit a replacement because work is still running. On a lost create response,
retry the identical arguments with the same `client_request_id`. If any input
changes, use a new ID. The returned `voice_id` works directly as the `voice`
field in [text to speech](https://docs.beatra.ai/en/docs/capabilities/speech/text-to-speech) once the
voice is `ready` (a voice that needs activation, after it is activated), stays
valid long-term, and can be inspected or deleted in
[voices](https://docs.beatra.ai/en/docs/capabilities/speech/voices).

## REST API

Direct protocol integrations may use `POST /v1/voices`,
`POST /v1/voices/{voice_id}/activate`, and the shared task endpoints. Follow
the generated API operations:
[clone](https://docs.beatra.ai/en/docs/api-reference/operations/voices/clone_voice_v1_voices_post) ·
[activate](https://docs.beatra.ai/en/docs/api-reference/operations/voices/activate_voice_v1_voices__voice_id__activate_post).
Skill + MCP is the recommended integration; use REST for custom, non-agent
applications.
