beatraDocs
Speech & voices

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. Each model's card lists its sample limits (the sample_* fields); a clean recording of one speaker works best. For ElevenLabs the sample must be 10 seconds to 5 minutes long and at most 20 MiB, in WAV, MP3, M4A, AAC, or OGG; anything outside these limits is rejected before charge.
  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

MCP integration guide for AI

For custom API integrations, copy this guide into Claude, Codex, or another coding assistant.

Tool arguments

{
  "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.

{
  "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

Some models are explicit-only: they are not in the default list, auto never picks them, and beatra.models.list lists them only when called with include_activation_required: true (REST: GET /v1/catalog/capabilities/voice_clone?include_activation_required=true). Their cards set constraints.automatic_formal_activation: false. That listing rule does not tell you whether activation is needed. doubao-voice-clone-2.0 below clones in two steps: cloning makes a free preview, and a separate paid activation makes the voice usable for speech. The ElevenLabs clone is listed the same way but is one-step and ready on success (see the ElevenLabs section). Use an explicit-only model 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.

KeyType and rangeEffect
sample_textstring, at most 1,000 charactersThe 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_denoiseboolean (default false)Remove background noise before training.
enable_audio_denoise_with_snrbooleanRemove noise only when the sample's signal-to-noise ratio is below denoise_max_snr_thresh.
denoise_max_snr_threshinteger, 1–99 (default 50)The signal-to-noise ratio below which noise is removed.
reject_min_snr_threshnumber, greater than 0 and less than 100 (default 5)Reject a sample whose signal-to-noise ratio is lower.
voice_clone_denoise_model_idSpeechInpaintingV2 (default) or VocalDiffusionV2VocalDiffusionV2_44kThe noise-removal model.
voice_clone_enable_mssbooleanSeparate the voice from background music before training.
enable_crop_by_asrbooleanPick the training segment by speech recognition instead of taking the first 25 seconds.
enable_check_prompt_text_qualitybooleanCheck the quality of sample_text before training.
enable_check_audio_qualitybooleanCheck the sample's audio quality before training.
disable_volume_normalizationbooleanKeep the sample's recorded volume.
{
  "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.

{
  "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

elevenlabs-voice-clone is open to every account but explicit-only: pass model: "elevenlabs-voice-clone". It is not in the default voice clone list and auto never picks it. Find it with beatra.models.list and include_activation_required: true (REST: GET /v1/catalog/capabilities/voice_clone?include_activation_required=true), with GET /v1/catalog/models/elevenlabs-voice-clone, or in the full /v1/models list. It matches the listing conditions of the two-step models above, but it is one-step: the voice is ready as soon as the task succeeds.

A successful clone costs 7,270 credits once and is immediately ready for elevenlabs-v4-turbo and elevenlabs-v4. The cloned voice works only with those two models and speaks the 10 languages they support (en, zh, ja, ko, es, pt, ar, hi, fr, it). 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. Calling activate on an already ready voice is a free no-op. prompt and model_options are ignored with a warning.

Sample limits. These are limits, not recommendations; a sample outside them is rejected before any charge:

  • Format: WAV, MP3, M4A, AAC, or OGG. Another format returns 422 unsupported_option.
  • Length: at least 10 seconds and at most 5 minutes. Size: at most 20 MiB. A duration or size outside the range returns 422 invalid_request.
  • Use an authorized recording of one speaker. 1–2 minutes is recommended; more than 3 minutes does not improve the clone.

If the engine itself rejects the sample after the task is accepted, the task fails with voice_sample_rejected and is refunded in full. The message says whether the sample was too short, too long, unreadable, or too large, or whether the voice needs additional verification (this also fails with voice_sample_rejected and is refunded).

Daily limit. At most 3 ElevenLabs clones per account per UTC day; the day resets at 08:00 Beijing time (00:00 UTC). A clone counts when it is in progress, succeeded, or failed after reaching the engine. A sample rejected by the local checks above, or a clone canceled before upload, does not count. The fourth returns 429 rate_limited with details.reason: voice_creation_daily_limit, retry_after_seconds, and, over REST, a Retry-After response header with the same seconds (MCP has no headers); nothing is charged. Omit model to use the default voice clone at the same price. Replaying the same request does not create another clone.

Temporary errors. Nothing is charged for either:

  • 503 model_unavailable with details.reason: creation_temporarily_unavailable: new clones with this model are paused. Omit model to use the default voice clone at the same price, or try again after available_at when it is given.
  • 503 model_unavailable with details.reason: voice_temporarily_busy: voice cloning is busy; retry after retry_after_seconds (about a minute).

Free preview. When you explicitly select the free preview in the account or desktop interface, Beatra synthesizes a fixed sentence in your cloned voice and saves it for later playback. The sentence is chosen by the clone's language (one of the 10 languages, otherwise English). The first preview is free, is cached and reused, and counts toward the two-task ElevenLabs speech limit (see text to speech). If the voice must first be restored, the preview may return 503 model_unavailable (see details.reason and retry_after_seconds; for a restore in progress, voice_temporarily_busy with 30 seconds); the restore continues in the background and the next try succeeds. No preview is generated while two ElevenLabs speech tasks are already running; it simply returns no preview. A failed preview does not change the clone's result or charge. Custom text or different synthesis settings require a separately confirmed speech quote.

Your sample and the voice. Clones remain owned by the account under the same voice_id. The uploaded sample is kept as a private copy so the voice can be restored internally when needed; restoring may add time and does not promise identical waveforms after model changes. The sample is deleted, together with the voice at the engine and any cached preview, when you delete the voice or close the account. Deletion cannot be undone and does not refund the clone; speech tasks already accepted still finish.

A speech request on a cloned voice can fail in these ways. A temporarily busy voice (503 voice_temporarily_busy) or one that cannot be restored right now (503 voice_temporarily_unavailable, with available_at when known) is not charged and does not affect other voices. A voice that can no longer be restored from its saved sample returns 422 voice_unavailable: this is permanent, so do not retry; contact support. That synthesis is not charged, and the original clone fee is not refunded. A failed accepted speech request refunds only that speech charge.

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 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.

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 · activate. Skill + MCP is the recommended integration; use REST for custom, non-agent applications.

Last updated

On this page

Markdown
Voice clone | Beatra Docs