用克隆音色生成音乐 · 接口调用示例

更新于 2026-09-15 · Suno-API 团队

适用接口:/api/music/voice-profile/*

一次提交固定生成 2 首成品。音色翻唱 1.2 元/次(开启 Max Mode 为 2.4 元/次);强化克隆按强化上传价计(当前 10 元/次,失败自动退款)。


0. 整体流程

① 创建音色   POST /api/music/voice-profile/create       → 拿到 voice_id
② 等音色就绪 GET  /api/music/voice-profile/{voice_id}    → status=ready(强化克隆需要)
③ 生成音乐   POST /api/music/voice-profile/cover        → 立刻拿到 2 个 song_id
④ 查进度     POST /api/music/query                      → 轮询到 status=completed
⑤ 下载成品   GET  /api/music/download?song_id=…&kind=mp3

普通克隆第 ① 步通常直接返回 status=ready,可以跳过第 ② 步;强化克隆是异步的,必须等 ready。


1. 准备工作

项 说明
Base URL https://www.suno-api.io
鉴权 每个请求带 Authorization: Bearer <你的 API Key>
人声样本 6 秒以上(建议 10–60 秒)、≤10MB、mp3 / wav / m4a / aac / flac / ogg
样本内容 干净人声,避免带伴奏的原曲或翻唱成品(与曲库录音高度相似会被拒)

一个 voice_id 只对创建它的账号可用。


2. ① 创建音色

推荐:直接上传文件

curl -sS -X POST "https://www.suno-api.io/api/music/voice-profile/create" \
  -H "Authorization: Bearer $API_KEY" \
  -F "file=@./my-voice.mp3" \
  -F "file_name=my-voice.mp3" \
  -F "source_file_name=my-voice.mp3" \
  -F "title=我的音色" \
  -F "source_kind=upload"

响应(普通克隆):

{
  "success": true,
  "message": "",
  "data": {
    "voice_id": "vp_20260926080618509168500DXXrxe",
    "clip_id": "91cc5935-389f-4193-b56b-cc796c15562d",
    "song_id": "91cc5935-389f-4193-b56b-cc796c15562d",
    "title": "我的音色",
    "source_file_name": "my-voice.mp3",
    "audio_url": "https://…/create-ui/voice-source/2026/09/26/xxx.mp3",
    "duration_s": 29.18,
    "enhanced": false,
    "source_kind": "upload",
    "status": "ready"
  }
}

data.voice_id 就是后续生成音乐要用的音色 ID。

备选一:传一个公网音频地址

curl -sS -X POST "https://www.suno-api.io/api/music/voice-profile/create" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "file_url": "https://your-cdn.example.com/voice/my-voice.mp3",
        "file_name": "my-voice.mp3",
        "title": "我的音色"
      }'

地址必须是公网可直接下载的 HTTPS 直链;服务端会下载一次并长期保存。

备选二:传 base64

{
  "file_base64": "data:audio/mpeg;base64,//uQxAAA…",
  "file_name": "my-voice.mp3",
  "title": "我的音色"
}

体积会放大 1.33 倍,大文件请改用上传文件。

强化克隆(样本含版权内容时)

加一个 enhanced=true:

curl -sS -X POST "https://www.suno-api.io/api/music/voice-profile/create" \
  -H "Authorization: Bearer $API_KEY" \
  -F "file=@./my-voice.mp3" \
  -F "title=我的音色" \
  -F "enhanced=true"

3. ② 等音色就绪

curl -sS "https://www.suno-api.io/api/music/voice-profile/$VOICE_ID" \
  -H "Authorization: Bearer $API_KEY"

关注 data.status:

status 含义 处理
ready 可以用了 进入下一步
processing 还在处理 每 5–10 秒查一次;可展示 progress_percent / progress_message
failed 失败 看 error_message,费用已退回

4. ③ 生成音乐

同一个接口支持两种场景,用是否传 song_clip_id 区分。

场景 A:用我的音色翻唱一首指定歌曲

curl -sS -X POST "https://www.suno-api.io/api/music/voice-profile/cover" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Create-Ui-Client-Request-Id: cover-$(date +%s)" \
  -d '{
        "model": "suno-v6",
        "voice_id": "vp_20260926080618509168500DXXrxe",
        "song_clip_id": "5b773e9a-a035-4134-a4a4-29c9961d3ccb",
        "lyrics": "[Verse 1]\n原曲歌词…",
        "cover_requirements": "咬字更清晰一些",
        "style_requirements": "慢速民谣,木吉他",
        "audio_weight": 0.85,
        "max_mode": false
      }'

场景 B:只给音色和歌词,让它唱一首新歌

curl -sS -X POST "https://www.suno-api.io/api/music/voice-profile/cover" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Create-Ui-Client-Request-Id: sing-$(date +%s)" \
  -d '{
        "model": "suno-v6",
        "voice_id": "vp_20260926080618509168500DXXrxe",
        "lyrics": "[Verse 1]\n这是一段示例歌词\n\n[Chorus]\n用我的声音唱出来",
        "style_requirements": "温暖流行,中速,木吉他",
        "title": "用我的音色唱新歌",
        "audio_weight": 0.85,
        "duration": 120
      }'

常用字段

字段 必填 说明
model 是 对客模型名,推荐 suno-v6(另有 suno-v6-wild、suno-v6-mini)
voice_id 是 第 1 步拿到的音色 ID,必须 ready
song_clip_id 否 传了 = 翻唱这首歌(场景 A);不传 = 唱新歌(场景 B)
lyrics 否 歌词全文,逐字上送,≤3000 字符
cover_requirements 否 翻唱要求,例如「咬字更清晰」
style_requirements 否 风格要求,例如「慢速民谣,木吉他」
title 否 成品标题
audio_weight 否 音频参考度,0–1 小数,默认 0.85;越高越贴近音色样本
duration 否 期望时长(秒),1–480 的整数;平台实际最短约 30 秒
max_mode 否 true 时费用 ×2
client_request_id 否 写入任务记录,便于排查;不做去重

提交成功会立刻返回 2 个 song_id:

{
  "code": 200,
  "message": "success",
  "data": {
    "resolved_scene": "sing",
    "clips": [
      { "song_id": "9f1c…", "status": "processing" },
      { "song_id": "3a7d…", "status": "processing" }
    ]
  }
}

提交成功不代表已完成,必须继续查进度。


5. ④ 查询进度

curl -sS -X POST "https://www.suno-api.io/api/music/query" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"suno-v6","song_ids":"9f1c…,3a7d…"}'
[
  {
    "song_id": "9f1c…",
    "status": "completed",
    "audio_url": "https://…/assets/9f1c….mp3",
    "duration": 115.15,
    "model_version": "suno-v6",
    "generation_type": "voice_profile_cover"
  }
]

6. ⑤ 下载成品

方式一:直接用查询结果里的 audio_url。

方式二:走下载接口(返回音频字节流,文件名已带在响应头里):

curl -sS -L "https://www.suno-api.io/api/music/download?song_id=9f1c…&kind=mp3" \
  -H "Authorization: Bearer $API_KEY" \
  -o song.mp3

kind 可选:mp3(等价 song)/ playback / wav / video / lyrics。


7. 完整脚本(bash + curl + jq)

保存为 clone-and-generate.sh,按需改前三个变量:

#!/usr/bin/env bash
set -euo pipefail

API_KEY="sk-你的密钥"
BASE="https://www.suno-api.io"
VOICE_FILE="./my-voice.mp3"

auth=(-H "Authorization: Bearer ${API_KEY}")

# ---------- ① 创建音色 ----------
echo "[1/5] 创建音色…"
CREATE=$(curl -sS -X POST "${BASE}/api/music/voice-profile/create" \
  "${auth[@]}" \
  -F "file=@${VOICE_FILE}" \
  -F "title=我的音色" \
  -F "source_kind=upload")

VOICE_ID=$(echo "$CREATE" | jq -r '.data.voice_id')
VOICE_STATUS=$(echo "$CREATE" | jq -r '.data.status')
echo "voice_id=${VOICE_ID} status=${VOICE_STATUS}"

if [ -z "${VOICE_ID}" ] || [ "${VOICE_ID}" = "null" ]; then
  echo "$CREATE"; exit 1
fi

# ---------- ② 等音色就绪 ----------
echo "[2/5] 等待音色就绪…"
i=0
while [ "${VOICE_STATUS}" != "ready" ]; do
  if [ "${VOICE_STATUS}" = "failed" ]; then
    curl -sS "${BASE}/api/music/voice-profile/${VOICE_ID}" "${auth[@]}" | jq -r '.data.error_message'
    exit 1
  fi
  i=$((i + 1))
  if [ "$i" -gt 120 ]; then echo "音色创建超时"; exit 1; fi
  sleep 10
  DETAIL=$(curl -sS "${BASE}/api/music/voice-profile/${VOICE_ID}" "${auth[@]}")
  VOICE_STATUS=$(echo "$DETAIL" | jq -r '.data.status')
  echo "  status=${VOICE_STATUS} $(echo "$DETAIL" | jq -r '.data.progress_message // ""')"
done

# ---------- ③ 生成音乐 ----------
echo "[3/5] 提交生成…"
COVER=$(curl -sS -X POST "${BASE}/api/music/voice-profile/cover" \
  "${auth[@]}" \
  -H "Content-Type: application/json" \
  -H "X-Create-Ui-Client-Request-Id: demo-$(date +%s)" \
  -d @- <<JSON
{
  "model": "suno-v6",
  "voice_id": "${VOICE_ID}",
  "lyrics": "[Verse 1]\n这是一段示例歌词\n\n[Chorus]\n用我的声音唱出来",
  "style_requirements": "温暖流行,中速,木吉他",
  "title": "用我的音色唱新歌",
  "audio_weight": 0.85,
  "duration": 120
}
JSON
)

SONG_IDS=$(echo "$COVER" | jq -r '.data.clips | map(.song_id) | join(",")')
echo "song_ids=${SONG_IDS}"

if [ -z "${SONG_IDS}" ] || [ "${SONG_IDS}" = "null" ]; then
  echo "$COVER"; exit 1
fi

# ---------- ④ 轮询 ----------
echo "[4/5] 等待生成完成…"
i=0
while true; do
  i=$((i + 1))
  if [ "$i" -gt 90 ]; then echo "生成超时"; exit 1; fi
  sleep 10
  Q=$(curl -sS -X POST "${BASE}/api/music/query" \
    "${auth[@]}" \
    -H "Content-Type: application/json" \
    -d "{\"model\":\"suno-v6\",\"song_ids\":\"${SONG_IDS}\"}")
  DONE=$(echo "$Q" | jq -r '[.[] | select(.status == "completed")] | length')
  FAILED=$(echo "$Q" | jq -r '[.[] | select(.status == "failed")] | length')
  echo "  completed=${DONE} failed=${FAILED}"
  if [ "${DONE}" -ge 2 ]; then break; fi
  if [ "${FAILED}" -ge 1 ]; then echo "$Q"; exit 1; fi
done

# ---------- ⑤ 下载 ----------
echo "[5/5] 下载成品…"
n=0
for id in ${SONG_IDS//,/ }; do
  n=$((n + 1))
  curl -sS -L "${BASE}/api/music/download?song_id=${id}&kind=mp3" \
    "${auth[@]}" -o "song-${n}.mp3"
  echo "  saved song-${n}.mp3 (${id})"
done

echo "完成"

脚本依赖 jq。没有 jq 的话可以用下面的 Node.js 版本。


8. Node.js 最小示例(Node 18+)

import { readFile, writeFile } from "node:fs/promises";

const BASE = "https://www.suno-api.io";
const KEY = process.env.SUNO_API_KEY;
const auth = { Authorization: `Bearer ${KEY}` };

const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

// ① 创建音色
const form = new FormData();
form.append("file", new Blob([await readFile("./my-voice.mp3")]), "my-voice.mp3");
form.append("title", "我的音色");
form.append("source_kind", "upload");

const created = await (
  await fetch(`${BASE}/api/music/voice-profile/create`, {
    method: "POST",
    headers: auth,
    body: form,
  })
).json();

const voiceId = created.data.voice_id;
console.log("voice_id:", voiceId);

// ② 等音色就绪(普通克隆通常直接 ready)
let voice = created.data;
while (voice.status !== "ready") {
  if (voice.status === "failed") throw new Error(voice.error_message || "voice failed");
  await sleep(10000);
  const detail = await (
    await fetch(`${BASE}/api/music/voice-profile/${voiceId}`, { headers: auth })
  ).json();
  voice = detail.data;
  console.log("voice status:", voice.status, voice.progress_message || "");
}

// ③ 生成音乐(不传 song_clip_id = 用音色唱新歌)
const cover = await (
  await fetch(`${BASE}/api/music/voice-profile/cover`, {
    method: "POST",
    headers: {
      ...auth,
      "Content-Type": "application/json",
      "X-Create-Ui-Client-Request-Id": `demo-${Date.now()}`,
    },
    body: JSON.stringify({
      model: "suno-v6",
      voice_id: voiceId,
      lyrics: "[Verse 1]\n这是一段示例歌词\n\n[Chorus]\n用我的声音唱出来",
      style_requirements: "温暖流行,中速,木吉他",
      title: "用我的音色唱新歌",
      audio_weight: 0.85,
      duration: 120,
    }),
  })
).json();

const songIds = cover.data.clips.map((c) => c.song_id);
console.log("song_ids:", songIds);

// ④ 轮询
let rows = [];
for (let i = 0; i < 90; i++) {
  await sleep(10000);
  rows = await (
    await fetch(`${BASE}/api/music/query`, {
      method: "POST",
      headers: { ...auth, "Content-Type": "application/json" },
      body: JSON.stringify({ model: "suno-v6", song_ids: songIds.join(",") }),
    })
  ).json();
  const done = rows.filter((r) => r.status === "completed").length;
  console.log(`completed: ${done}/${songIds.length}`);
  if (done >= songIds.length) break;
}

// ⑤ 下载
for (const [i, id] of songIds.entries()) {
  const res = await fetch(`${BASE}/api/music/download?song_id=${id}&kind=mp3`, {
    headers: auth,
  });
  const buf = Buffer.from(await res.arrayBuffer());
  await writeFile(`song-${i + 1}.mp3`, buf);
  console.log(`saved song-${i + 1}.mp3`);
}

运行:

export SUNO_API_KEY="sk-你的密钥"
node clone-and-generate.mjs

9. 常见错误

HTTP message 原因与处理
401 无效的令牌 API Key 不对或已停用
200 one of file_path, file_base64, or file_url is required 创建音色时没带音频
200 Uploaded audio is too short (currently 2.4 seconds). Minimum duration is 6 seconds. 样本太短,换 ≥6 秒(建议 ≥10 秒)
200 This audio matches an existing recording in our catalog. 样本与曲库录音高度相似,换一段干净人声
400 voice_id is required and must be a ready voice 没传 voice_id,或传的是占位值
400 该音色不存在或已被删除(voice_id=vp_xxx)… 音色已删除、不存在或不属于当前账号;重新选择音色,或用同一段音频重新创建
400 voice is not ready yet (status=processing) 音色还在创建中,等 ready
500 model is required 生成时漏了 model
400 song_clip_id must be a real completed clip song_clip_id 是占位符或那首歌还没完成
400 song_clip_id must differ from the voice clip 翻唱对象不能就是音色样本本身
400 audio_weight must be a number between 0 and 1 audio_weight 要传 0–1 小数,不是百分数

10. 计费与限制速查

下一篇风格增强 API

开始接入

注册后即可在控制台创建 API Key,0.6 元一次固定生成 2 首,下载不限次数。

免费注册 查看完整文档