curl --request POST \
--url https://api.sunoapi.org/api/v1/generate/upload-extend \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"uploadUrl": "https://storage.example.com/upload",
"defaultParamFlag": true,
"model": "V4_5ALL",
"callBackUrl": "https://api.example.com/callback",
"instrumental": false,
"prompt": "Extend the music with more relaxing notes",
"style": "Classical",
"title": "Peaceful Piano Extended",
"continueAt": 60,
"personaId": "persona_123",
"personaModel": "style_persona",
"negativeTags": "Relaxing Piano",
"vocalGender": "m",
"styleWeight": 0.65,
"weirdnessConstraint": 0.65,
"audioWeight": 0.65
}
'import requests
url = "https://api.sunoapi.org/api/v1/generate/upload-extend"
payload = {
"uploadUrl": "https://storage.example.com/upload",
"defaultParamFlag": True,
"model": "V4_5ALL",
"callBackUrl": "https://api.example.com/callback",
"instrumental": False,
"prompt": "Extend the music with more relaxing notes",
"style": "Classical",
"title": "Peaceful Piano Extended",
"continueAt": 60,
"personaId": "persona_123",
"personaModel": "style_persona",
"negativeTags": "Relaxing Piano",
"vocalGender": "m",
"styleWeight": 0.65,
"weirdnessConstraint": 0.65,
"audioWeight": 0.65
}
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({
uploadUrl: 'https://storage.example.com/upload',
defaultParamFlag: true,
model: 'V4_5ALL',
callBackUrl: 'https://api.example.com/callback',
instrumental: false,
prompt: 'Extend the music with more relaxing notes',
style: 'Classical',
title: 'Peaceful Piano Extended',
continueAt: 60,
personaId: 'persona_123',
personaModel: 'style_persona',
negativeTags: 'Relaxing Piano',
vocalGender: 'm',
styleWeight: 0.65,
weirdnessConstraint: 0.65,
audioWeight: 0.65
})
};
fetch('https://api.sunoapi.org/api/v1/generate/upload-extend', 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/generate/upload-extend",
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([
'uploadUrl' => 'https://storage.example.com/upload',
'defaultParamFlag' => true,
'model' => 'V4_5ALL',
'callBackUrl' => 'https://api.example.com/callback',
'instrumental' => false,
'prompt' => 'Extend the music with more relaxing notes',
'style' => 'Classical',
'title' => 'Peaceful Piano Extended',
'continueAt' => 60,
'personaId' => 'persona_123',
'personaModel' => 'style_persona',
'negativeTags' => 'Relaxing Piano',
'vocalGender' => 'm',
'styleWeight' => 0.65,
'weirdnessConstraint' => 0.65,
'audioWeight' => 0.65
]),
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/generate/upload-extend"
payload := strings.NewReader("{\n \"uploadUrl\": \"https://storage.example.com/upload\",\n \"defaultParamFlag\": true,\n \"model\": \"V4_5ALL\",\n \"callBackUrl\": \"https://api.example.com/callback\",\n \"instrumental\": false,\n \"prompt\": \"Extend the music with more relaxing notes\",\n \"style\": \"Classical\",\n \"title\": \"Peaceful Piano Extended\",\n \"continueAt\": 60,\n \"personaId\": \"persona_123\",\n \"personaModel\": \"style_persona\",\n \"negativeTags\": \"Relaxing Piano\",\n \"vocalGender\": \"m\",\n \"styleWeight\": 0.65,\n \"weirdnessConstraint\": 0.65,\n \"audioWeight\": 0.65\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/generate/upload-extend")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"uploadUrl\": \"https://storage.example.com/upload\",\n \"defaultParamFlag\": true,\n \"model\": \"V4_5ALL\",\n \"callBackUrl\": \"https://api.example.com/callback\",\n \"instrumental\": false,\n \"prompt\": \"Extend the music with more relaxing notes\",\n \"style\": \"Classical\",\n \"title\": \"Peaceful Piano Extended\",\n \"continueAt\": 60,\n \"personaId\": \"persona_123\",\n \"personaModel\": \"style_persona\",\n \"negativeTags\": \"Relaxing Piano\",\n \"vocalGender\": \"m\",\n \"styleWeight\": 0.65,\n \"weirdnessConstraint\": 0.65,\n \"audioWeight\": 0.65\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sunoapi.org/api/v1/generate/upload-extend")
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 \"uploadUrl\": \"https://storage.example.com/upload\",\n \"defaultParamFlag\": true,\n \"model\": \"V4_5ALL\",\n \"callBackUrl\": \"https://api.example.com/callback\",\n \"instrumental\": false,\n \"prompt\": \"Extend the music with more relaxing notes\",\n \"style\": \"Classical\",\n \"title\": \"Peaceful Piano Extended\",\n \"continueAt\": 60,\n \"personaId\": \"persona_123\",\n \"personaModel\": \"style_persona\",\n \"negativeTags\": \"Relaxing Piano\",\n \"vocalGender\": \"m\",\n \"styleWeight\": 0.65,\n \"weirdnessConstraint\": 0.65,\n \"audioWeight\": 0.65\n}"
response = http.request(request)
puts response.read_body{
"code": 200,
"msg": "success",
"data": {
"taskId": "5c79****be8e"
}
}Upload And Extend Audio
This API extends audio tracks while preserving the original style of the audio track. It includes Suno’s upload functionality, allowing users to upload audio files for processing. The expected result is a longer track that seamlessly continues the input style.
curl --request POST \
--url https://api.sunoapi.org/api/v1/generate/upload-extend \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"uploadUrl": "https://storage.example.com/upload",
"defaultParamFlag": true,
"model": "V4_5ALL",
"callBackUrl": "https://api.example.com/callback",
"instrumental": false,
"prompt": "Extend the music with more relaxing notes",
"style": "Classical",
"title": "Peaceful Piano Extended",
"continueAt": 60,
"personaId": "persona_123",
"personaModel": "style_persona",
"negativeTags": "Relaxing Piano",
"vocalGender": "m",
"styleWeight": 0.65,
"weirdnessConstraint": 0.65,
"audioWeight": 0.65
}
'import requests
url = "https://api.sunoapi.org/api/v1/generate/upload-extend"
payload = {
"uploadUrl": "https://storage.example.com/upload",
"defaultParamFlag": True,
"model": "V4_5ALL",
"callBackUrl": "https://api.example.com/callback",
"instrumental": False,
"prompt": "Extend the music with more relaxing notes",
"style": "Classical",
"title": "Peaceful Piano Extended",
"continueAt": 60,
"personaId": "persona_123",
"personaModel": "style_persona",
"negativeTags": "Relaxing Piano",
"vocalGender": "m",
"styleWeight": 0.65,
"weirdnessConstraint": 0.65,
"audioWeight": 0.65
}
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({
uploadUrl: 'https://storage.example.com/upload',
defaultParamFlag: true,
model: 'V4_5ALL',
callBackUrl: 'https://api.example.com/callback',
instrumental: false,
prompt: 'Extend the music with more relaxing notes',
style: 'Classical',
title: 'Peaceful Piano Extended',
continueAt: 60,
personaId: 'persona_123',
personaModel: 'style_persona',
negativeTags: 'Relaxing Piano',
vocalGender: 'm',
styleWeight: 0.65,
weirdnessConstraint: 0.65,
audioWeight: 0.65
})
};
fetch('https://api.sunoapi.org/api/v1/generate/upload-extend', 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/generate/upload-extend",
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([
'uploadUrl' => 'https://storage.example.com/upload',
'defaultParamFlag' => true,
'model' => 'V4_5ALL',
'callBackUrl' => 'https://api.example.com/callback',
'instrumental' => false,
'prompt' => 'Extend the music with more relaxing notes',
'style' => 'Classical',
'title' => 'Peaceful Piano Extended',
'continueAt' => 60,
'personaId' => 'persona_123',
'personaModel' => 'style_persona',
'negativeTags' => 'Relaxing Piano',
'vocalGender' => 'm',
'styleWeight' => 0.65,
'weirdnessConstraint' => 0.65,
'audioWeight' => 0.65
]),
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/generate/upload-extend"
payload := strings.NewReader("{\n \"uploadUrl\": \"https://storage.example.com/upload\",\n \"defaultParamFlag\": true,\n \"model\": \"V4_5ALL\",\n \"callBackUrl\": \"https://api.example.com/callback\",\n \"instrumental\": false,\n \"prompt\": \"Extend the music with more relaxing notes\",\n \"style\": \"Classical\",\n \"title\": \"Peaceful Piano Extended\",\n \"continueAt\": 60,\n \"personaId\": \"persona_123\",\n \"personaModel\": \"style_persona\",\n \"negativeTags\": \"Relaxing Piano\",\n \"vocalGender\": \"m\",\n \"styleWeight\": 0.65,\n \"weirdnessConstraint\": 0.65,\n \"audioWeight\": 0.65\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/generate/upload-extend")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"uploadUrl\": \"https://storage.example.com/upload\",\n \"defaultParamFlag\": true,\n \"model\": \"V4_5ALL\",\n \"callBackUrl\": \"https://api.example.com/callback\",\n \"instrumental\": false,\n \"prompt\": \"Extend the music with more relaxing notes\",\n \"style\": \"Classical\",\n \"title\": \"Peaceful Piano Extended\",\n \"continueAt\": 60,\n \"personaId\": \"persona_123\",\n \"personaModel\": \"style_persona\",\n \"negativeTags\": \"Relaxing Piano\",\n \"vocalGender\": \"m\",\n \"styleWeight\": 0.65,\n \"weirdnessConstraint\": 0.65,\n \"audioWeight\": 0.65\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sunoapi.org/api/v1/generate/upload-extend")
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 \"uploadUrl\": \"https://storage.example.com/upload\",\n \"defaultParamFlag\": true,\n \"model\": \"V4_5ALL\",\n \"callBackUrl\": \"https://api.example.com/callback\",\n \"instrumental\": false,\n \"prompt\": \"Extend the music with more relaxing notes\",\n \"style\": \"Classical\",\n \"title\": \"Peaceful Piano Extended\",\n \"continueAt\": 60,\n \"personaId\": \"persona_123\",\n \"personaModel\": \"style_persona\",\n \"negativeTags\": \"Relaxing Piano\",\n \"vocalGender\": \"m\",\n \"styleWeight\": 0.65,\n \"weirdnessConstraint\": 0.65,\n \"audioWeight\": 0.65\n}"
response = http.request(request)
puts response.read_body{
"code": 200,
"msg": "success",
"data": {
"taskId": "5c79****be8e"
}
}Parameter Usage Guide
- instrumental determines whether the audio is instrumental (without lyrics) and defaults to false
- prompt is optional in all cases; when provided, it is used as a generation prompt
- When defaultParamFlag is true (Custom Parameters):
- If instrumental is true: only style, title, and uploadUrl are required; prompt and vocalGender are not required
- If instrumental is false: style, title, and uploadUrl are required; prompt is optional and used as a generation prompt when provided, and vocalGender is not required
- prompt length limit by model:
- V4: Maximum 3000 characters
- V4_5, V4_5PLUS, V4_5ALL, V5 & V5_5: Maximum 5000 characters
- style length limit by model:
- V4: Maximum 200 characters
- V4_5, V4_5PLUS, V4_5ALL, V5 & V5_5: Maximum 1000 characters
- title length limit by model:
- V4 & V4_5ALL: Maximum 80 characters
- V4_5, V4_5PLUS, V5 & V5_5: Maximum 100 characters
- continueAt: the time point in seconds from which to start extending (must be greater than 0 and less than the uploaded audio duration)
- uploadUrl: specifies the upload location for audio files; ensure uploaded audio does not exceed 8 minutes.
- Important: When using the V4_5ALL model, the uploaded audio file must not exceed 1 minute in length.
- When defaultParamFlag is false (Default Parameters):
- Regardless of instrumental setting, only uploadUrl is required
- prompt is optional
- If instrumental is false, lyrics will be generated automatically
- Other parameters will use the original audio’s parameters
Optional Parameters
- personaId (string): Persona ID or Suno Voice
voiceIdto apply when using custom parameters. If you use a Voice-generated ID, setpersonaModeltovoice_persona. - personaModel (string): Persona type. Use
style_personafor Generate Persona IDs, orvoice_personafor Suno Voice IDs.
Developer Notes
- Generated files will be retained for 14 days
- Model version must be consistent with the source music
- V4_5ALL Model Upload Limit: When using the V4_5ALL model, the uploaded audio file must not exceed 1 minute in length.
- This feature is ideal for creating longer works by extending existing music
- uploadUrl parameter specifies the upload location for audio files; provide a valid URL.
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
The URL for uploading audio files, required regardless of whether defaultParamFlag is true or false. Ensure the uploaded audio does not exceed 8 minutes in length.
"https://storage.example.com/upload"
Enables custom mode for advanced audio generation settings.
- Set to
trueto use custom parameter mode (requiresstyle,title, anduploadUrl).promptis optional in all cases and, when provided, is used as a prompt. - Set to
falseto use non-custom mode (onlyuploadUrlis required).promptremains optional. Wheninstrumentalisfalse, lyrics are generated automatically.
true
Model version to use, must be consistent with the source audio
V4, V4_5, V4_5PLUS, V4_5ALL, V5, V5_5 "V4_5ALL"
The URL to receive task completion notifications when music extension is complete.
- For detailed callback format and implementation guide, see Upload and Extend Audio Callbacks
- Alternatively, you can use the get music generation details endpoint to poll task status
"https://api.example.com/callback"
Determines whether the audio should be instrumental (without lyrics).
- In custom parameter mode (
defaultParamFlag: true):- If
true: onlystyle,title, anduploadUrlare required;promptandvocalGenderdo not need to be provided. - If
false:style,title, anduploadUrlare required;promptis optional and, when provided, is used as a prompt;vocalGenderdoes not need to be provided.
- If
- In non-custom parameter mode (
defaultParamFlag: false): required fields are unaffected (onlyuploadUrlis required), andpromptremains optional. Iffalse, lyrics are generated automatically.
Optional. Defaults tofalse.
false
Describes how the music should be extended. Optional in all cases. When provided, it is used as a prompt. Character limits by model:
- V4: Maximum 3000 characters
- V4_5, V4_5PLUS, V4_5ALL, V5 & V5_5: Maximum 5000 characters
"Extend the music with more relaxing notes"
Music style, e.g., Jazz, Classical, Electronic. Required when defaultParamFlag is true. Character limits by model:
- V4: Maximum 200 characters
- V4_5, V4_5PLUS, V4_5ALL, V5 & V5_5: Maximum 1000 characters
"Classical"
Music title. Required when defaultParamFlag is true. Character limits by model:
- V4 & V4_5ALL: Maximum 80 characters
- V4_5, V4_5PLUS, V5 & V5_5: Maximum 100 characters
"Peaceful Piano Extended"
The time point (in seconds) from which to start extending the music.
- Required when
defaultParamFlagistrue. - Value range: greater than 0 and less than the total duration of the uploaded audio.
- Specifies the position in the original track where the extension should begin.
60
Only available when custom parameters are enabled. Persona ID to apply to the generated music. Optional. You can use either:
- A Persona ID generated by the Generate Persona endpoint. Use
personaModel: style_personaor omitpersonaModelto use the default. - A
voiceIdgenerated by the Suno Voice workflow. When using a voice-generated ID, you must setpersonaModel: voice_persona.
"persona_123"
Persona model type to apply when using personaId. Optional.
style_persona(default): Use this for Persona IDs generated by the Generate Persona endpoint.voice_persona: Use this whenpersonaIdis avoiceIdgenerated by Suno Voice. This option is only available with V5 and V5_5 models.
style_persona, voice_persona "style_persona"
Music styles to exclude from generation
"Relaxing Piano"
Preferred vocal gender. Optional; no value is required for this endpoint.
m, f "m"
Weight of the provided style guidance. Range 0.00–1.00.
0 <= x <= 1Must be a multiple of 0.010.65
Constraint on creative deviation/novelty. Range 0.00–1.00.
0 <= x <= 1Must be a multiple of 0.010.65
Weight of the input audio influence (where applicable). Range 0.00–1.00.
0 <= x <= 1Must be a multiple of 0.010.65
Callbacks
Response
Request successful
Status Codes
- ✅ 200 - Request successful
- ⚠️ 400 - Invalid parameters
- ⚠️ 401 - Unauthorized access
- ⚠️ 404 - Invalid request method or path
- ⚠️ 405 - Rate limit exceeded
- ⚠️ 413 - Theme or prompt too long
- ⚠️ 429 - Insufficient credits
- ⚠️ 430 - Your call frequency is too high. Please try again later.
- ⚠️ 455 - System maintenance
- ❌ 500 - Server error
200, 400, 401, 404, 405, 413, 429, 430, 455, 500 200
Error message when code != 200
"success"
Show child attributes
Show child attributes
