Suno Voice Create Custom Voice API
curl --request POST \
--url https://api.sunoapi.org/api/v1/voice/generate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"taskId": "voice_create_001",
"verifyUrl": "https://example.com/audio/verify_read.mp3",
"voiceName": "My Voice",
"description": "created from uploaded voice",
"style": "Pop, Female Vocal",
"singerSkillLevel": "beginner",
"callBackUrl": "https://example.com/callback/suno/voice_create"
}
'import requests
url = "https://api.sunoapi.org/api/v1/voice/generate"
payload = {
"taskId": "voice_create_001",
"verifyUrl": "https://example.com/audio/verify_read.mp3",
"voiceName": "My Voice",
"description": "created from uploaded voice",
"style": "Pop, Female Vocal",
"singerSkillLevel": "beginner",
"callBackUrl": "https://example.com/callback/suno/voice_create"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
taskId: 'voice_create_001',
verifyUrl: 'https://example.com/audio/verify_read.mp3',
voiceName: 'My Voice',
description: 'created from uploaded voice',
style: 'Pop, Female Vocal',
singerSkillLevel: 'beginner',
callBackUrl: 'https://example.com/callback/suno/voice_create'
})
};
fetch('https://api.sunoapi.org/api/v1/voice/generate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sunoapi.org/api/v1/voice/generate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'taskId' => 'voice_create_001',
'verifyUrl' => 'https://example.com/audio/verify_read.mp3',
'voiceName' => 'My Voice',
'description' => 'created from uploaded voice',
'style' => 'Pop, Female Vocal',
'singerSkillLevel' => 'beginner',
'callBackUrl' => 'https://example.com/callback/suno/voice_create'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.sunoapi.org/api/v1/voice/generate"
payload := strings.NewReader("{\n \"taskId\": \"voice_create_001\",\n \"verifyUrl\": \"https://example.com/audio/verify_read.mp3\",\n \"voiceName\": \"My Voice\",\n \"description\": \"created from uploaded voice\",\n \"style\": \"Pop, Female Vocal\",\n \"singerSkillLevel\": \"beginner\",\n \"callBackUrl\": \"https://example.com/callback/suno/voice_create\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.sunoapi.org/api/v1/voice/generate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"taskId\": \"voice_create_001\",\n \"verifyUrl\": \"https://example.com/audio/verify_read.mp3\",\n \"voiceName\": \"My Voice\",\n \"description\": \"created from uploaded voice\",\n \"style\": \"Pop, Female Vocal\",\n \"singerSkillLevel\": \"beginner\",\n \"callBackUrl\": \"https://example.com/callback/suno/voice_create\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sunoapi.org/api/v1/voice/generate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"taskId\": \"voice_create_001\",\n \"verifyUrl\": \"https://example.com/audio/verify_read.mp3\",\n \"voiceName\": \"My Voice\",\n \"description\": \"created from uploaded voice\",\n \"style\": \"Pop, Female Vocal\",\n \"singerSkillLevel\": \"beginner\",\n \"callBackUrl\": \"https://example.com/callback/suno/voice_create\"\n}"
response = http.request(request)
puts response.read_body{
"code": 200,
"msg": "success",
"data": {
"taskId": "xxx_task_id_xxx"
}
}Suno Voice
Suno Voice Create Custom Voice
Generate a reusable Suno custom voice from the user’s verification recording.
POST
/
api
/
v1
/
voice
/
generate
Suno Voice Create Custom Voice API
curl --request POST \
--url https://api.sunoapi.org/api/v1/voice/generate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"taskId": "voice_create_001",
"verifyUrl": "https://example.com/audio/verify_read.mp3",
"voiceName": "My Voice",
"description": "created from uploaded voice",
"style": "Pop, Female Vocal",
"singerSkillLevel": "beginner",
"callBackUrl": "https://example.com/callback/suno/voice_create"
}
'import requests
url = "https://api.sunoapi.org/api/v1/voice/generate"
payload = {
"taskId": "voice_create_001",
"verifyUrl": "https://example.com/audio/verify_read.mp3",
"voiceName": "My Voice",
"description": "created from uploaded voice",
"style": "Pop, Female Vocal",
"singerSkillLevel": "beginner",
"callBackUrl": "https://example.com/callback/suno/voice_create"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
taskId: 'voice_create_001',
verifyUrl: 'https://example.com/audio/verify_read.mp3',
voiceName: 'My Voice',
description: 'created from uploaded voice',
style: 'Pop, Female Vocal',
singerSkillLevel: 'beginner',
callBackUrl: 'https://example.com/callback/suno/voice_create'
})
};
fetch('https://api.sunoapi.org/api/v1/voice/generate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sunoapi.org/api/v1/voice/generate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'taskId' => 'voice_create_001',
'verifyUrl' => 'https://example.com/audio/verify_read.mp3',
'voiceName' => 'My Voice',
'description' => 'created from uploaded voice',
'style' => 'Pop, Female Vocal',
'singerSkillLevel' => 'beginner',
'callBackUrl' => 'https://example.com/callback/suno/voice_create'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.sunoapi.org/api/v1/voice/generate"
payload := strings.NewReader("{\n \"taskId\": \"voice_create_001\",\n \"verifyUrl\": \"https://example.com/audio/verify_read.mp3\",\n \"voiceName\": \"My Voice\",\n \"description\": \"created from uploaded voice\",\n \"style\": \"Pop, Female Vocal\",\n \"singerSkillLevel\": \"beginner\",\n \"callBackUrl\": \"https://example.com/callback/suno/voice_create\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.sunoapi.org/api/v1/voice/generate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"taskId\": \"voice_create_001\",\n \"verifyUrl\": \"https://example.com/audio/verify_read.mp3\",\n \"voiceName\": \"My Voice\",\n \"description\": \"created from uploaded voice\",\n \"style\": \"Pop, Female Vocal\",\n \"singerSkillLevel\": \"beginner\",\n \"callBackUrl\": \"https://example.com/callback/suno/voice_create\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sunoapi.org/api/v1/voice/generate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"taskId\": \"voice_create_001\",\n \"verifyUrl\": \"https://example.com/audio/verify_read.mp3\",\n \"voiceName\": \"My Voice\",\n \"description\": \"created from uploaded voice\",\n \"style\": \"Pop, Female Vocal\",\n \"singerSkillLevel\": \"beginner\",\n \"callBackUrl\": \"https://example.com/callback/suno/voice_create\"\n}"
response = http.request(request)
puts response.read_body{
"code": 200,
"msg": "success",
"data": {
"taskId": "xxx_task_id_xxx"
}
}Usage Guide
- Call this API after the validation phrase is generated and the user has recorded the verification audio.
- The validation phrase is the
validateInfotext returned by the server. For best voice generation results, have the user record the server-provided phrase in a singing voice rather than plain speech. - Submit the original validation
taskIdand the verification audio URL inverifyUrl. - Optional metadata such as
voiceName,description,style, andsingerSkillLevelhelps organize and tune the generated voice. - The API returns a
taskId; use it to query the finalvoiceId. - When
callBackUrlis provided, the system sends a POST callback when the voice is created or the task fails. The callback URL must be publicly accessible and return HTTP 200 within 15 seconds.
Workflow
- Generate and retrieve the validation phrase.
- Record clear verification audio for the phrase; singing is recommended for best voice generation results.
- Upload or host the verification audio and pass the URL as
verifyUrl. - Submit the voice generation task and store the returned
taskId. - Receive
voiceIdthrough the record query API or callback when the task succeeds.
Callback
Custom Voice Generation Callbacks
Learn the callback payload sent when the custom voice is created or the task fails
Developer Notes
taskIdmust come from the validation phrase task for the same voice workflow.verifyUrlshould point to the user’s recording of the exact validation phrase returned by the server; for best results, recording it in a singing voice is recommended.- After receiving
voiceId, use the availability check endpoint before starting generation workflows that depend on the custom voice.
Authorizations
API Authentication
All endpoints require authentication using Bearer Token.
Get API Key
- Visit the API Key Management Page to obtain your API Key
Usage
Add to request headers:
Authorization: Bearer YOUR_API_KEY
Note:
- Keep your API Key secure and do not share it with others
- If you suspect your API Key has been compromised, reset it immediately from the management page
Body
application/json
Task ID
Audio URL for the user's recording of the validation phrase returned by the server; singing is recommended for best results [Required]
Voice name
Voice description
Voice style
Singer skill level. Supported: beginner, intermediate, advanced, professional
Available options:
beginner, intermediate, advanced, professional Callback URL used to receive custom voice generation results. When the task succeeds, the callback includes the generated voiceId; when it fails, it includes errorCode and errorMessage. The URL must be publicly accessible and return HTTP 200 within 15 seconds. For the payload format, see Custom Voice Generation Callbacks.
