curl --request POST \
--url https://api.ttapi.io/suno/v1/add-stem \
--header 'Content-Type: application/json' \
--header 'TT-API-KEY: <api-key>' \
--data '
{
"mv": "chirp-v6",
"music_id": "<string>",
"prompt": "<string>",
"title": "<string>",
"tags": "rock, blues, hip-hop, r&b",
"negative_tags": "<string>",
"style_weight": 0.5,
"weirdness_constraint": 0.5,
"audio_weight": 0.5,
"variety": "normal",
"max_mode": false,
"audio_format": "mp3",
"hookUrl": "<string>",
"isStorage": true
}
'import requests
url = "https://api.ttapi.io/suno/v1/add-stem"
payload = {
"mv": "chirp-v6",
"music_id": "<string>",
"prompt": "<string>",
"title": "<string>",
"tags": "rock, blues, hip-hop, r&b",
"negative_tags": "<string>",
"style_weight": 0.5,
"weirdness_constraint": 0.5,
"audio_weight": 0.5,
"variety": "normal",
"max_mode": False,
"audio_format": "mp3",
"hookUrl": "<string>",
"isStorage": True
}
headers = {
"TT-API-KEY": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'TT-API-KEY': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
mv: 'chirp-v6',
music_id: '<string>',
prompt: '<string>',
title: '<string>',
tags: 'rock, blues, hip-hop, r&b',
negative_tags: '<string>',
style_weight: 0.5,
weirdness_constraint: 0.5,
audio_weight: 0.5,
variety: 'normal',
max_mode: false,
audio_format: 'mp3',
hookUrl: '<string>',
isStorage: true
})
};
fetch('https://api.ttapi.io/suno/v1/add-stem', 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.ttapi.io/suno/v1/add-stem",
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([
'mv' => 'chirp-v6',
'music_id' => '<string>',
'prompt' => '<string>',
'title' => '<string>',
'tags' => 'rock, blues, hip-hop, r&b',
'negative_tags' => '<string>',
'style_weight' => 0.5,
'weirdness_constraint' => 0.5,
'audio_weight' => 0.5,
'variety' => 'normal',
'max_mode' => false,
'audio_format' => 'mp3',
'hookUrl' => '<string>',
'isStorage' => true
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"TT-API-KEY: <api-key>"
],
]);
$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.ttapi.io/suno/v1/add-stem"
payload := strings.NewReader("{\n \"mv\": \"chirp-v6\",\n \"music_id\": \"<string>\",\n \"prompt\": \"<string>\",\n \"title\": \"<string>\",\n \"tags\": \"rock, blues, hip-hop, r&b\",\n \"negative_tags\": \"<string>\",\n \"style_weight\": 0.5,\n \"weirdness_constraint\": 0.5,\n \"audio_weight\": 0.5,\n \"variety\": \"normal\",\n \"max_mode\": false,\n \"audio_format\": \"mp3\",\n \"hookUrl\": \"<string>\",\n \"isStorage\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("TT-API-KEY", "<api-key>")
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.ttapi.io/suno/v1/add-stem")
.header("TT-API-KEY", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"mv\": \"chirp-v6\",\n \"music_id\": \"<string>\",\n \"prompt\": \"<string>\",\n \"title\": \"<string>\",\n \"tags\": \"rock, blues, hip-hop, r&b\",\n \"negative_tags\": \"<string>\",\n \"style_weight\": 0.5,\n \"weirdness_constraint\": 0.5,\n \"audio_weight\": 0.5,\n \"variety\": \"normal\",\n \"max_mode\": false,\n \"audio_format\": \"mp3\",\n \"hookUrl\": \"<string>\",\n \"isStorage\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ttapi.io/suno/v1/add-stem")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["TT-API-KEY"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"mv\": \"chirp-v6\",\n \"music_id\": \"<string>\",\n \"prompt\": \"<string>\",\n \"title\": \"<string>\",\n \"tags\": \"rock, blues, hip-hop, r&b\",\n \"negative_tags\": \"<string>\",\n \"style_weight\": 0.5,\n \"weirdness_constraint\": 0.5,\n \"audio_weight\": 0.5,\n \"variety\": \"normal\",\n \"max_mode\": false,\n \"audio_format\": \"mp3\",\n \"hookUrl\": \"<string>\",\n \"isStorage\": true\n}"
response = http.request(request)
puts response.read_body{
"status": "SUCCESS",
"message": "success",
"data": {
"jobId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}{
"status": "FAILED",
"message": "<string>",
"data": {}
}{
"status": "FAILED",
"message": "Wrong TT-API-KEY or email is not activated."
}Suno Add Stem API Reference
Use the Suno Add Stem API to layer an additional stem onto an existing Suno track, blending lyrics, style tags, and audio weight to enrich arrangements and multi-track production.
curl --request POST \
--url https://api.ttapi.io/suno/v1/add-stem \
--header 'Content-Type: application/json' \
--header 'TT-API-KEY: <api-key>' \
--data '
{
"mv": "chirp-v6",
"music_id": "<string>",
"prompt": "<string>",
"title": "<string>",
"tags": "rock, blues, hip-hop, r&b",
"negative_tags": "<string>",
"style_weight": 0.5,
"weirdness_constraint": 0.5,
"audio_weight": 0.5,
"variety": "normal",
"max_mode": false,
"audio_format": "mp3",
"hookUrl": "<string>",
"isStorage": true
}
'import requests
url = "https://api.ttapi.io/suno/v1/add-stem"
payload = {
"mv": "chirp-v6",
"music_id": "<string>",
"prompt": "<string>",
"title": "<string>",
"tags": "rock, blues, hip-hop, r&b",
"negative_tags": "<string>",
"style_weight": 0.5,
"weirdness_constraint": 0.5,
"audio_weight": 0.5,
"variety": "normal",
"max_mode": False,
"audio_format": "mp3",
"hookUrl": "<string>",
"isStorage": True
}
headers = {
"TT-API-KEY": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'TT-API-KEY': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
mv: 'chirp-v6',
music_id: '<string>',
prompt: '<string>',
title: '<string>',
tags: 'rock, blues, hip-hop, r&b',
negative_tags: '<string>',
style_weight: 0.5,
weirdness_constraint: 0.5,
audio_weight: 0.5,
variety: 'normal',
max_mode: false,
audio_format: 'mp3',
hookUrl: '<string>',
isStorage: true
})
};
fetch('https://api.ttapi.io/suno/v1/add-stem', 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.ttapi.io/suno/v1/add-stem",
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([
'mv' => 'chirp-v6',
'music_id' => '<string>',
'prompt' => '<string>',
'title' => '<string>',
'tags' => 'rock, blues, hip-hop, r&b',
'negative_tags' => '<string>',
'style_weight' => 0.5,
'weirdness_constraint' => 0.5,
'audio_weight' => 0.5,
'variety' => 'normal',
'max_mode' => false,
'audio_format' => 'mp3',
'hookUrl' => '<string>',
'isStorage' => true
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"TT-API-KEY: <api-key>"
],
]);
$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.ttapi.io/suno/v1/add-stem"
payload := strings.NewReader("{\n \"mv\": \"chirp-v6\",\n \"music_id\": \"<string>\",\n \"prompt\": \"<string>\",\n \"title\": \"<string>\",\n \"tags\": \"rock, blues, hip-hop, r&b\",\n \"negative_tags\": \"<string>\",\n \"style_weight\": 0.5,\n \"weirdness_constraint\": 0.5,\n \"audio_weight\": 0.5,\n \"variety\": \"normal\",\n \"max_mode\": false,\n \"audio_format\": \"mp3\",\n \"hookUrl\": \"<string>\",\n \"isStorage\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("TT-API-KEY", "<api-key>")
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.ttapi.io/suno/v1/add-stem")
.header("TT-API-KEY", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"mv\": \"chirp-v6\",\n \"music_id\": \"<string>\",\n \"prompt\": \"<string>\",\n \"title\": \"<string>\",\n \"tags\": \"rock, blues, hip-hop, r&b\",\n \"negative_tags\": \"<string>\",\n \"style_weight\": 0.5,\n \"weirdness_constraint\": 0.5,\n \"audio_weight\": 0.5,\n \"variety\": \"normal\",\n \"max_mode\": false,\n \"audio_format\": \"mp3\",\n \"hookUrl\": \"<string>\",\n \"isStorage\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ttapi.io/suno/v1/add-stem")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["TT-API-KEY"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"mv\": \"chirp-v6\",\n \"music_id\": \"<string>\",\n \"prompt\": \"<string>\",\n \"title\": \"<string>\",\n \"tags\": \"rock, blues, hip-hop, r&b\",\n \"negative_tags\": \"<string>\",\n \"style_weight\": 0.5,\n \"weirdness_constraint\": 0.5,\n \"audio_weight\": 0.5,\n \"variety\": \"normal\",\n \"max_mode\": false,\n \"audio_format\": \"mp3\",\n \"hookUrl\": \"<string>\",\n \"isStorage\": true\n}"
response = http.request(request)
puts response.read_body{
"status": "SUCCESS",
"message": "success",
"data": {
"jobId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}{
"status": "FAILED",
"message": "<string>",
"data": {}
}{
"status": "FAILED",
"message": "Wrong TT-API-KEY or email is not activated."
}Authorizations
You can obtain your API key from the TTAPI Dashboard.
Body
Model to use. Available values: chirp-v6, chirp-v6-wild, chirp-v6-mini. Suno legacy models have all been discontinued; passing a legacy name maps it to chirp-v6. See Model Mapping. After creating a custom model, you can also pass chirp-custom:{model_id}. See Create Model. persona_id and chirp-custom cannot be used together.
chirp-v6, chirp-v6-wild, chirp-v6-mini Audio ID
Lyrics.
Used in custom mode (custom=true). Required when instrumental is false. The lyrics will be used and sung in the generated track. Maximum length: 5000 characters.
Music title.
Used in custom mode (custom=true). Maximum length: 80 characters.
Music style or genre.
Used in custom mode (custom=true). Maximum length: 1000 characters.
"rock, blues, hip-hop, r&b"
Music styles or genres that should be excluded from generation.
Used in custom mode (custom=true).
Music style weight, range: 0.00โ1.00.
Used in custom mode. Valid range: 0 <= x <= 1.
0.5
Audio creativity (weirdness) weight, range: 0.00โ1.00.
Used in custom mode. Valid range: 0 <= x <= 1.
0.5
Audio weight, range: 0.00โ1.00.
Used in custom mode. Valid range: 0 <= x <= 1.
0.5
Style variety. Controls how much the generated result varies from the specified style.
- off: Exact style
- normal: Balanced variety
- high: Distinct styles
- extra: Bold exploration
- max: Unreasonably varied
off, normal, high, extra, max Whether to use more compute to maximize consistency throughout the song. Custom mode only.
- false: No (default)
- true: Yes. Credit consumption is doubled when enabled
Audio format of audioUrl after the job succeeds.
mp3, m4a, wav "mp3"
Callback notification URL
Whether to store the generated audio.
- true: The audio will be stored and a TTAPI CDN URL will be returned
- false: The original source URL will be returned