Generierungs-API im einfachen Modus
Beschreibung des Endpunkts
Die Generierung im einfachen Modus verwandelt eine einzeilige Beschreibung in einen fertigen Song. Der Dienst schreibt Text, Melodie, Arrangement und Gesang aus Ihrer Beschreibung.
Endpunkt: POST /api/music/create
Abrechnung: Kostenpflichtig, derzeit standardmäßig 0,6 ¥ pro Aufruf. Jeder Aufruf liefert meist 2 Songs; der tatsächlich berechnete Betrag folgt der aktuellen Preis-Konfiguration im Backoffice.
Max Mode / Variety: Dieser Endpunkt unterstützt die optionalen Parameter max_mode und variety (0-4). Mit
aktiviertem max_mode wird dieser Aufruf zum doppelten Preis abgerechnet (0,6 ¥ → 1,2 ¥ pro Aufruf); variety kostet
nichts extra. Bedeutung und Schreibweise stehen im Abschnitt „Erweiterte Parameter“ in der
Übersicht der neuen API.
Empfohlenes Modell: suno-v6
Wartezeiten und Timeouts (wichtig): Dies ist ein synchroner Endpunkt — die Bestellung wird erst angenommen und der Generierung übergeben, wenn die Antwort eintrifft. Gemessen antworten die meisten Anfragen in 1-3 Sekunden, etwa 10 % brauchen länger als 30 Sekunden und die längste liegt bei rund 230 Sekunden. Setzen Sie den Client-Timeout auf 300 Sekunden oder mehr; keine Antwort bedeutet nicht, dass nichts generiert wurde, und wiederholen Sie nicht direkt nach einem Timeout (das dupliziert die Bestellung und berechnet erneut). Wenn die Verbindung abbrach, prüfen Sie später mit
GET /api/music/songs. Siehe „Wartezeiten und Timeout-Einstellungen“ in der Übersicht der neuen API.
Anfrageparameter
Headers
| Parameter | Typ | Erforderlich | Hinweise |
|---|---|---|---|
| Authorization | string | ja | Bearer YOUR_API_KEY |
| Content-Type | string | ja | application/json |
Body-Parameter
| Parameter | Typ | Erforderlich | Standard | Hinweise |
|---|---|---|---|---|
| description | string | ja | - | Beschreibung des Songs, in beliebiger Sprache; höchstens 3000 Zeichen (mehr ergibt 400 und wird nicht berechnet) |
| model | string | nein | suno-v6 | Modellname für Kunden: suno-v6, suno-v6-wild oder suno-v6-mini |
| instrumental | boolean | nein | false | Ob der Song rein instrumental ist |
| wait_completion | boolean | nein | false | Ob auf den Abschluss der Generierung gewartet wird, bevor geantwortet wird |
| references | array | nein | - | Liste von Referenzmaterial, das Referenzsongs / Altstimmen / Referenzbilder tragen kann; höchstens 5 Songs, 1 Stimme und 1 Bild. Siehe „Referenzmaterial references (optional)“ unten |
Anfragebeispiele
curl -X POST https://www.suno-api.io/api/music/create \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "suno-v6",
"description": "ein schwungvoller Mandarin-Popsong über den Sommer am Meer",
"instrumental": false,
"wait_completion": false
}'
Referenzmaterial references (optional)
references ist ein Array, das dieser Generierung „Referenzmaterial“ anhängt. Es ist völlig optional (ohne Angabe verhält es sich genau wie zuvor), und Sie können nur eine Art oder jede Kombination anhängen.
Elementtypen
| type | Pflichtfeld | Optionale Felder | Maximum | Hinweise |
|---|---|---|---|---|
song |
song_id |
style_prompt, lyrics, duration_s |
5 | Referenzsong; die song_id kommt aus der API zum Abfragen von Songs und zum Verlauf, und der Song muss bereits abgeschlossen sein |
voice |
voice_id |
- | 1 | Altstimme; die voice_id kommt aus der API für Voice-Cloning und Generierung mit Stimme |
image |
base64 |
- | 1 | Referenzbild; senden Sie base64-Inhalt in der Form data:image/jpeg;base64,... |
Regeln
- Die Reihenfolge der Referenzsongs ist ihre semantische Reihenfolge: übergeben Sie sie in der gewünschten Reihenfolge (zum Beispiel „Melodie vom ersten, Gesang vom zweiten“).
style_prompt/lyrics/duration_sdürfen alle weggelassen werden; die Plattform füllt sie aus den Songinformationen, und was Sie senden, gilt.- Bei rein instrumentalen Songs darf
lyrics""oder"[Instrumental]"sein. - Referenzbilder unterstützen
jpeg/png/webp, je bis 10 MB, als base64 mit dem Body übermittelt. - Wenn Sie mehrere Referenzsongs anhängen, nutzen Sie zusätzlich
accept_mode=async(siehe „Empfangsbeleg-Modus“ oben): Der Dienst muss das Material erst vorbereiten, ein synchrones Warten kann also lang sein.
Beispiel: zwei Referenzsongs
curl -X POST https://www.suno-api.io/api/music/create \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "suno-v6",
"description": "fasse diese Ideen in einem Song zusammen",
"references": [
{ "type": "song", "song_id": "43eb711d-81f8-4e72-a68e-b2498bac88f9" },
{ "type": "song", "song_id": "a90438d2-35fc-4443-88f4-56531e6e5d24" }
]
}'
Beispiel: Referenzsong + Altstimme
{
"model": "suno-v6",
"description": "singe diese Ideen mit dieser Stimme",
"references": [
{ "type": "song", "song_id": "43eb711d-81f8-4e72-a68e-b2498bac88f9" },
{ "type": "voice", "voice_id": "5813cbe1-36f1-414a-a9a8-4d399dfeb292" }
]
}
Beispiel: Referenzsong + Referenzbild
{
"model": "suno-v6",
"description": "fange die Stimmung dieses Bildes ein",
"references": [
{ "type": "song", "song_id": "43eb711d-81f8-4e72-a68e-b2498bac88f9" },
{ "type": "image", "base64": "data:image/jpeg;base64,/9j/4AAQ..." }
]
}
Parameterfehler
Diese Fälle liefern HTTP 400, vor jeder Abrechnung blockiert, kosten also nichts:
| Fall | Fehlermeldung |
|---|---|
| Mehr als 5 Referenzsongs | references supports at most 5 song references |
| Mehr als 1 Stimme | references supports at most 1 voice reference |
| Mehr als 1 Referenzbild | references supports at most 1 image reference |
Ungültiger type |
references[0].type must be one of song, voice, image |
Song ohne song_id |
references[0].song_id is required |
| Song noch nicht fertig | references[0].song_id must be a real completed clip |
| Derselbe Song doppelt | references[0].song_id is duplicated |
Die Zahl in
references[0]ist der Index dieses Elements im Array, das fehlerhafte Element ist also leicht zu finden.
Antwort
Ein Array von Songs, das normalerweise 2 Aufgaben oder Songs enthält.
[
{
"song_id": "clip_id",
"song_title": "Sommerliche Meeresbrise",
"status": "pending",
"description": "ein schwungvoller Mandarin-Popsong über den Sommer am Meer",
"audio_url": "",
"cover_url": "",
"video_url": "",
"model_version": "suno-v6",
"generation_type": "generate",
"created_at": "2026-05-21T10:00:00Z"
}
]
Empfangsbeleg-Modus (optional, empfohlen für Clients, die keine langen Verbindungen halten sollen)
Standardmäßig ist dieser Endpunkt synchron: Das Eintreffen der Antwort bedeutet, dass die Bestellung angenommen wurde, und gemessene Wartezeiten können etwa 230 Sekunden erreichen. Wenn Ihr Client keine lange Verbindung halten soll, aktivieren Sie den Empfangsbeleg-Modus — beides funktioniert:
"accept_mode": "async"im Anfrage-Body ergänzen- den Header
X-Accept-Mode: asyncergänzen
Damit antwortet der Endpunkt sofort mit HTTP 202, was nur „angenommen und in der Generierungswarteschlange“ bedeutet, während die Generierung im Hintergrund weiterläuft:
{
"success": true,
"data": {
"request_id": "ac_20260920092714315816800d76fv3nq",
"status": "queued",
"accepted_at": 1789896434,
"pre_consumed_quota": 300000,
"tasks": [
{ "index": 0, "status": "queued" },
{ "index": 1, "status": "queued" }
]
}
}
Die Annahmephase liefert keine
song_id. Es existiert noch keine echte Song-ID, und wederrequest_idnochtasks[].indexsind eine Song-ID — speichern Sie sie nicht alssong_id. Die echtesong_iderscheint in der Fortschrittsabfrage unten.
Den Annahmefortschritt abfragen
Endpunkt: GET /api/music/requests/{request_id} (kostenlos, authentifiziert mit demselben API-Schlüssel)
curl "https://www.suno-api.io/api/music/requests/ac_20260920092714315816800d76fv3nq" \
-H "Authorization: Bearer YOUR_API_KEY"
{
"success": true,
"data": {
"request_id": "ac_20260920092714315816800d76fv3nq",
"status": "processing",
"tasks": [
{ "index": 0, "status": "processing", "song_id": "f3fa09f5-3d55-4953-826c-0d23f043ec57" },
{ "index": 1, "status": "processing", "song_id": "5fcafe3e-3fae-4d64-8f66-c01bc027b0c3" }
]
}
}
Was die einzelnen status-Werte bedeuten:
| status | Bedeutung |
|---|---|
queued |
Angenommen, noch nicht an konkrete Songs gebunden (tasks kann ein leeres Array sein) |
processing |
Zur Generierung übergeben |
partial |
Einer der beiden ist fertig |
completed |
Beide fertig, tasks[].song_id ist lesbar |
failed |
Übergabe fehlgeschlagen, der Betrag wurde vollständig erstattet, error_message nennt den Grund |
Jede Aufgabe hat zusätzlich ihr eigenes tasks[].status, mit denselben Werten wie die API zum Abfragen von Songs:
pending (übergeben, in Generierung), processing, completed, failed. Aufgabeneinträge können außerdem title,
duration und eine schon eingetragene audio_url tragen; was fehlt, ist einfach noch nicht generiert.
Sobald Sie die echte song_id haben, fahren Sie mit der API zum Abfragen von Songs oder den Download-Endpunkten fort.
Python-Beispiel
import time
import requests
BASE = "https://www.suno-api.io"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json"}
accepted = requests.post(
f"{BASE}/api/music/create",
headers={**HEADERS, "Idempotency-Key": "your-own-unique-key"},
json={"description": "ein schwungvoller Popsong", "model": "suno-v6", "accept_mode": "async"},
timeout=300,
).json()["data"]
request_id = accepted["request_id"]
while True:
time.sleep(5)
progress = requests.get(
f"{BASE}/api/music/requests/{request_id}", headers=HEADERS, timeout=60
).json()["data"]
if progress["status"] in ("completed", "failed"):
print(progress)
break
Kompatibilität und Hinweise
- Ohne
accept_modeverhält sich alles genau wie zuvor: synchrones Warten, Antwort200und Song-Array. Bestehende Integrationen müssen nichts ändern. - Dieser Schalter funktioniert derzeit nur bei
POST /api/music/createundPOST /api/music/create/custom; die übrigen Generierungs-Endpunkte unterstützen ihn noch nicht. - Senden Sie zusätzlich einen
Idempotency-Key(Ihre eigene eindeutige Zeichenkette, ≤128 Zeichen): derselbe Schlüssel wird nur einmal angenommen, eine Wiederholung liefert denselben Beleg, und es wird nicht doppelt berechnet. Im asynchronen Modus ist das besonders wichtig. - Mit
accept_mode=asyncwirdwait_completionignoriert (der Beleg kommt sofort zurück, ohne auf die Songs zu warten). - Der Betrag wird weiterhin bei der Annahme vorab abgebucht; eine fehlgeschlagene Generierung wird automatisch vollständig erstattet.
- Textfeldgrenze:
descriptionfasst höchstens 3000 Zeichen (gezählt in Unicode-Zeichen, ein Han-Zeichen zählt als 1). Längerer Text liefert direkt HTTP400, geht nie in die Generierung und wird nicht berechnet; die Fehlermeldung nennt die gemessene Länge, zum Beispieldescription must not exceed 3000 characters; received 4120. Dieser Endpunkt hat keine Text-/Stilfelder; dafür siehe „Textfeldgrenze“ in der Generierungs-API im benutzerdefinierten Modus. Die allgemeinen Regeln stehen in „Grenzen der Textfelder“ in der Übersicht der neuen API. - Ohne
referencessind Verhalten, Preis und Antwort genau wie zuvor: Bestehende Integrationen müssen nichts ändern. - Wenn Referenzmaterial angehängt wird (vor allem mehrere Referenzsongs), bevorzugen Sie den Belegmodus
accept_mode=asyncstatt langen synchronen Wartens; wie lange die Vorbereitung dauert, hängt von Menge und Herkunft des Materials ab.
Nächste Schritte
Sind die Songs beim Eintreffen der Antwort noch nicht fertig, holen Sie das Endergebnis mit der API zum Abfragen von Songs.
Beispiel für Node/Electron-Integration
Wenn Sie die Standardgenerierung im Electron-Hauptprozess, in einem Node.js-Server oder in einem Desktop-Client einbinden, ist dies der empfohlene Ablauf:
- Rufen Sie
POST /api/music/createauf, um die Generierungsaufgabe zu erstellen. - Lesen Sie
song_idoderidaus der Antwort. - Rufen Sie alle 2 Sekunden
POST /api/music/queryauf, um den Status zu prüfen. - Betrachten Sie die Generierung als abgeschlossen, sobald
audio_urlim Abfrageergebnis erscheint.
Verwenden Sie die alten Pfade POST /api/generate oder GET /api/clip?id=... nicht mehr; sie gehören nicht zur aktuell empfohlenen öffentlichen Integrationsfläche.
const http = require('http');
const https = require('https');
const BASE_URL = 'https://www.suno-api.io';
const MODEL = 'suno-v6';
const POLL_INTERVAL_MS = 2000;
const MAX_POLL_ATTEMPTS = 60;
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
function requestJson(urlString, apiKey, body) {
const url = new URL(urlString);
const transport = url.protocol === 'https:' ? https : http;
const payload = JSON.stringify(body);
return new Promise((resolve, reject) => {
const req = transport.request(
{
method: 'POST',
hostname: url.hostname,
port: url.port || undefined,
path: `${url.pathname}${url.search}`,
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(payload),
},
},
(res) => {
let raw = '';
res.setEncoding('utf8');
res.on('data', (chunk) => {
raw += chunk;
});
res.on('end', () => {
const data = raw ? JSON.parse(raw) : {};
if (!res.statusCode || res.statusCode < 200 || res.statusCode >= 300) {
reject(new Error(`Suno API request failed: HTTP ${res.statusCode} ${raw}`));
return;
}
resolve(data);
});
}
);
req.on('error', reject);
req.write(payload);
req.end();
});
}
function getPayload(response) {
return response && response.data !== undefined ? response.data : response;
}
function toSongList(payload) {
if (Array.isArray(payload)) return payload;
if (Array.isArray(payload?.songs)) return payload.songs;
if (Array.isArray(payload?.clips)) return payload.clips;
return payload ? [payload] : [];
}
function collectSongIds(createResponse) {
return toSongList(getPayload(createResponse))
.map((song) => song.song_id || song.id)
.filter(Boolean);
}
async function generateSunoSong({ apiKey, description, instrumental = false }) {
const createResponse = await requestJson(`${BASE_URL}/api/music/create`, apiKey, {
description,
model: MODEL,
instrumental,
wait_completion: false,
});
const songIds = collectSongIds(createResponse);
if (songIds.length === 0) {
throw new Error(`Suno API did not return song ids: ${JSON.stringify(createResponse)}`);
}
for (let attempt = 0; attempt < MAX_POLL_ATTEMPTS; attempt += 1) {
await sleep(POLL_INTERVAL_MS);
const queryResponse = await requestJson(`${BASE_URL}/api/music/query`, apiKey, {
song_ids: songIds,
model: MODEL,
});
const songs = toSongList(getPayload(queryResponse));
const completed = songs.find((song) => song.audio_url);
if (completed) {
return {
audioUrl: completed.audio_url,
title: completed.song_title || completed.title || 'Suno Song',
duration: completed.duration,
};
}
const allFailed = songs.length > 0 && songs.every((song) =>
['failed', 'error', 'rejected'].includes(String(song.status || '').toLowerCase())
);
if (allFailed) {
throw new Error(`Suno generation failed: ${JSON.stringify(songs)}`);
}
}
throw new Error('Suno generation timed out after 120 seconds. Please query again later.');
}
// Usage:
// generateSunoSong({
// apiKey: process.env.SUNO_API_KEY,
// description: 'A bright pop song about the ocean in summer',
// }).then(console.log).catch(console.error);
In echten Projekten gehört der API-Schlüssel in eine Server-Umgebungsvariable, eine Desktop-Client-Einstellung oder einen sicheren Speicher — nie in Frontend-Code und nie ins Repository.
API-Schlüssel erhalten
Erstellen Sie nach der Anmeldung einen API-Schlüssel in der Konsole. Jede Generierung kostet 0,6 ¥ und liefert 2 Tracks, Downloads sind unbegrenzt und eine Telefonnummer ist nicht erforderlich.
API-Schlüssel holen Zurück zur Übersicht