Skip to content
TriedDocs
Voices

Clone voice

Create a workspace voice from audio samples with ElevenLabs, Fish Audio or MiniMax instant cloning.

POSThttps://api.tried.com.au/clone-voice

Needs keys Creates a voice from one or more audio samples and adds it to your workspace's voices. Real cloning needs the chosen vendor's key (ELEVENLABS_API_KEY, FISH_API_KEY or MINIMAX_API_KEY).

Without that key, or with TRIED_MOCK_PROVIDERS=1, Tried stores the voice with a mock_ provider ID so you can build and test agents end to end.

Request#

Send multipart/form-data with the fields below and one or more audio file parts. A JSON body is also accepted (see JSON form).

Field Type Required Description
voice_name string Yes Name of the new voice. 1 to 100 characters.
description string No Up to 500 characters. Sent to ElevenLabs and Fish Audio.
provider string No elevenlabs (default), fishaudio or minimax.
files file Yes Audio samples. Send at least one. All samples together can be at most 25 MB. MiniMax uses only the first file.

JSON form#

For scripts, send application/json with the same fields and the samples as base64:

{
  "voice_name": "Front desk (Sydney)",
  "provider": "elevenlabs",
  "files": [
    { "filename": "sample.mp3", "mimetype": "audio/mpeg", "content_base64": "SUQzBAAAAAAA..." }
  ]
}

filename defaults to sample.mp3 and mimetype to audio/mpeg. The whole JSON body is limited to 25 MB.

Example request#

curl -X POST https://api.tried.com.au/clone-voice \
  -H "Authorization: Bearer $TRIED_API_KEY" \
  -F voice_name="Front desk (Sydney)" \
  -F provider=elevenlabs \
  -F files=@sample1.mp3 \
  -F files=@sample2.mp3
import { readFile } from "node:fs/promises";

const form = new FormData();
form.append("voice_name", "Front desk (Sydney)");
form.append("provider", "elevenlabs");
form.append("files", new Blob([await readFile("sample1.mp3")], { type: "audio/mpeg" }), "sample1.mp3");

const res = await fetch("https://api.tried.com.au/clone-voice", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.TRIED_API_KEY}` },
  body: form,
});
const voice = await res.json();
import os, requests

with open("sample1.mp3", "rb") as f:
    res = requests.post(
        "https://api.tried.com.au/clone-voice",
        headers={"Authorization": f"Bearer {os.environ['TRIED_API_KEY']}"},
        data={"voice_name": "Front desk (Sydney)", "provider": "elevenlabs"},
        files=[("files", ("sample1.mp3", f, "audio/mpeg"))],
    )
voice = res.json()

Response#

201 Created

{
  "voice_id": "custom_voice_137bcfa732ab6e2df5d2b815",
  "voice_name": "Front desk (Sydney)",
  "provider": "elevenlabs",
  "provider_voice_id": "mock_9f060d81a4d8df9b04ca",
  "gender": "female",
  "accent": "Custom",
  "age": "middle_aged",
  "preview_audio_url": null
}
Field Type Description
voice_id string Starts with custom_voice_. Set it as an agent's voice_id.
provider_voice_id string The vendor's voice ID. In mock mode it starts with mock_. For MiniMax it is an ID Tried picks, starting with Tried.
gender string Always female for cloned voices.
accent string Always Custom.
age string Always middle_aged.
preview_audio_url null Always null.

Errors#

Status When
400 A field fails validation (for example voice_name missing), At least one audio sample (files) is required, Audio samples are limited to 25 MB in total, or the vendor rejects the clone (ElevenLabs voice clone failed (<status>): ..., and the same for Fish Audio and MiniMax).
401 Missing or invalid API key.
403 The key's IP allowlist or scopes reject the request (this route needs the agents scope), or the caller is a read-only dashboard member.
413 A single file is over 50 MB, or the JSON body is over 25 MB.
429 Rate limit exceeded. See Rate limits.

See Errors for the body format.

Retell compatibility#

Same path and method as Retell, and both take multipart voice_name plus files. The provider field differs: Tried reads provider with values elevenlabs, fishaudio and minimax, and defaults to elevenlabs.