MIDI 条件生成 API
接口说明
MIDI 条件生成接口会读取用户上传的 MIDI 文件和填写的风格,创作一首严格跟随 MIDI 旋律与段落的新歌曲。支持两种模式:
instrumental:只生成伴奏,不生成人声;vocal:按 MIDI 旋律生成带人声的歌曲,需要额外提供歌词。
适用场景包括:
- 已有旋律草稿,希望快速制作完整编曲;
- 已有单音轨人声旋律,希望生成带歌词的人声 Demo;
- 将 MIDI 乐句扩展成完整歌曲;
- 批量制作风格统一、旋律结构可控的音乐素材。
该接口创作的是音频,不负责生成或改写 MIDI 文件本身。
接口地址
POST /api/music/midi
完整地址:
https://www.suno-api.io/api/music/midi
计费
按当前 suno-v6-wild 生成价格计费,通常一次返回 2 首歌曲,实际扣费以后台价格配置为准。开启 max_mode 时按 2 倍价格计费。参数校验失败不会预扣费;上游提交失败或最终生成失败按现有任务退款规则处理。
推荐使用异步受理模式。MIDI 文件可能较大,同步请求需要客户端保持较长连接;异步模式会先返回受理号,再由客户端轮询结果。
请求头
| 参数名 | 必填 | 说明 |
|---|---|---|
Authorization |
是 | Bearer YOUR_API_KEY |
Content-Type |
是 | application/json |
Idempotency-Key |
否 | 建议异步请求填写;同一个 key 的重复提交只受理一次 |
Idempotency-Key 最长 128 个字符。相同 key 和相同请求体重复提交时会返回原受理结果;更换 key 会被视为新订单。
请求参数
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
model |
string | 否 | - | 兼容字段。传 suno-v6、suno-v6-wild 或 suno-v6-mini 会统一按 V6 Wild 能力生成;其他模型返回 400 |
mode |
string | 是 | - | instrumental 或 vocal |
midi_base64 |
string | 是 | - | MIDI 文件的 base64,也支持 data:audio/midi;base64,... |
style_tags |
string | 是 | - | 风格、编曲和音色描述,建议使用英文 |
lyrics |
string | 人声模式必填 | - | 人声歌词;伴奏模式必须为空或 [Instrumental] |
song_title |
string | 否 | 自动标题 | 歌曲标题 |
negative_tags |
string | 否 | - | 不希望出现的风格或元素 |
crop_start_s |
number | 否 | 0 |
从 MIDI 的第几秒开始使用 |
crop_end_s |
number | 否 | MIDI 结尾 | 使用到 MIDI 的第几秒;必须大于 crop_start_s |
wait_completion |
boolean | 否 | false |
是否等待生成完成后再返回 |
accept_mode |
string | 否 | - | 传 async 时使用异步受理模式 |
client_request_id |
string | 否 | 自动生成 | 客户端提交标识,建议显式传入 |
max_mode |
boolean | 否 | false |
Max Mode;开启后按 2 倍价格计费 |
variety |
integer | 否 | - | 变化程度,范围 0–4 |
style_weight |
number | 否 | - | 风格权重,范围 0–1 |
audio_weight |
number | 否 | - | 音频参考权重,范围 0–1 |
weirdness_constraint |
number | 否 | - | 创意偏离约束,范围 0–1 |
为兼容旧版本封装,客户端如果仍携带平台内部配置字段,服务端会忽略客户端配置,并根据
mode、MIDI、风格和高级参数重新构造最终任务。旧式
v2_web_options.midi_cond.midi_b64 中的 MIDI 内容仍可识别,但没有顶层
midi_base64 的新接入应优先使用顶层字段。
文本字段沿用平台生成接口的长度上限:
| 字段 | 上限 |
|---|---|
lyrics |
5000 |
style_tags |
1000 |
negative_tags |
1000 |
song_title |
100 |
字段详细说明
model
兼容字段,可传:
suno-v6
suno-v6-wild
suno-v6-mini
也可以完全不传。MIDI 条件生成当前统一使用 V6 Wild 能力,业务上不需要客户端选择其他模型。
模型转换说明
Suno 的 MIDI 条件生成只接受 V6 Wild。为了提高兼容性,客户传
suno-v6或suno-v6-mini时,服务端会自动转换成 V6 Wild 后再提交;客户无需自己修改。 传suno-v4、suno-v5-5等非 V6 模型会返回 HTTP400。
mode
| 值 | 行为 | 歌词要求 |
|---|---|---|
instrumental |
只生成伴奏 | 必须为空或 [Instrumental] |
vocal |
生成带人声歌曲 | 必须提供非空 lyrics |
midi_base64
支持两种写法:
TVRoZAAAAAYAAQAB...
data:audio/midi;base64,TVRoZAAAAAYAAQAB...
也支持:
data:audio/x-midi;base64,...
data:application/x-midi;base64,...
不接受:
- MIDI 文件 URL;
- 只有文件扩展名但没有
MThd文件头的数据; - 文本、图片、音频 MP3/WAV 等其他文件;
- 解码后超过 10 MiB 的文件。
style_tags
描述最终编曲、配器和演唱风格。建议使用英文,并同时写明:
曲风 + 主奏乐器 + 情绪 + 节奏感 + 制作质感
例如:
Cantopop ballad, emotional male vocal, acoustic piano, warm strings,
slow tempo, cinematic reverb
lyrics
人声模式必填。中文歌词可以直接传入;需要更严格贴合 MIDI 旋律时,建议把每个音节转换成拼音并以空格分隔,按原句换行。
crop_start_s / crop_end_s
用于只生成 MIDI 文件中的一个时间段:
- 两个字段必须同时传;
crop_start_s不得小于 0;crop_end_s必须大于crop_start_s;- 不传时默认使用整份 MIDI。
例如只使用第 30 秒到第 90 秒:
{
"crop_start_s": 30,
"crop_end_s": 90
}
MIDI 文件要求
- 文件必须包含标准
MThd头; - 解码后默认最大 10 MiB;
- 不要求文件扩展名,服务端按文件内容校验;
- 人声模式建议使用单音轨 MIDI,过多和弦或轨道会降低人声旋律清晰度;
- 首版只接受内联 base64,不支持远程 URL。
高级生成参数
MIDI 生成支持以下高级参数:
| 参数 | 取值范围 | 说明 |
|---|---|---|
max_mode |
true / false |
提升生成强度;产生两首时仍按一次请求计费,但单价为普通模式 2 倍 |
variety |
整数 0–4 |
控制结果变化程度 |
style_weight |
数字 0–1 |
控制对 style_tags 的贴合程度 |
audio_weight |
数字 0–1 |
控制音频参考权重 |
weirdness_constraint |
数字 0–1 |
控制创意偏离约束 |
参数超出范围、布尔值无法解析或权重不是数字时,请求会在预扣费前返回 HTTP 400。
伴奏模式示例
curl -X POST https://www.suno-api.io/api/music/midi \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
--max-time 300 \
-d '{
"model": "suno-v6",
"mode": "instrumental",
"midi_base64": "TVRoZAAAAAYAAQAB...",
"style_tags": "solo acoustic piano, expressive dynamics, cinematic, warm room reverb",
"song_title": "Piano from MIDI",
"crop_start_s": 0,
"crop_end_s": 251
}'
人声模式示例
curl -X POST https://www.suno-api.io/api/music/midi \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
--max-time 300 \
-d '{
"model": "suno-v6-wild",
"mode": "vocal",
"midi_base64": "TVRoZAAAAAYAAQAB...",
"style_tags": "Cantopop ballad, emotional male vocal, piano and strings",
"lyrics": "ni jin lai you zai you kong\nwo zai fang bei bie fa gong",
"song_title": "MIDI vocal demo",
"crop_start_s": 0,
"crop_end_s": 251
}'
中文歌词可以直接传入。若希望每个字更严格贴合 MIDI 音符,建议按原句换行,并将中文音节转换为空格分隔的拼音。
同步响应
同步模式通常返回 2 个歌曲对象:
[
{
"song_id": "aa71a4d2-5a4e-48c3-a5ef-87afd020c62d",
"song_title": "Piano from MIDI",
"status": "processing",
"generation_type": "midi_condition",
"play_url": "https://..."
},
{
"song_id": "b9520b6e-8ace-4e8b-aeae-4622b6990281",
"song_title": "Piano from MIDI",
"status": "processing",
"generation_type": "midi_condition",
"play_url": "https://..."
}
]
首次响应中的 processing 表示已经提交成功,不代表失败。请保存 song_id,通过歌曲查询与历史 API轮询最终状态和音频地址。
同步歌曲对象
| 字段 | 类型 | 说明 |
|---|---|---|
song_id |
string | 真实歌曲 ID,后续查询、下载使用 |
song_title |
string | 歌曲标题 |
status |
string | processing、completed、failed 等 |
generation_type |
string | MIDI 任务通常为 midi_condition |
prompt / lyrics |
string | 人声歌词;伴奏为空 |
style_tags |
string | 风格描述 |
play_url |
string | 生成中试听地址,存在时可直接播放 |
audio_url |
string | 完成后可下载的音频地址 |
duration |
number | 完成后的音频时长,单位秒 |
action_config |
object | 平台允许的操作项,例如下载、加入 Studio |
当状态仍为 processing 时,audio_url 为空是正常现象。
异步受理
请求体增加:
{
"accept_mode": "async"
}
接口会立即返回 HTTP 202:
{
"success": true,
"data": {
"request_id": "ac_20261109060217175804300DjCBGAeO",
"status": "queued",
"pre_consumed_quota": 200000,
"tasks": [
{"index": 0, "status": "queued"},
{"index": 1, "status": "queued"}
]
}
}
使用受理号查询进度:
GET /api/music/requests/{request_id}
任务完成后,tasks[] 会包含真实 song_id、audio_url 和时长。
异步流程
1. POST /api/music/midi
-> 202 + request_id
2. GET /api/music/requests/{request_id}
-> queued
3. GET /api/music/requests/{request_id}
-> processing
4. GET /api/music/requests/{request_id}
-> completed + song_id + audio_url
轮询示例:
curl "https://www.suno-api.io/api/music/requests/ac_your_request_id" \
-H "Authorization: Bearer YOUR_API_KEY"
异步任务状态
| 状态 | 含义 |
|---|---|
queued |
已受理,等待后台执行 |
processing |
正在生成 |
partial |
部分歌曲完成、部分仍在生成或失败 |
completed |
全部完成 |
failed |
任务失败;错误信息会说明失败阶段和退款状态 |
建议轮询间隔:
- 前 2 分钟每 10 秒一次;
- 后续每 20–30 秒一次;
- 连续轮询到
completed、failed或partial终态后停止。
参数校验
以下情况返回 HTTP 400,不会进入生成,也不会扣费:
mode不是instrumental或vocal;style_tags为空;midi_base64缺失、不是合法 base64、不是 MIDI 文件或超过大小限制;- data URL 没有声明 MIDI media type;
model传入suno-v6系列之外的模型;- 人声模式未提供
lyrics; - 伴奏模式提供了非空且不是
[Instrumental]的歌词; crop_start_s和crop_end_s只传其中一个;crop_end_s <= crop_start_s;max_mode不是布尔值;variety不是0–4的整数;style_weight、audio_weight或weirdness_constraint不在0–1范围内。
常见错误
| HTTP 状态 | 场景 | 处理建议 |
|---|---|---|
400 |
参数缺失、MIDI 不合法、字段冲突 | 按错误 message 修正后重试 |
401 |
API Key 缺失或无效 | 检查 Authorization: Bearer ... |
402/403 |
余额或权限问题 | 检查账户余额和接口权限 |
429 |
请求频率过高 | 降低并发,指数退避后重试 |
5xx |
服务临时异常 | 使用幂等键重试,并联系技术支持 |
生产环境实测错误示例:
{
"error": {
"message": "mode must be instrumental or vocal",
"type": "new_api_error",
"param": "",
"code": "invalid_request"
}
}
{
"error": {
"message": "variety must be an integer between 0 and 4",
"type": "new_api_error",
"param": "",
"code": "invalid_request"
}
}
完整 Python 示例
import base64
import time
import requests
API_BASE = "https://www.suno-api.io"
API_KEY = "YOUR_API_KEY"
with open("melody.mid", "rb") as midi_file:
midi_base64 = base64.b64encode(midi_file.read()).decode("ascii")
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
"Idempotency-Key": "midi-job-20261109-001",
}
payload = {
"model": "suno-v6-wild",
"mode": "vocal",
"midi_base64": midi_base64,
"style_tags": (
"Cantopop ballad, emotional male vocal, acoustic piano, "
"warm strings, cinematic reverb"
),
"lyrics": "ni jin lai you zai you kong\nwo zai fang bei bie fa gong",
"song_title": "MIDI vocal demo",
"crop_start_s": 0,
"crop_end_s": 251,
"accept_mode": "async",
"client_request_id": "midi-job-20261109-001",
}
created = requests.post(
f"{API_BASE}/api/music/midi",
headers=headers,
json=payload,
timeout=300,
)
created.raise_for_status()
request_id = created.json()["data"]["request_id"]
while True:
result = requests.get(
f"{API_BASE}/api/music/requests/{request_id}",
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=60,
)
result.raise_for_status()
data = result.json()["data"]
print(data["status"], data["tasks"])
if data["status"] in {"completed", "failed", "partial"}:
break
time.sleep(10)
接入注意事项
- MIDI 文件只在本次请求中使用,不会以原文件形式返回。
- MIDI base64 会显著增大请求体:10 MiB MIDI 约为 13.3 MiB base64。
- 不要为同一个业务请求生成新的
Idempotency-Key后立即重试,否则会产生新订单。 - 同步请求建议把客户端超时设置为 300 秒以上;异步模式更适合长任务和批量任务。
- 音频地址是临时资源,拿到
audio_url后应及时转存到自己的存储。 - 生成中可优先使用
play_url试听;最终交付使用完成状态的audio_url。 - 建议在业务侧保存
request_id、client_request_id、song_id,用于幂等、查询和售后定位。
与“上传源音频 + 翻唱”的关系
现有的上传与翻唱能力采用两步式:
POST /api/music/upload-source
-> 免费上传音频,得到 clip_id
POST /api/music/generate-from-source
-> 用 sourceClipId 复用该音频,生成翻唱或其他派生歌曲
这套 clip_id 机制不能直接复用到 MIDI 条件生成,原因如下:
upload-source上传的是音频文件,返回的是音频 clip;- Suno 的 MIDI 条件任务要求原始 MIDI 文件内容,以
midi_base64提交; - Suno 不把普通音频 clip_id 当作 MIDI 乐谱,也不支持只传一个上传 ID 来完成 MIDI 条件生成。
因此:
- 当前 MIDI 条件生成每次都需要提交
midi_base64; - 如果同一份 MIDI 要生成多个版本,建议客户端保存原始
.mid文件,在每次请求时重新编码为 base64; POST /api/music/upload-source返回的clip_id不能填入 MIDI 接口;- MIDI 生成完成后的歌曲会返回真实
song_id,这个结果是一个普通歌曲 clip,可以继续用于翻唱、续写、替换段落、分轨等现有接口。 .mid文件不能通过POST /api/music/upload-source当作普通音频素材上传;MIDI 条件生成不走该上传接口。
如果后续需要“MIDI 文件只上传一次,后续通过一个 midi_id 反复生成”,需要新增一套平台侧 MIDI 素材存储与引用接口;当前接口不提供这种服务端持久化复用。
查询与下载
- 生成状态:歌曲查询与历史 API
- 异步进度:
GET /api/music/requests/{request_id} - MP3/WAV 下载:歌曲媒体下载与试听 API
MIDI 原文只参与本次生成,不写入普通日志和任务参数快照。参数快照仅保留 MIDI 文件大小和摘要,不回传原始 base64。