♪Suno API 中文教程

Suno API 的 Node.js 调用示例

不需要 SDK:Node 18 自带的 fetch、一个任务 ID,加上一个轮询循环就够了。

提交并保存任务 ID

const BASE = "https://www.suno-api.io";
const H = {
  Authorization: `Bearer ${process.env.SUNO_API_KEY}`,
  "Content-Type": "application/json",
};

const created = await fetch(`${BASE}/api/music/create`, {
  method: "POST",
  headers: H,
  body: JSON.stringify({
    description: "明亮的中文流行,钢琴前奏,温暖女声",
    model: "suno-v6",
  }),
  signal: AbortSignal.timeout(300_000),
}).then((r) => r.json());

const songId = created.data.clips[0].song_id;
console.log({ songId });

先落库再轮询。进程重启后任务还在,但没有任务 ID 就找不回来。

轮询到完成

async function waitForSong(songId) {
  for (let i = 0; i < 75; i += 1) {
    const task = await fetch(`${BASE}/api/music/query`, {
      method: "POST",
      headers: H,
      body: JSON.stringify({ song_id: songId }),
      signal: AbortSignal.timeout(60_000),
    }).then((r) => r.json()).then((r) => r.data);

    if (["complete", "completed"].includes(task.status)) return task;
    if (["failed", "error"].includes(task.status)) throw new Error(task.reason || "failed");
    await new Promise((resolve) => setTimeout(resolve, 4000));
  }
  throw new Error("仍在生成,保留任务 ID 稍后再查");
}

超时只代表客户端不等了,不代表任务失败。正确做法是查同一个任务,而不是重新提交。

取下载地址

任务完成后调用 POST /api/music/download-url,传 { song_id, kind: "song" }。返回的是临时取件地址;要长期保存就存任务 ID,需要文件时重新取一次。

遇到 429 用指数退避(1s → 2s → 4s),并降低并发生成数;读取类接口也会限流,只是不计费。

接着看:Python 版本 · 轮询与超时 · 并发与队列。

常见问题 / FAQ

需要装官方 SDK 吗?

不需要。接口就是普通 HTTP,用 Node 自带 fetch 或 undici 都能调。

Node 版本有要求吗?

建议 Node 18+,自带 fetch 和 AbortSignal.timeout;更老的版本用 AbortController 代替。

能同时跑很多首吗?

可以,但要加队列和并发上限。无上限地并发提交,最快的结果就是 429。

申请 Key、第一个请求、接口清单与报错排查
注册只需要邮箱,一次生成 0.6 元出 2 首,MP3 与 WAV 下载不限次。
查看接口清单