Suno API in Node.js: a working loop
No SDK is required: Node 18's fetch, a task id, and a polling loop are enough to get from a prompt to a file.
Submit and keep the task 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: "warm Mandarin pop, piano intro, female vocal",
model: "suno-v6",
}),
signal: AbortSignal.timeout(300_000),
}).then((r) => r.json());
const songId = created.data.clips[0].song_id;
console.log({ songId });Persist songId before you start polling. If the process restarts, the task still exists; without the id you cannot find it.
Poll with a real timeout
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("still running; keep the task id and check again");
}A timeout means your client stopped waiting, not that the render failed. Query the same task instead of submitting a new one.
Download a fresh URL
When the task is complete, call POST /api/music/download-url with { song_id, kind: "song" }. The result is temporary; store the task id and fetch a new link later instead of saving the URL as a permanent field.
On 429, back off (1s → 2s → 4s) and reduce parallel generations. Reads are cheap, but they are still rate-limited.
Next: Python version · polling vs webhooks · rate limits.
常见问题 / FAQ
Which Node version do I need?
Node 18 or newer for built-in fetch and AbortSignal.timeout. On older versions use undici and an AbortController.
Is there an npm SDK?
No. A small wrapper around fetch is enough; keeping it in your own code makes retries and logging explicit.
Can I run many songs at once?
Yes, but cap concurrency and queue work. Increasing parallel requests without a queue is the fastest way to get 429s.
注册只需要邮箱,一次生成 0.6 元出 2 首,MP3 与 WAV 下载不限次。