Suno 音乐生成

用 Suno 协议格式生成音乐与歌词——异步任务模型的提交与轮询,参数与状态枚举说明。

Suno 音乐生成接入的是 Suno 官方协议格式,与积木的视频生成同属异步任务模型: 提交请求只拿回任务标识,需要轮询任务状态,完成后再取歌曲或歌词内容。 不要期望提交接口同步返回音乐文件。

端点总览

方法路径说明
POST/suno/submit/{action}提交任务,{action} 为 music(生成歌曲)或 lyrics(生成歌词)
POST/suno/fetch按任务 ID 数组批量查询
GET/suno/fetch/{id}按单个任务 ID 查询

鉴权见 鉴权与令牌(Authorization: Bearer <令牌>), 通用错误码见 错误处理与请求追踪——本组接口返回任务错误信封 (顶层扁平 code/message/data,不是嵌套 error 对象)。

第一步:提交任务

POST/suno/submit/{action}

{action} 决定任务类型与必填参数:

  • music:生成歌曲。mv 留空时默认取 chirp-v3-0
  • lyrics:生成歌词。prompt 必填,留空返回 invalid_request(prompt_empty)
promptstring

歌曲描述或歌词主题。lyrics 任务必填;music 任务留空时按 gpt_description_prompt 或纯乐器生成

gpt_description_promptstring

用自然语言描述想要的歌曲风格,由模型自动生成对应的 prompt/tags

mvstring

使用的 Suno 模型版本

默认值: chirp-v3-0
titlestring

歌曲标题

tagsstring

风格标签,如 pop, upbeat

make_instrumentalbool

是否生成纯伴奏(无人声)

continue_atnumber

从已有歌曲的第几秒续写

continue_clip_idstring

被续写的原歌曲片段 ID。传此参数时必须同时传 task_id,否则返回 invalid_request

task_idstring

配合 continue_clip_id 使用,指向原任务

提交响应

响应200
{
  "code": "success",
  "message": "",
  "data": "task_9f8e7d6c5b4a"
}

data 是任务 ID 字符串本身(不是对象),拿到后进入轮询环节。 提交失败时返回任务错误信封,如 lyrics 缺 prompt:

响应400
{
  "code": "invalid_request",
  "message": "prompt_empty",
  "data": null
}

提交即预扣费。配额不足的提交会被直接拒绝(HTTP 403 quota_not_enough)。

第二步:轮询任务状态

批量查询

POST/suno/fetch
idsstring[]必填

要查询的任务 ID 数组

响应200
{
  "code": "success",
  "message": "",
  "data": [
    {
      "task_id": "task_9f8e7d6c5b4a",
      "action": "MUSIC",
      "status": "IN_PROGRESS",
      "fail_reason": "",
      "submit_time": 1753700000,
      "start_time": 1753700005,
      "finish_time": 0,
      "progress": "30%",
      "data": null
    }
  ]
}

ids 为空数组或未匹配到任何任务时,data 返回空数组 [],不是错误。

按单个任务 ID 查询

GET/suno/fetch/{id}

响应结构与批量查询的单项一致,data 是单个任务对象而非数组。 任务不存在时返回 HTTP 400(不是 404):

响应400
{
  "code": "task_not_exist",
  "message": "task_not_exist",
  "data": null
}

任务对象字段

task_idstring

任务 ID

actionstring

任务类型:MUSIC(歌曲)或 LYRICS(歌词)

statusstring

内部状态枚举,见下表

fail_reasonstring

失败原因,仅失败时非空

submit_time / start_time / finish_timeint64

提交 / 开始 / 完成时间戳(Unix 秒),未发生时为 0

progressstring

带百分号的字符串(如 "30%"),粒度较粗,仅作展示

dataobject | null

完成后的歌曲/歌词数据,结构见下文;未完成时为 null

status 值含义
NOT_START已创建,尚未提交上游
SUBMITTED已提交上游,等待受理
QUEUED上游排队中
IN_PROGRESS生成中
SUCCESS生成成功(终态)
FAILURE生成失败(终态),原因见 fail_reason
UNKNOWN状态未知

任务由后台同步器每约 15 秒扫描未完成任务、回源查询上游后更新,轮询间隔小于 15 秒看不到新数据, 与视频生成的轮询机制一致。

完成后的 data 结构

music 任务完成后,data 是歌曲片段对象:

music 任务完成后的 data200
{
  "id": "clip_abc123",
  "video_url": "https://cdn.example.com/clip.mp4",
  "audio_url": "https://cdn.example.com/clip.mp3",
  "image_url": "https://cdn.example.com/cover.jpeg",
  "image_large_url": "https://cdn.example.com/cover_large.jpeg",
  "major_model_version": "v3",
  "model_name": "chirp-v3-0",
  "status": "complete",
  "title": "夏日回忆",
  "text": "(歌词文本)",
  "metadata": {
    "tags": "pop, upbeat",
    "prompt": "一首关于夏天的歌",
    "duration": 128.5
  }
}

lyrics 任务完成后,data 是歌词对象(id、status、title、text)。

失败与重试

  • 提交阶段失败(4xx/5xx):5xx 与 429 网关会自动换渠道重试;400 为请求本身问题,修复参数后再提交
  • 任务状态 FAILURE:读取 fail_reason 定位原因,内容审核类失败不要原样重试
  • 任务经后台同步首次进入 FAILURE 时,平台自动退还预扣额度(同一任务只退一次)
  • task_id 只能由提交它的令牌查询,跨令牌查询会返回 task_not_exist

请求示例

# 提交歌曲生成任务
TASK_ID=$(curl -s https://api.jimu.chat/suno/submit/music \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $JIMU_API_KEY" \
  -d '{"gpt_description_prompt":"一首关于夏天的轻快流行歌","make_instrumental":false}' \
  | python -c "import sys,json;print(json.load(sys.stdin)['data'])")

# 轮询(每 10 秒一次)
while true; do
  STATUS=$(curl -s "https://api.jimu.chat/suno/fetch/$TASK_ID" \
    -H "Authorization: Bearer $JIMU_API_KEY" \
    | python -c "import sys,json;print(json.load(sys.stdin)['data']['status'])")
  echo "status=$STATUS"
  [ "$STATUS" = "SUCCESS" ] || [ "$STATUS" = "FAILURE" ] && break
  sleep 10
done