Skip to content

Voices

A text-to-speech model on Layer speaks in the voice of a reference set. There is no voice_id field on the inference request: you pick a voice by passing a voice reference set in reference_sets, and a model that needs one refuses a request without it.

This applies to every ElevenLabs voice model:

Base model base_model_id
ElevenLabs TTS V4 ELEVEN_LABS_TTS_V4
ElevenLabs TTS V4 Turbo ELEVEN_LABS_TTS_V4_TURBO
ElevenLabs TTS V3 ELEVEN_LABS_TTS_V3
ElevenLabs Multilingual V2 ELEVEN_LABS_MULTILINGUAL_V2
ElevenLabs Voice Changer ELEVEN_LABS_VOICE_CHANGER

One voice reference set works on all five: the same voice is bound to each of them.

Layer ships a library of character voices (Amelia, David, Hope and more) as reference sets that are already bound to the models above. List them like any other reference set, optionally searching by name:

Terminal window
curl "https://api.app.layer.ai/api/v2/workspaces/$WORKSPACE_ID/reference-sets?search=David" \
-H "Authorization: Bearer $LAYER_TOKEN"
# → { "reference_sets": [{ "reference_set_id": "…", "name": "David", "category": "character", "has_active_finetune": true }], … }

Then pass its reference_set_id as set_id when you generate:

Terminal window
curl -X POST https://api.app.layer.ai/api/v2/workspaces/$WORKSPACE_ID/inferences \
-H "Authorization: Bearer $LAYER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"base_model_id": "ELEVEN_LABS_TTS_V4",
"prompt": "[whispering] Keep your voice down. The patrol passes at midnight.",
"reference_sets": [{ "set_id": "REFERENCE_SET_ID" }]
}'

The run is asynchronous: poll GET …/inferences/{inference_id} until it completes.

Your own voice is a reference set you train with one of three training frameworks:

training_framework Starts from Inputs
voice-clone Recordings of the voice 1 to 10 audio clips in the reference set.
voice-design A written description of the voice training_parameters.training_prompt, plus at most one optional reference clip.
voice-import An ElevenLabs voice ID you already have training_parameters.voice_id; no files.

Train on ELEVEN_LABS_TTS_V4, ELEVEN_LABS_TTS_V4_TURBO or ELEVEN_LABS_TTS_V3. Whichever you pick, the finished voice is bound to all five ElevenLabs voice models, so you can generate with any of them afterwards.

Every framework follows the same flow: create a reference set, start a training run on it, poll the run, then generate with the set.

  1. Create a reference set

    For voice-clone, upload your clips first (audio/wav or audio/mpeg) and pass their IDs. For voice-import, and for voice-design without a reference clip, file_ids can be empty.

    Terminal window
    curl -X POST https://api.app.layer.ai/api/v2/workspaces/$WORKSPACE_ID/reference-sets \
    -H "Authorization: Bearer $LAYER_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
    "name": "Captain Mara",
    "category": "character",
    "file_ids": ["AUDIO_FILE_ID_1", "AUDIO_FILE_ID_2"]
    }'
    # → { "reference_set_id": "…", "name": "Captain Mara", "asset_count": 2, … }
  2. Start a training run

    Pass the framework and its parameters. See the examples for each framework below.

    Terminal window
    curl -X POST https://api.app.layer.ai/api/v2/workspaces/$WORKSPACE_ID/training-runs \
    -H "Authorization: Bearer $LAYER_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
    "reference_set_id": "REFERENCE_SET_ID",
    "base_model_id": "ELEVEN_LABS_TTS_V4",
    "training_framework": "voice-clone"
    }'
    # → { "training_run_id": "…", "state": "in_progress", "poll_interval_seconds": … }

    To check the price first, send the same body to POST …/training-runs/estimate.

  3. Poll the run

    Terminal window
    curl https://api.app.layer.ai/api/v2/workspaces/$WORKSPACE_ID/training-runs/TRAINING_RUN_ID \
    -H "Authorization: Bearer $LAYER_TOKEN"

    Poll every poll_interval_seconds until state is terminal_success or terminal_failure. On failure, read error and error_code. You can also pass a webhook when you start the run instead of polling (see Webhooks).

  4. Generate with the voice

    Pass the reference set exactly as in Use a ready-made voice, with any of the five base models.

voice-clone needs between 1 and 10 audio clips in the reference set. Clean speech with no music or background noise gives the closest match; a few minutes in total is plenty.

{
"reference_set_id": "REFERENCE_SET_ID",
"base_model_id": "ELEVEN_LABS_TTS_V4",
"training_framework": "voice-clone"
}

voice-design creates a new voice from a description in training_parameters.training_prompt. On ElevenLabs the description runs 20 to 1000 characters, and three optional knobs shape the result:

Parameter Range Effect
loudness -1 to 1 How loud the designed voice speaks.
guidance_scale 0 to 100 How closely the voice follows the description.
prompt_strength 0 to 1 With a reference clip in the set: the balance between the description and the clip.
{
"reference_set_id": "REFERENCE_SET_ID",
"base_model_id": "ELEVEN_LABS_TTS_V4",
"training_framework": "voice-design",
"training_parameters": {
"training_prompt": "A weathered sea captain in her fifties, low and gravelly, calm but commanding.",
"guidance_scale": 5
}
}

voice-import turns an existing ElevenLabs voice into a reference set. Pass its ID in training_parameters.voice_id. It can be any voice from the public ElevenLabs voice library, or a voice made on Layer. Layer generates through its own ElevenLabs access, so a voice that is private to your own ElevenLabs account can’t be reached and its import fails. The reference set needs no files.

{
"reference_set_id": "REFERENCE_SET_ID",
"base_model_id": "ELEVEN_LABS_TTS_V4",
"training_framework": "voice-import",
"training_parameters": { "voice_id": "ELEVENLABS_VOICE_ID" }
}

The run checks the ID by generating one short line with it, and that clip becomes the run’s sample. An ID that doesn’t exist, or that Layer can’t use, fails the run with error_code INVALID_INPUT.

Qwen 3 TTS (QWEN_3_TTS) and Seed Audio 1.0 (SEED_AUDIO_1) train voices through the same flow, with two differences: a clone reads one clip, so put exactly one in the set, and the voice stays on the model it was trained on. Qwen 3 TTS also offers voice-design; neither offers voice-import. Each model’s page lists the frameworks it takes.

The MCP server follows the same flow: list_reference_sets to find a voice, or create_reference_set then start_training (with the same training_framework and training_parameters) and get_training_status to make one. Generate with execute_forge, passing the set as reference_sets: [{ "set_id": "…" }].