上传并翻唱音乐
curl --request POST \
--url https://api.sunoapi.org/api/v1/generate/upload-cover \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"uploadUrl": "https://api.example.com/upload",
"customMode": true,
"instrumental": true,
"model": "V4_5ALL",
"callBackUrl": "https://api.example.com/callback",
"prompt": "一段平静舒缓的钢琴曲,带有柔和的旋律",
"style": "古典",
"title": "宁静钢琴冥想",
"personaId": "persona_123",
"personaModel": "style_persona",
"negativeTags": "重金属, 强节奏鼓点",
"vocalGender": "m",
"styleWeight": 0.65,
"weirdnessConstraint": 0.65,
"audioWeight": 0.65,
"duration": 20
}
'import requests
url = "https://api.sunoapi.org/api/v1/generate/upload-cover"
payload = {
"uploadUrl": "https://api.example.com/upload",
"customMode": True,
"instrumental": True,
"model": "V4_5ALL",
"callBackUrl": "https://api.example.com/callback",
"prompt": "一段平静舒缓的钢琴曲,带有柔和的旋律",
"style": "古典",
"title": "宁静钢琴冥想",
"personaId": "persona_123",
"personaModel": "style_persona",
"negativeTags": "重金属, 强节奏鼓点",
"vocalGender": "m",
"styleWeight": 0.65,
"weirdnessConstraint": 0.65,
"audioWeight": 0.65,
"duration": 20
}
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://api.example.com/upload',
customMode: true,
instrumental: true,
model: 'V4_5ALL',
callBackUrl: 'https://api.example.com/callback',
prompt: '一段平静舒缓的钢琴曲,带有柔和的旋律',
style: '古典',
title: '宁静钢琴冥想',
personaId: 'persona_123',
personaModel: 'style_persona',
negativeTags: '重金属, 强节奏鼓点',
vocalGender: 'm',
styleWeight: 0.65,
weirdnessConstraint: 0.65,
audioWeight: 0.65,
duration: 20
})
};
fetch('https://api.sunoapi.org/api/v1/generate/upload-cover', 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-cover",
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://api.example.com/upload',
'customMode' => true,
'instrumental' => true,
'model' => 'V4_5ALL',
'callBackUrl' => 'https://api.example.com/callback',
'prompt' => '一段平静舒缓的钢琴曲,带有柔和的旋律',
'style' => '古典',
'title' => '宁静钢琴冥想',
'personaId' => 'persona_123',
'personaModel' => 'style_persona',
'negativeTags' => '重金属, 强节奏鼓点',
'vocalGender' => 'm',
'styleWeight' => 0.65,
'weirdnessConstraint' => 0.65,
'audioWeight' => 0.65,
'duration' => 20
]),
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-cover"
payload := strings.NewReader("{\n \"uploadUrl\": \"https://api.example.com/upload\",\n \"customMode\": true,\n \"instrumental\": true,\n \"model\": \"V4_5ALL\",\n \"callBackUrl\": \"https://api.example.com/callback\",\n \"prompt\": \"一段平静舒缓的钢琴曲,带有柔和的旋律\",\n \"style\": \"古典\",\n \"title\": \"宁静钢琴冥想\",\n \"personaId\": \"persona_123\",\n \"personaModel\": \"style_persona\",\n \"negativeTags\": \"重金属, 强节奏鼓点\",\n \"vocalGender\": \"m\",\n \"styleWeight\": 0.65,\n \"weirdnessConstraint\": 0.65,\n \"audioWeight\": 0.65,\n \"duration\": 20\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-cover")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"uploadUrl\": \"https://api.example.com/upload\",\n \"customMode\": true,\n \"instrumental\": true,\n \"model\": \"V4_5ALL\",\n \"callBackUrl\": \"https://api.example.com/callback\",\n \"prompt\": \"一段平静舒缓的钢琴曲,带有柔和的旋律\",\n \"style\": \"古典\",\n \"title\": \"宁静钢琴冥想\",\n \"personaId\": \"persona_123\",\n \"personaModel\": \"style_persona\",\n \"negativeTags\": \"重金属, 强节奏鼓点\",\n \"vocalGender\": \"m\",\n \"styleWeight\": 0.65,\n \"weirdnessConstraint\": 0.65,\n \"audioWeight\": 0.65,\n \"duration\": 20\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sunoapi.org/api/v1/generate/upload-cover")
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://api.example.com/upload\",\n \"customMode\": true,\n \"instrumental\": true,\n \"model\": \"V4_5ALL\",\n \"callBackUrl\": \"https://api.example.com/callback\",\n \"prompt\": \"一段平静舒缓的钢琴曲,带有柔和的旋律\",\n \"style\": \"古典\",\n \"title\": \"宁静钢琴冥想\",\n \"personaId\": \"persona_123\",\n \"personaModel\": \"style_persona\",\n \"negativeTags\": \"重金属, 强节奏鼓点\",\n \"vocalGender\": \"m\",\n \"styleWeight\": 0.65,\n \"weirdnessConstraint\": 0.65,\n \"audioWeight\": 0.65,\n \"duration\": 20\n}"
response = http.request(request)
puts response.read_body{
"code": 200,
"msg": "success",
"data": {
"taskId": "5c79****be8e"
}
}Generate Music
上传并翻唱音乐
此 API 通过在保留其核心旋律的同时将音轨转换为新样式来覆盖音轨。它结合了 Suno 的上传功能,使用户能够上传音频文件进行处理。预期的结果是刷新了具有新风格的音轨,同时保持了原始旋律的完整性。
POST
/
api
/
v1
/
generate
/
upload-cover
上传并翻唱音乐
curl --request POST \
--url https://api.sunoapi.org/api/v1/generate/upload-cover \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"uploadUrl": "https://api.example.com/upload",
"customMode": true,
"instrumental": true,
"model": "V4_5ALL",
"callBackUrl": "https://api.example.com/callback",
"prompt": "一段平静舒缓的钢琴曲,带有柔和的旋律",
"style": "古典",
"title": "宁静钢琴冥想",
"personaId": "persona_123",
"personaModel": "style_persona",
"negativeTags": "重金属, 强节奏鼓点",
"vocalGender": "m",
"styleWeight": 0.65,
"weirdnessConstraint": 0.65,
"audioWeight": 0.65,
"duration": 20
}
'import requests
url = "https://api.sunoapi.org/api/v1/generate/upload-cover"
payload = {
"uploadUrl": "https://api.example.com/upload",
"customMode": True,
"instrumental": True,
"model": "V4_5ALL",
"callBackUrl": "https://api.example.com/callback",
"prompt": "一段平静舒缓的钢琴曲,带有柔和的旋律",
"style": "古典",
"title": "宁静钢琴冥想",
"personaId": "persona_123",
"personaModel": "style_persona",
"negativeTags": "重金属, 强节奏鼓点",
"vocalGender": "m",
"styleWeight": 0.65,
"weirdnessConstraint": 0.65,
"audioWeight": 0.65,
"duration": 20
}
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://api.example.com/upload',
customMode: true,
instrumental: true,
model: 'V4_5ALL',
callBackUrl: 'https://api.example.com/callback',
prompt: '一段平静舒缓的钢琴曲,带有柔和的旋律',
style: '古典',
title: '宁静钢琴冥想',
personaId: 'persona_123',
personaModel: 'style_persona',
negativeTags: '重金属, 强节奏鼓点',
vocalGender: 'm',
styleWeight: 0.65,
weirdnessConstraint: 0.65,
audioWeight: 0.65,
duration: 20
})
};
fetch('https://api.sunoapi.org/api/v1/generate/upload-cover', 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-cover",
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://api.example.com/upload',
'customMode' => true,
'instrumental' => true,
'model' => 'V4_5ALL',
'callBackUrl' => 'https://api.example.com/callback',
'prompt' => '一段平静舒缓的钢琴曲,带有柔和的旋律',
'style' => '古典',
'title' => '宁静钢琴冥想',
'personaId' => 'persona_123',
'personaModel' => 'style_persona',
'negativeTags' => '重金属, 强节奏鼓点',
'vocalGender' => 'm',
'styleWeight' => 0.65,
'weirdnessConstraint' => 0.65,
'audioWeight' => 0.65,
'duration' => 20
]),
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-cover"
payload := strings.NewReader("{\n \"uploadUrl\": \"https://api.example.com/upload\",\n \"customMode\": true,\n \"instrumental\": true,\n \"model\": \"V4_5ALL\",\n \"callBackUrl\": \"https://api.example.com/callback\",\n \"prompt\": \"一段平静舒缓的钢琴曲,带有柔和的旋律\",\n \"style\": \"古典\",\n \"title\": \"宁静钢琴冥想\",\n \"personaId\": \"persona_123\",\n \"personaModel\": \"style_persona\",\n \"negativeTags\": \"重金属, 强节奏鼓点\",\n \"vocalGender\": \"m\",\n \"styleWeight\": 0.65,\n \"weirdnessConstraint\": 0.65,\n \"audioWeight\": 0.65,\n \"duration\": 20\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-cover")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"uploadUrl\": \"https://api.example.com/upload\",\n \"customMode\": true,\n \"instrumental\": true,\n \"model\": \"V4_5ALL\",\n \"callBackUrl\": \"https://api.example.com/callback\",\n \"prompt\": \"一段平静舒缓的钢琴曲,带有柔和的旋律\",\n \"style\": \"古典\",\n \"title\": \"宁静钢琴冥想\",\n \"personaId\": \"persona_123\",\n \"personaModel\": \"style_persona\",\n \"negativeTags\": \"重金属, 强节奏鼓点\",\n \"vocalGender\": \"m\",\n \"styleWeight\": 0.65,\n \"weirdnessConstraint\": 0.65,\n \"audioWeight\": 0.65,\n \"duration\": 20\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sunoapi.org/api/v1/generate/upload-cover")
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://api.example.com/upload\",\n \"customMode\": true,\n \"instrumental\": true,\n \"model\": \"V4_5ALL\",\n \"callBackUrl\": \"https://api.example.com/callback\",\n \"prompt\": \"一段平静舒缓的钢琴曲,带有柔和的旋律\",\n \"style\": \"古典\",\n \"title\": \"宁静钢琴冥想\",\n \"personaId\": \"persona_123\",\n \"personaModel\": \"style_persona\",\n \"negativeTags\": \"重金属, 强节奏鼓点\",\n \"vocalGender\": \"m\",\n \"styleWeight\": 0.65,\n \"weirdnessConstraint\": 0.65,\n \"audioWeight\": 0.65,\n \"duration\": 20\n}"
response = http.request(request)
puts response.read_body{
"code": 200,
"msg": "success",
"data": {
"taskId": "5c79****be8e"
}
}参数使用指南
-
当 customMode 为 true(自定义模式)时:
- 如果 instrumental 为 true:需要提供 style、title 和 uploadUrl
- 如果 instrumental 为 false:需要提供 style、prompt、title和uploadUrl
- prompt 根据模型的长度限制:
- V4:最大 3000 字符
- V4_5、V4_5PLUS、V4_5ALL、V5 和 V5_5:最大 5000 字符
- style 根据模型的长度限制:
- V4:最大 200 字符
- V4_5、V4_5PLUS、V4_5ALL、V5 和 V5_5:最大 1000 字符
- title 根据模型的长度限制:
- V4 和 V4_5ALL:最大 80 字符
- V4_5、V4_5PLUS、V5 和 V5_5:最大 100 字符
- uploadUrl 用于指定音频文件的上传位置;确保上传的音频长度不超过 8 分钟。
- 重要提示:使用 V4_5ALL 模型时,上传的音频文件长度不得超过 1 分钟。
-
当 customMode 为 false(非自定义模式)时:
- 无论 instrumental 设置如何,只需要提供 prompt和uploadUrl
- prompt 长度限制:500字符
- 其他参数应留空
可选参数
- duration(integer):时长,可选。仅当
customMode为true且model为V5_5时有效。取值范围:10–360。示例:20 - personaId(string):自定义模式下可传入 Persona ID 或 Suno Voice 生成的
voiceId。如果使用 Voice 生成的 ID,personaModel必须设置为voice_persona。 - personaModel(string):Persona 类型。生成 Persona 接口返回的 ID 使用
style_persona,Suno Voice 生成的 ID 使用voice_persona。
开发者注意事项
- 新用户推荐设置:将 customMode 设为 false,instrumental 设为 false,只提供 prompt和uploadUrl。这是最简单的配置,可以快速测试API并体验结果。
- V4_5ALL 模型上传限制:使用 V4_5ALL 模型时,上传的音频文件长度不得超过 1 分钟。
- 生成的文件将保留15天后删除
- 请根据 customMode 和 instrumental 设置确保提供所有必要参数,避免出错
- 请注意 prompt、style 和 title 的字符长度限制,确保成功处理
- 回调过程有三个阶段:text(文本生成完成)、first(第一首完成)、complete(全部完成)
- 您可以使用音乐生成详情查询接口主动检查任务状态,而不必等待回调
- uploadUrl 参数用于指定音频文件的上传位置;请提供有效的 URL。
授权
🔑 API 认证说明
所有接口都需要通过 Bearer Token 方式进行认证。
获取 API Key
- 访问 API Key 管理页面 获取您的 API Key
使用方式
在请求头中添加:
Authorization: Bearer YOUR_API_KEY
⚠️ 注意:
- 请妥善保管您的 API Key,不要泄露给他人
- 如果怀疑 API Key 泄露,请立即在管理页面重置
请求体
application/json
用于上传音频文件的 URL,无论 customMode 和 instrumental 是 true 还是 false,都是必需的。确保上传的音频长度不超过 8 分钟。
示例:
"https://api.example.com/upload"
启用自定义模式进行高级音频生成设置。
- 设为
true使用自定义模式(需要提供style和title;如果instrumental为false,则需要提供prompt)。如果instrumental为false,提示词将严格用作歌词。 - 设为
false使用非自定义模式(只需要提供prompt)。歌词将根据提示词自动生成。
示例:
true
决定音频是否为纯音乐(无歌词)。
- 在自定义模式下(
customMode: true):- 如果为
true:只需提供style和title。 - 如果为
false:需要提供style、title和prompt(prompt将作为精确歌词使用)。
- 如果为
- 在非自定义模式下(
customMode: false):不影响必填字段(只需prompt)。如果为false,将自动生成歌词。
示例:
true
用于音频生成的模型版本。
- 可选择:
V4、V4_5、V4_5PLUS、V4_5ALL、V5或V5_5。注意: 确保格式正确(例如,使用 "V4" 或 "V4_5ALL",而不是 "V4.5" 或其他变体)。
可用选项:
V4, V4_5, V4_5PLUS, V4_5ALL, V5, V5_5 示例:
"V4_5ALL"
描述期望生成的音频内容。
- 在自定义模式下(
customMode: true):当instrumental为false时必填。提示词将严格用作歌词并在生成的音乐中演唱。根据模型的字符限制:- V4:最大 3000 字符
- V4_5、V4_5PLUS、V4_5ALL、V5 和 V5_5:最大 5000 字符
示例:"一段平静舒缓的钢琴曲,带有柔和的旋律"
- 在非自定义模式下(
customMode: false):始终必填。提示词作为核心创意,歌词将基于此自动生成(不会严格匹配输入内容)。最大长度:500字符。
示例:"一段短小舒缓的钢琴曲"
示例:
"一段平静舒缓的钢琴曲,带有柔和的旋律"
音乐风格或流派。
- 在自定义模式下(
customMode: true)必填。示例:"爵士"、"古典"、"电子"。- 对于 V4 模型:最大长度:200字符。
- 对于 V4_5、V4_5PLUS、V4_5ALL、V5 和 V5_5 模型:最大长度:1000字符。 示例:"古典"
- 在非自定义模式下(
customMode: false):留空。
示例:
"古典"
生成音乐的标题。
- 在自定义模式下(
customMode: true)必填。根据模型的字符限制:- V4 和 V4_5ALL:最大 80 字符
- V4_5、V4_5PLUS、V5 和 V5_5:最大 100 字符
示例:"宁静钢琴冥想"
- 在非自定义模式下(
customMode: false):留空。
示例:
"宁静钢琴冥想"
仅在开启自定义参数时可用。应用到生成音乐的 Persona ID,可选。你可以传入以下两类 ID:
- 通过 生成 Persona 接口生成的 Persona ID。此时可使用
personaModel: style_persona,或省略personaModel使用默认值。 - 通过 Suno Voice 流程生成的
voiceId。当使用 Voice 生成的 ID 时,必须设置personaModel: voice_persona。
示例:
"persona_123"
使用 personaId 时应用的 Persona 模型类型,可选。
style_persona(默认):用于生成 Persona 接口返回的 Persona ID。voice_persona:当personaId使用 Suno Voice 生成的voiceId时必须选择该值。该选项仅在 V5 与 V5_5 模型下可用。
可用选项:
style_persona, voice_persona 示例:
"style_persona"
需要在生成的音频中排除的音乐风格或特征。
- 可选。用于避免特定风格。
示例:"重金属, 强节奏鼓点"
示例:
"重金属, 强节奏鼓点"
期望的人声性别(可选)
可用选项:
m, f 示例:
"m"
风格指引权重,范围 0.00–1.00
必填范围:
0 <= x <= 1必须是以下数值的倍数 0.01示例:
0.65
创意发散/奇异度约束,范围 0.00–1.00
必填范围:
0 <= x <= 1必须是以下数值的倍数 0.01示例:
0.65
输入音频影响力权重(如适用),范围 0.00–1.00
必填范围:
0 <= x <= 1必须是以下数值的倍数 0.01示例:
0.65
时长,可选。仅当 customMode 为 true 且 model 为 V5_5 时有效。
必填范围:
10 <= x <= 360示例:
20
回调
响应
请求成功
状态码说明
- ✅ 200 - 请求成功
- ⚠️ 400 - 参数错误
- ⚠️ 401 - 没有访问权限
- ⚠️ 404 - 请求方式或者路径错误
- ⚠️ 405 - 调用超过限制
- ⚠️ 413 - 主题或者prompt过长
- ⚠️ 429 - 积分不足
- ⚠️ 430 - 您的调用频率过高,请稍后再试。
- ⚠️ 455 - 网站维护
- ❌ 500 - 服务器异常
可用选项:
200, 400, 401, 404, 405, 413, 429, 430, 455, 500 示例:
200
当 code != 200 时,展示错误信息
示例:
"success"
Show child attributes
Show child attributes
