Voice clone and generate-with-voice API (not recommended)
⛔ Legacy chain — not recommended for new integrations. This page documents the early
personachain (voice_task_id/generate-with-voice). It still works, but it is no longer recommended to customers; the left-hand navigation marks it "not recommended".For new integrations use the 【Recommended】 Voice profile API: create a voice profile from one vocal sample (
POST /api/music/voice-profile/create), then use it to cover a chosen song or to sing a new song. A voice profile is a first-class resource — it can be listed, fetched and deleted, and its source audio is kept permanently.If your product needs the full loop "create a voice → reuse it for a long time → cover songs", prefer the new chain.
Important: a cloned voice can expire.
The
voice_id/voice_task_idproduced by voice cloning is not a permanently usable resource — it can stop working because its validity period elapsed or because the account or voice state changed. Integrators must not clone once and then reuse a locally cached voice ID forever.Recommended practice:
- Store
voice_task_id,voice_id,is_available,updated_atand the time of the last successful generation.- Before every generation that uses a cloned voice, call
GET /api/voice/clone/tasks/{voice_task_id}orPOST /api/voice/clone/tasks/{voice_task_id}/checkand confirmis_available=true.- If the endpoint reports that the voice is unavailable, that the task does not exist or returns
selected voice is not ready, ask the user to clone again or to pick another available voice.- Do not promise end users that a cloned voice is a "permanent asset"; show a hint in your product UI that "a voice can expire and may need re-validation or re-cloning".
Endpoint description
This group of endpoints creates a reusable voice and generates songs with it. The caller only needs the API Key issued by the platform; the server handles task submission, status synchronisation, billing and downloads.
Authentication: Authorization: Bearer YOUR_API_KEY
Billing:
- Voice validation, voice cloning, status queries, deletion and downloads: free.
- The one-step clone entry in the workspace: a flat ¥5 per call; it completes source-voice validation and the second verification audio automatically, and refunds on failure.
- Continuing automatically into the verification audio after an ordinary clone: a flat ¥5 per call, refunded on failure according to the existing flow.
- Generating a song with a cloned voice: charged, a flat ¥1.2 per call; each call usually returns 2 placeholder tasks.
- With Max Mode switched on (
max_mode: trueonPOST /api/music/generate-with-voice) the ¥1.2 per call is billed at 2×, that is ¥2.4 per call; voice generation also supportsvariety(0-4, no extra charge) — see the "Advanced parameters" section of the new API overview.
Calling flow
- Call
POST /api/voice/clone/validateto upload the source voice and obtain avoice_task_id. - Wait or poll
GET /api/voice/clone/tasks/{voice_task_id}until you getvalidate_info. - The user reads the text out and records the verification audio.
- Call
POST /api/voice/clone/tasks/{voice_task_id}/generateto submit the verification audio. - Call
POST /api/voice/clone/tasks/{voice_task_id}/checkor keep polling the task untilis_available=true. - Call
POST /api/music/generate-with-voiceto generate a song with that voice. - The generation endpoint first returns placeholder tasks; once generation finishes and you have the real
song_id, use the download endpoints to fetch a single file or a bundle. - (Optional) When the voice is no longer needed, call
DELETE /api/voice/clone/voices/{voice_task_id}to delete it — the semantics are in section 6.
There is also a one-step clone: on the first recording/upload page in the workspace you can choose to finish in one go, and the system completes validation and voice creation together, so you do not have to record a second verification audio; it costs ¥5 per call with a refund on failure.
Voice task fields
| Field | Type | Notes |
|---|---|---|
voice_task_id |
number | The voice task ID inside the platform; every later endpoint uses this ID |
voice_id |
string | The voice ID that can be used to generate songs; returned once the task is usable |
voice_name |
string | Voice name |
description |
string | Voice description |
style |
string | Voice style |
singer_skill_level |
string | Singing level; common values: beginner, intermediate, professional |
language |
string | Source voice language, for example zh, en |
validate_info |
string | The verification text that has to be read out |
validate_status |
string | State of the validation task |
voice_status |
string | Voice creation state |
is_available |
boolean | Whether it can already be used to generate songs |
status |
string | Platform task state |
stage |
string | Current stage |
error_code |
string | Failure error code |
error_message |
string | Failure reason |
source_duration_seconds |
number | Source audio duration in seconds |
created_at |
number | Creation timestamp |
updated_at |
number | Update timestamp |
completed_at |
number | Completion timestamp |
1. Submit the source voice for validation
Endpoint: POST /api/voice/clone/validate
Body parameters
| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
voice_url |
string | No | - | Source voice audio URL. Either this or file_base64 |
file_base64 |
string | No | - | Base64 audio. Either this or voice_url |
file_name |
string | No | - | File name; recommended when using file_base64 |
voice_name |
string | No | generated automatically | Voice name |
description |
string | No | - | Voice description |
style |
string | No | - | Voice style |
singer_skill_level |
string | No | beginner |
Singing level |
language |
string | No | zh |
Source voice language |
vocal_start_s |
number | Yes | - | Start second of the usable vocal |
vocal_end_s |
number | Yes | - | End second of the usable vocal |
source_duration_seconds |
number | No | - | Total source audio duration in seconds |
vocal_end_s - vocal_start_smust meet the minimum vocal-segment requirement. Upload a clear vocal recording with no obvious backing music or noise.
Request example
curl -X POST https://www.suno-api.io/api/voice/clone/validate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"voice_url": "https://example.com/source-voice.wav",
"voice_name": "My Chinese female voice",
"description": "A clear, natural Chinese female voice",
"style": "Mandopop",
"singer_skill_level": "intermediate",
"language": "zh",
"vocal_start_s": 1.2,
"vocal_end_s": 18.5,
"source_duration_seconds": 20
}'
Response example
{
"success": true,
"message": "",
"data": {
"voice": {
"voice_task_id": 123,
"voice_name": "My Chinese female voice",
"language": "zh",
"validate_status": "submitted",
"is_available": false,
"status": "validate_submitted",
"stage": "validate_submitted",
"created_at": 1780480000,
"updated_at": 1780480000
}
}
}
2. Query a voice task
Endpoint: GET /api/voice/clone/tasks/{voice_task_id}
Request example
curl https://www.suno-api.io/api/voice/clone/tasks/123 \
-H "Authorization: Bearer YOUR_API_KEY"
Response example
{
"success": true,
"message": "",
"data": {
"voice": {
"voice_task_id": 123,
"voice_name": "My Chinese female voice",
"validate_info": "Please read out the verification text returned here",
"validate_status": "success",
"is_available": false,
"status": "validate_ready",
"stage": "validate_callback"
}
}
}
3. Regenerate the verification text
Endpoint: POST /api/voice/clone/tasks/{voice_task_id}/regenerate
Use this when the verification text is unsuitable to read out loud or when validation has to be redone.
curl -X POST https://www.suno-api.io/api/voice/clone/tasks/123/regenerate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
4. Submit the verification audio and create the voice
Endpoint: POST /api/voice/clone/tasks/{voice_task_id}/generate
Body parameters
| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
verify_url |
string | No | - | URL of the audio read out from the verification text. Either this or file_base64 |
file_base64 |
string | No | - | Base64 verification audio. Either this or verify_url |
file_name |
string | No | - | File name; recommended when using file_base64 |
voice_name |
string | No | task name | Voice name |
description |
string | No | task description | Voice description |
style |
string | No | task style | Voice style |
singer_skill_level |
string | No | task setting | Singing level |
Request example
curl -X POST https://www.suno-api.io/api/voice/clone/tasks/123/generate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"verify_url": "https://example.com/verify-voice.wav",
"voice_name": "My Chinese female voice"
}'
5. Check whether the voice is usable
Endpoint: POST /api/voice/clone/tasks/{voice_task_id}/check
curl -X POST https://www.suno-api.io/api/voice/clone/tasks/123/check \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
When the task is usable, is_available in the response is true and a voice_id is returned.
6. Delete a voice
Endpoint: DELETE /api/voice/clone/voices/{voice_task_id}
Billing: free.
curl -X DELETE https://www.suno-api.io/api/voice/clone/voices/123 \
-H "Authorization: Bearer YOUR_API_KEY"
Response example
{
"success": true,
"message": "",
"data": {
"voice_task_id": 123,
"deleted": true
}
}
| Field | Type | Notes |
|---|---|---|
| voice_task_id | number | ID of the deleted voice task |
| deleted | boolean | Always true, meaning the delete request has been accepted |
What happens after deletion
- The voice can no longer be used to generate new songs: calling
POST /api/music/generate-with-voicewith thisvoice_task_id(or itsvoice_id) is rejected with the messageselected voice is not ready, and nothing is charged. - Songs already generated with it are completely unaffected: playback, download, extend, replace and separation all keep working.
- The voice task disappears from queries:
GET /api/voice/clone/tasks/{voice_task_id}returnsrecord not found. - The source audio is kept under the platform's permanent-retention policy (since 2026-09-23, deleting no longer cleans up the vocal sample you uploaded), but that does not mean it can be restored: this old task has ended, and continuing with the same voice means going through the clone flow again, which yields a new
voice_task_id. - Deleting twice: deleting the same task again returns
record not found(it is already in the deleted state and can no longer be found).
7. Generate a song with a cloned voice
Endpoint: POST /api/music/generate-with-voice
Billing: ¥1.2 per call.
Body parameters
| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
voice_task_id |
number | Yes | - | ID of a usable voice task |
voice_id |
string | No | - | Optional verification field; when sent it must match the voice_id on the task |
customMode |
boolean | No | false |
false is simple mode, true is advanced mode |
prompt |
string | Yes | - | In simple mode the song description; in advanced mode the lyrics. Neither may be empty |
style |
string | Yes in advanced mode | - | Style tags; must not be empty when customMode=true |
title |
string | Yes in advanced mode | - | Song title; must not be empty when customMode=true |
negativeTags |
string | No | - | Negative style |
instrumental |
boolean | No | false |
Compatibility field; cloned-voice generation is always treated as a vocal song |
waitAudio |
boolean | No | false |
Compatibility field; this endpoint always returns placeholder tasks asynchronously and does not wait for the audio |
model |
string | No | suno-v6 |
Ordinary song generation model; suno-v6, suno-v6-wild or suno-v6-mini |
vocalGender |
string | No | - | Vocal gender preference |
lyricsMode |
string | No | - | Compatibility field; the current cloned-voice submission path does not change the lyrics mode on its own |
weirdnessConstraint |
number | No | - | Creative strength |
styleWeight |
number | No | - | Style weight |
audioWeight |
number | No | platform default | Audio Influence (how much the reference audio matters), range 0.0-1.0. When not sent, the platform default applies (equivalent to 25% in the official interface); 0 is a valid value meaning "do not lean towards the reference at all". It is tightly coupled to sourceClipId below: with a source it points at the reference audio, without one it points at the cloned voice — the platform has only this one slider covering both cases, so do not split it into two parameters per use case |
sourceClipId |
string | No | - | The real workspace clip ID of the source song. Sending it switches to a cloned-voice cover; omitting it is ordinary cloned-voice generation |
sourceAudioUrl |
string | No | - | Source display field; it takes no part in ownership or account decisions, the server uses its database record |
sourceTitle |
string | No | - | Source display field; it takes no part in ownership or account decisions |
clientSubmissionId |
string | No | - | Create UI compatibility field; reliable de-duplication on the customer API must use the Idempotency-Key header |
suno-v6, suno-v6-wild and suno-v6-mini are supported; an empty model is treated as suno-v6. The old V5/V5.5 models are retired, but historical tasks may still show the old model names.
The shared request structure also parses Create UI compatibility fields such as task, soundType, soundLoop, soundBpm, soundKey, voiceTaskId and voiceId, but they are not valid customer parameters for this endpoint: a voice task must be sent as voice_task_id, an optional voice verification must be sent as voice_id, and voice music generation never reads the sound fields.
How to fill in the generation parameters
- With
customMode=false,promptholds the song description; withcustomMode=true,promptholds the full lyrics, andstyleandtitlemust be filled in as well. Do not send lyrics into the description field of simple mode, or treat a song description as advanced-mode lyrics. weirdnessConstraintandstyleWeightare both decimal ratios from0.0to1.0; you cannot send50or50%.0.5is a reasonable balanced value; omitting them means "unspecified", while0is a valid explicit value.vocalGenderaccepts onlym,male,forfemale.instrumentalis a compatibility-only field on this endpoint — cloned-voice generation is always treated as a vocal song.waitAudiodoes not change behaviour here; the endpoint always returns placeholder tasks asynchronously. An emptyaudio_urlin the initial result is normal: query withclient_request_idand read the audio address only after the result completes.
Header parameters
| Header | Required | Notes |
|---|---|---|
Authorization: Bearer ... |
Yes | Customer API token |
Content-Type: application/json |
Yes | JSON request body |
Idempotency-Key |
No, strongly recommended | Up to 128 characters. The same user, token, endpoint, key and request body are billed and create a task only once |
Idempotency-Key behaviour:
- The first request writes a persistent idempotency record before billing;
- If the same key with the same request has already completed, the first acceptance response is replayed, with no second charge and no second task;
- The same key with a different request body is rejected;
- The same key while still processing returns a stable "processing" error, and only exposes a safe
client_request_idonce one has been generated; - After the first request under a given key fails, it stays failed; retrying requires a new key.
sourceClipId cover requirements
Source covers on the customer API are handled entirely server-side: the server deals with source-song access and the customer passes no account information. Whether a cover is allowed is decided by the actual endpoint response.
The source must belong to the current API user, be a completed workspace song that is not pending: and have usable audio. Ordinary generation, ordinary upload sources and enhanced-upload final songs are supported; enhanced-upload intermediate records are rejected before billing. The server only accepts the source song ID submitted by the customer and never an account ID from the customer; an unavailable or unfinished source returns an error before billing.
Request example
curl -X POST https://www.suno-api.io/api/music/generate-with-voice \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"voice_task_id": 123,
"customMode": true,
"prompt": "Write a Chinese pop song about the seaside on a summer night",
"style": "Mandopop, warm piano, emotional",
"title": "Sea breeze on a summer night",
"negativeTags": "noise, low quality",
"instrumental": false,
"model": "suno-v6"
}'
Response example
{
"success": true,
"message": "",
"data": {
"client_request_id": "cu_1780480000_abcd1234",
"items": [
{
"placeholder_id": "pending:cu_1780480000_abcd1234:0",
"client_request_id": "cu_1780480000_abcd1234",
"client_request_index": 0,
"status": "submitted",
"type": "voice_generate",
"title": "Sea breeze on a summer night",
"prompt": "Write a Chinese pop song about the seaside on a summer night"
},
{
"placeholder_id": "pending:cu_1780480000_abcd1234:1",
"client_request_id": "cu_1780480000_abcd1234",
"client_request_index": 1,
"status": "submitted",
"type": "voice_generate",
"title": "Sea breeze on a summer night",
"prompt": "Write a Chinese pop song about the seaside on a summer night"
}
],
"pre_consumed_quota": 600000,
"billing_source": "wallet"
}
}
About placeholder tasks and the final song_id
generate-with-voice is an asynchronous generation endpoint. A successful response only means the generation task has been submitted, not that the song has finished generating.
Key fields in the response:
| Field | Notes |
|---|---|
client_request_id |
Tracking ID of this generation request. One request usually generates 2 songs, and both results share this client_request_id. |
items[].placeholder_id |
Platform-local placeholder ID, usually in the form pending:{client_request_id}:{index}. It is not the final song ID. |
items[].client_request_index |
Result index within the same request, usually 0 and 1. |
items[].status |
Initial status after submission, for example submitted. Later success or failure follows the final task record. |
Note: a placeholder_id starting with pending: cannot be used as the final song_id, nor passed to /api/music/query or the download endpoints. Calling /api/music/query with only pending:* values may return an empty array [], because the real song is not finished yet or the placeholder task has not been replaced by the final song ID.
Wrong example:
{
"song_ids": "pending:cu_1780480000_abcd1234:0"
}
Correct flow:
- Call
POST /api/music/generate-with-voiceto submit the voice-generation task. - Store
client_request_id,items[].placeholder_idanditems[].client_request_indexfrom the response. - Poll
GET /api/music/generate-with-voice/results?client_request_id=cu_xxx. - Once
items[].song_idhas a value that does not start withpending:, call/api/music/query,/api/music/download-fileor/api/music/download-all.
The current version adds a public query endpoint:
GET /api/music/generate-with-voice/results?client_request_id=cu_xxx
It returns the task results for that client_request_id under the current user, so customers can look up the final song_id themselves. In the returned list:
song_idis the real song ID;placeholder_idonly appears while the task is still a placeholder;- a value starting with
pending:cannot be used with/api/music/queryor the download endpoints.
If you only stored the client_request_id or a pending:* placeholder ID, call this results endpoint first; if the real song_id is still not found, send the client_request_id to technical support for help.
Query the results of voice generation
Endpoint: GET /api/music/generate-with-voice/results
Billing: free.
Query parameters
| Parameter | Type | Required | Notes |
|---|---|---|---|
client_request_id |
string | Yes | The request tracking ID returned by generate-with-voice |
Request example
curl -X GET "https://www.suno-api.io/api/music/generate-with-voice/results?client_request_id=cu_1780480000_abcd1234" \
-H "Authorization: Bearer YOUR_API_KEY"
Processing response example
{
"success": true,
"message": "",
"data": {
"client_request_id": "cu_1780480000_abcd1234",
"status": "processing",
"items": [
{
"song_id": "",
"placeholder_id": "pending:cu_1780480000_abcd1234:0",
"client_request_id": "cu_1780480000_abcd1234",
"client_request_index": 0,
"status": "processing",
"type": "voice_generate",
"title": "Sea breeze on a summer night"
}
]
}
}
Completed response example
{
"success": true,
"message": "",
"data": {
"client_request_id": "cu_1780480000_abcd1234",
"status": "completed",
"items": [
{
"song_id": "song_abc123",
"client_request_id": "cu_1780480000_abcd1234",
"client_request_index": 0,
"status": "completed",
"type": "voice_generate",
"title": "Sea breeze on a summer night",
"audio_url": "https://...",
"image_url": "https://...",
"duration": 180.5
}
]
}
}
Top-level status values
| Value | Notes |
|---|---|
not_found |
No task record for that client_request_id exists under the current user yet |
processing |
At least one result is unfinished; keep polling |
completed |
All results are done; the song_id can be queried or downloaded |
partial |
Some finished, some failed; handle the completed song_id values first |
failed |
All results failed; check items[].error_message |
8. Download a single file
Endpoint: POST /api/music/download-file
Body parameters
| Parameter | Type | Required | Notes |
|---|---|---|---|
song_id |
string | Yes | Song ID |
kind |
string | Yes | Download type: audio, cover, wav, video |
Request example
curl -X POST https://www.suno-api.io/api/music/download-file \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"song_id": "song_abc123",
"kind": "audio"
}' \
--output song.mp3
The response is a file stream; Content-Type and the file name follow what the backend returns.
9. Bundle download of song assets
Endpoint: POST /api/music/download-all
Body parameters
| Parameter | Type | Required | Notes |
|---|---|---|---|
song_id |
string | Yes | Song ID |
Request example
curl -X POST https://www.suno-api.io/api/music/download-all \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"song_id": "song_abc123"
}' \
--output song.zip
The bundle usually contains the audio, the cover and metadata.json; if some asset type has not been generated yet it is left out of the archive.
Common errors
| message | Notes |
|---|---|
voice audio is required |
Neither voice_url nor file_base64 was supplied when submitting the source voice |
invalid voice task id |
The voice task ID in the path is invalid |
voice validation is not ready |
The verification text is not available yet, so the verification audio cannot be submitted |
selected voice is not ready |
The chosen voice cannot be used to generate songs yet (not ready, deleted, or not on the current account) |
selected voice does not match voice task |
The voice_id in the request does not match the task |
voice task is required |
voice_task_id is missing when generating a voice song |
record not found |
The task / song does not exist, does not belong to the account behind the current API key, or has already been deleted (querying this task after deleting the voice shows the same thing) |
Errors from this endpoint group always return HTTP 200: judge success from the
successfield in the body (falsemeans failure, with the reason inmessage) and do not look only at the HTTP status code. The full semantics of deleting a voice (whether it remains usable, whether it can be restored) are in section 6.
Get an API key
Create an API key in the console after signing up. ¥0.6 per run returns 2 tracks, downloads are unlimited, and no phone number is required.
Get API key Back to overview