Voice Cloning API
Create a reusable custom voice from one short reference recording. Once it is created, use its voice_id in the same Text to Speech API request you already use for system voices.
What you can build
Create and use a voice in three steps
1. Prepare one reference recording
You need a reference recording and an API key with Voice Cloning enabled. The recording must be 3–60 seconds and no larger than 20 MiB (20,971,520 bytes), and you must be authorized to use the voice.
Set your API base URL and API key first. See Get your API key if you need one.
export VUILABS_API_BASE_URL="https://api.vuilabs.ai"
export VUILABS_API_KEY="your-api-key"
Supported file extensions are WAV, MP3, M4A, WebM, and OGG. If your recording is a local file, upload it first with the
Audio Upload API. Use scene=audio and keep the
returned data.object_key. Uploading preserves the original file privately; it
does not create a voice or consume a voice-cloning use.
curl --request POST \
--url "$VUILABS_API_BASE_URL/v1/files/upload" \
--header "X-API-Key: $VUILABS_API_KEY" \
--form "scene=audio" \
--form "file=@/path/to/reference.wav"
Use the same API environment and keys belonging to the same project space for the upload and voice creation. Object keys cannot be reused across project spaces or environments. If you already have a public audio URL, you can skip this upload step.
2. Create your custom voice
Choose a short, reusable ID, and replace YOUR_UPLOAD_OBJECT_KEY with the data.object_key returned by the upload above. After the request succeeds, keep the voice ID; it is the only value you need to select the custom voice in later synthesis requests.
curl --request POST \
--url "$VUILABS_API_BASE_URL/v1/voice/save" \
--header "X-API-Key: $VUILABS_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"voice_id": "my_support_voice",
"ref_audio": "YOUR_UPLOAD_OBJECT_KEY"
}'
Creating a new voice uses the current Voice Cloning entitlement. Each successful custom-voice creation consumes one free use when available; otherwise it is charged at the current Voice Cloning price. See Pricing. Choose a new voice_id for every new voice; an existing ID is rejected to prevent accidental replacement.
3. Generate audio with your voice
Pass the saved voice_id to Text to Speech. You can use the same request controls as other voices, including speed and the official expression tags inside text.
curl --request POST \
--url "$VUILABS_API_BASE_URL/v1/text-to-speech" \
--header "X-API-Key: $VUILABS_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"text": "Your appointment has been confirmed.",
"voice_id": "my_support_voice",
"language": "en",
"speed": 1
}' \
--output custom-voice.wav
Use a short sample to check pronunciation, pacing, and supported tags before generating longer content. See Text to Speech API for all synthesis controls and audio-output details.
API details
Endpoints at a glance
| Task | Endpoint |
|---|---|
| Upload reference audio | POST /v1/files/upload |
| Create a custom voice | POST /v1/voice/save |
| List custom voices | GET /v1/voice/list |
| Delete a custom voice | DELETE /v1/voice/{voice_id} |
| Generate audio with a custom voice | POST /v1/text-to-speech |
Voice-management endpoints use X-API-Key and return the standard JSON envelope:
{
"error_code": 0,
"error_message": "",
"succeed": true,
"data": {}
}
Create a custom voice
POST /v1/voice/save
| Header | Required | Description |
|---|---|---|
X-API-Key | Yes | Project API key with Voice Cloning enabled. |
Content-Type | Yes | application/json |
| Field | Type | Required | Description |
|---|---|---|---|
voice_id | string | Yes | After trimming leading/trailing whitespace and converting to lowercase, the new ID must be 1–30 characters using only a-z, 0-9, _, or -. |
ref_audio | string | Yes | The data.object_key returned by the Audio Upload API, a publicly accessible HTTP/HTTPS reference-audio URL or an existing readable object key. Uploaded keys must belong to the current API key's organization and project space. |
Reference audio must use WAV (.wav), MP3 (.mp3), M4A (.m4a), WebM (.webm), or OGG (.ogg), be 3–60 seconds long, and be no larger than 20 MiB. FLAC (.flac), raw AAC (.aac), and .opus files are not supported. AAC and Opus are codecs: use an M4A container for AAC, or an OGG or WebM container for Opus. The audio content must be readable; changing a filename extension does not convert the file.
Provide clear speech from a single speaker; silence or audio without usable speech cannot create a voice. A successful upload does not guarantee cloning eligibility. The upload endpoint has no cloning duration limit; check its duration locally before uploading if you intend to create a voice.
An ID longer than 30 characters is rejected with HTTP 400 and error_code
10001. This creation limit does not shorten existing
resource IDs: use the IDs returned by the API when listing, deleting or generating
speech with an existing voice. Pagination cursors are opaque.
Successful requests return HTTP 200; failures use a non-2xx HTTP status and the same JSON envelope. Check both the HTTP status and succeed/error_code; see Voice Cloning errors.
Common error codes
error_code | Meaning | What to do |
|---|---|---|
10018 | voice_id already exists or is reserved | Use another voice_id |
20010 | Reference audio is too large | Use a file no larger than 20 MiB |
20012 | Reference audio format is unsupported or unreadable, corrupt, or has no audio stream | Use a valid supported audio file |
20015 | Reference audio exceeds 60 seconds | Use a recording between 3 and 60 seconds |
20016 | Reference audio is shorter than 3 seconds or has insufficient usable speech | Use a longer, clearer recording |
20017 | The recording contains a pause longer than allowed | Use a more continuous recording |
See Errors for authentication, rate-limit, billing, timeout, service, and other common errors.
Manage custom voices
GET /v1/voice/list returns custom voices visible in the API key's organization.
| Query parameter | Type | Required | Description |
|---|---|---|---|
page_size | integer | No | Number of items in a page. Use 1–20; the default is 20. |
voice_id | string | No | Opaque cursor returned as next_voice_id by the preceding response. Omit it for the first page. |
curl --request GET \
--url "$VUILABS_API_BASE_URL/v1/voice/list?page_size=20" \
--header "X-API-Key: $VUILABS_API_KEY"
| Response field | Type | Description |
|---|---|---|
data.list | array | Custom voices returned in this page. |
data.list[].voice_id | string | Custom voice ID for Text to Speech. |
data.list[].voice_url | string | Temporary signed URL for the voice's reference audio. |
data.list[].created_at | integer | Creation time as a Unix timestamp in seconds. |
data.next_voice_id | string | Cursor for the next page when data.has_more is true. |
data.has_more | boolean | Whether more results are available. |
data.total | integer | Number of custom voices returned in this page. |
data.remainingFreeCloneCount | integer | Remaining free voice-cloning count for the account. |
To remove a custom voice, call DELETE /v1/voice/{voice_id}. The request is idempotent: deleting an already missing custom voice can return success, and system voices are never removed.
curl --request DELETE \
--url "$VUILABS_API_BASE_URL/v1/voice/my_support_voice" \
--header "X-API-Key: $VUILABS_API_KEY"
For request failures, see Errors. For pricing and available free usage, see Pricing.