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 下载不限次。
查看接口清单
注册只需要邮箱,一次生成 0.6 元出 2 首,MP3 与 WAV 下载不限次。