Suno API clients: Python and Node examples
The flow is the same in every language: submit, poll, then fetch. What differs is how each runtime handles timeouts - and that is where most bugs come from.
Before you start
- Keep the key server-side. Never ship it in front-end code, an app bundle or a public repo.
- Generation is asynchronous. A successful submit returns a task; the audio appears later.
- Budget per generation, not per request. One call returns two tracks.
- Read-only calls are free - status, downloads, lyrics and MIDI are not billed.
Python
import time, requests
BASE = "https://www.suno-api.io"
H = {"Authorization": "Bearer YOUR_API_KEY"}
# 1) submit
song = requests.post(f"{BASE}/api/music/create", headers=H, timeout=300, json={
"description": "warm lo-fi piano loop", "model": "suno-v6"
}).json()["data"]["clips"][0]["song_id"]
# 2) poll until complete
for _ in range(60):
status = requests.post(f"{BASE}/api/music/query", headers=H, timeout=60,
json={"song_id": song}).json()
if status.get("data", {}).get("status") in ("complete", "completed"):
break
time.sleep(4)
# 3) fetch a media url (free)
url = requests.post(f"{BASE}/api/music/download-url", headers=H, timeout=60,
json={"song_id": song, "kind": "song"}).json()
print(url)
Node
const BASE = "https://www.suno-api.io";
const H = { Authorization: "Bearer YOUR_API_KEY", "Content-Type": "application/json" };
const submit = await fetch(`${BASE}/api/music/create`, {
method: "POST", headers: H, body: JSON.stringify({ description: "warm lo-fi piano loop", model: "suno-v6" })
}).then((r) => r.json());
const songId = submit.data.clips[0].song_id;
let status = "";
while (status !== "complete" && status !== "completed") {
const q = await fetch(`${BASE}/api/music/query`, {
method: "POST", headers: H, body: JSON.stringify({ song_id: songId })
}).then((r) => r.json());
status = q.data?.status ?? "";
if (status !== "complete" && status !== "completed") await new Promise((r) => setTimeout(r, 4000));
}
The four mistakes worth avoiding
- A 30-second client timeout. Generation can take minutes; treat a timeout as "still running" and query the task.
- Resubmitting after a timeout. That is how duplicate charges happen - the first order was already placed.
- No backoff on 429. Add exponential backoff instead of retrying immediately.
- Storing the audio URL. Download links are temporary; store the song id and fetch a fresh URL when you need the file.
常见问题 / FAQ
Is there an official SDK?
No. Every provider exposes plain HTTP, which is why the examples above use only requests and fetch.
Do I need async code?
No. Polling with a sleep is fine for most workloads; async only helps when you run many generations in parallel.
What should the client timeout be?
Set it well above the slowest render you observe - a few minutes, not thirty seconds.
Is there an official Suno API? What you can actually use, and what it costs.
注册只需要邮箱,一次生成 0.6 元出 2 首,MP3 与 WAV 下载不限次。
Read the quick start
注册只需要邮箱,一次生成 0.6 元出 2 首,MP3 与 WAV 下载不限次。