API zum Hochladen und Covern in einem Schritt
Beschreibung des Endpunkts
Hochladen und Covern in einem Schritt übergibt eine Audiodatei oder eine Audio-URL und erzeugt daraus eine neue Cover-Version.
Endpunkt: POST /api/music/upload-cover
Abrechnung: Kostenpflichtig, derzeit standardmäßig 0,6 ¥ pro Aufruf. Dieser Endpunkt ist „hochladen und covern“ — es geht nicht um das Hochladen eines Bild-Covers. 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.
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.
Bei großem Audio sollten „Hochladen“ und „Covern“ in zwei Schritte getrennt werden (empfohlen)
Dieser Endpunkt verlangt, dass das ganze Audio in den Request-Body geht: je größer das Audio, desto größer der Body, und eine Netzwerkschwankung oder ein Timeout bricht die Übertragung mittendrin ab, woraufhin der Server
unexpected end of JSON inputzurückgibt (HTTP 400, keine Berechnung).Wenn das Audio etwa 8 MB übersteigt, das Netz instabil ist oder dasselbe Quellmaterial wiederverwendet wird, wechseln Sie zur zweistufigen Form:
POST /api/music/upload-sourcelädt zuerst das Quellaudio hoch — kostenlos, jederzeit wiederholbar — und liefert eineclip_id;POST /api/music/generate-from-sourcestartet mit dieserclip_iddas Cover — der Body des kostenpflichtigen Schritts ist nur etwa 250 Bytes groß.Siehe API zum Hochladen von Quellaudio, Cover-aus-Quell-Clip-API und „Große Dateien und abgeschnittene Requests“ am Ende dieser Seite.
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 |
|---|---|---|---|---|
| model | string | nein | suno-v6 | Kundenmodellname: suno-v6, suno-v6-wild oder suno-v6-mini |
| file_url | string | nein | - | URL des Quellaudios |
| file_base64 | string | nein | - | Audio als Base64 |
| file_name | string | nein | - | Dateiname |
| prompt | string | nein | - | Neuer Text oder Richtung der Bearbeitung |
| style | string | nein | - | Stil-Tags |
| title | string | nein | - | Titel |
| negativeTags | string | nein | - | Negativer Stil |
| instrumental | boolean | nein | false | Ob der Song instrumental ist |
| waitAudio | boolean | nein | false | Ob auf die Fertigstellung des Audios gewartet wird |
| cover_start_s | number | nein | - | Startsekunde des zu covernden Abschnitts |
| cover_end_s | number | nein | - | Endsekunde des zu covernden Abschnitts |
| audio_weight | number | nein | - | Abhängigkeit vom Referenzaudio, Bereich 0.0-1.0; nur sendbar, wenn ein Referenzaudio angegeben ist |
cover_start_s und cover_end_s sind in Sekunden und dürfen Dezimalwerte sein; die Startzeit muss kleiner als die Endzeit sein und darf die Länge des Quellaudios nicht übersteigen. Werden beide Felder weggelassen, wird das ganze Audio verwendet. audio_weight wird auf Sunos metadata.control_sliders.audio_weight abgebildet und steuert, wie stark sich das Ergebnis auf das Referenzaudio stützt; es nimmt 0.0-1.0 und darf nur mitgeschickt werden, wenn die Anfrage ein gültiges Referenzaudio über file_url oder file_base64 liefert. 0 ist ein gültiger Wert; das Weglassen des Felds bedeutet „nicht angegeben“ und behält Sunos Standardverhalten. instrumental und waitAudio müssen JSON-Boolesche Werte sein, keine Strings.
Der Upload-Endpunkt antwortet standardmäßig asynchron. Solange clips[].status in der Antwort pending ist, ist eine leere audio_url normal und bedeutet nicht, dass Upload oder Cover fehlgeschlagen sind; speichern Sie die zurückgegebene echte song_id und fragen Sie den Song-Abfrage-Endpunkt ab, bis der Vorgang fertig ist, bevor Sie die Audio-Adresse lesen.
Beispielanfrage
curl -X POST https://www.suno-api.io/api/music/upload-cover \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "suno-v6",
"file_url": "https://example.com/source.mp3",
"file_name": "source.mp3",
"prompt": "Neuer Text oder Richtung der Bearbeitung",
"style": "Mandopop, acoustic guitar",
"title": "Cover-Version",
"negativeTags": "noise, low quality",
"audio_weight": 0.5,
"instrumental": false,
"waitAudio": false,
"cover_start_s": 0,
"cover_end_s": 60
}'
Antwort
{
"code": 200,
"message": "success",
"data": {
"upload": {
"clip_id": "uploaded_clip_id",
"status": "complete"
},
"clips": [
{
"song_id": "new_clip_id",
"song_title": "Cover-Version",
"status": "pending"
}
]
}
}
Große Dateien und abgeschnittene Requests
Empfohlen: Hochladen und Covern in zwei Schritte trennen
Der Einmal-Endpunkt (dieser hier) fasst Hochladen und Generieren in einen Schritt zusammen: der große Body steckt in genau diesem einen Schritt, sodass bei einem Abbruch weder klar ist, ob etwas generiert wurde, noch ob berechnet wurde.
| Schritt 1 Hochladen | Schritt 2 Covern | |
|---|---|---|
| Endpunkt | POST /api/music/upload-source |
POST /api/music/generate-from-source |
| Abrechnung | Kostenlos (nur Upload, keine Generierung) | 0,6 ¥ pro Aufruf; 1,2 ¥ pro Aufruf mit Max Mode |
| Request-Body | Das Audio selbst (Base64 / Multipart) oder nur ein Link über file_url |
Etwa 250 Bytes (nur eine sourceClipId) |
| Rückgabe | clip_id (die Clip-ID des Quellaudios) |
data.clips[].song_id (das generierte Ergebnis) |
| Bei Fehlschlag | Einfach erneut versuchen, keine Berechnung und keine Generierungsaufgabe | Client-Timeout auf ≥300 s setzen; bei Timeout zuerst mit /api/music/songs prüfen und nicht sofort wiederholen |
| Quellmaterial wiederverwenden | Dieselbe clip_id funktioniert auch für Erweitern / Ersetzen / Trennen |
Das Audio muss jedes Mal neu hochgeladen werden |
Fazit: Audio über etwa 8 MB, instabiles Netz oder dasselbe Material mehrfach → zweistufige Form; winziges Audio bei stabilem Netz → dieser Endpunkt ist bequemer.
Was 400 unexpected end of JSON input bedeutet
Es bedeutet, dass das vom Server empfangene JSON unvollständig ist (kein falscher Parameter, kein Berechtigungs- oder Guthabenproblem). Die üblichen Ursachen, wahrscheinlichste zuerst:
- Ein großer Body mitten in der Übertragung abgeschnitten: die Eingangsschicht protokolliert sowohl „wie viele Bytes der Client angekündigt hat“ als auch „wie viele tatsächlich angekommen sind“. Gemessener Fall: der Client kündigte 14,17 MB an, angekommen sind nur 11,8–12,4 MB, und alle drei Anfragen stoppten bei etwa 1,6–1,7 s; die fehlende Bytezahl war jedes Mal anders, was auf einen Übertragungsabbruch und nicht auf ein festes Limit hindeutet (der Server begrenzt die Request-Body-Größe nicht).
Content-Lengthpasst nicht zu den tatsächlich gesendeten Bytes: in Node.js rechnet die Verwendung von.lengtheines Strings (UTF-16-Zeichenzahl) als Länge falsch, sobald der Inhalt chinesischen oder anderen Mehrbyte-Text enthält.- Der Body wurde als String statt als Buffer geschrieben, sodass die geschriebenen Bytes nicht zur Ankündigung passen.
Alle drei Fälle passieren vor der Abrechnung, es entstehen also keine Kosten.
Selbstprüfung im Client
-
Content-Lengthstammt ausBuffer.byteLength(json, 'utf8')(oderBuffer.from(json).length) — niemals ausjson.length; - Der Request-Body wird als Buffer geschrieben, nicht als String;
- Socket-/Request-Timeout ≥ 300 Sekunden;
- Wenn das Audio etwa 8 MB übersteigt:
file_urlnutzen (der Body ist nur wenige hundert Bytes), den Multipart-Upload vonupload-sourceverwenden oder direkt zur zweistufigen Form gehen; - Bei Multipart-Anfragen
Content-Typenicht manuell setzen (den Boundary vom Client ergänzen lassen); - Die „tatsächlich gesendeten Bytes“ ausgeben und mit
Content-Lengthvergleichen; - In der zweistufigen Form prüfen, dass Schritt 1 eine
clip_idmit abgeschlossenemstatusgeliefert hat, bevor Schritt 2 gesendet wird.
Häufige Fehler
| Fehler | Bedeutung | Vorgehen |
|---|---|---|
unexpected end of JSON input |
Request-Body unvollständig (abgeschnitten) | Selbstprüfung oben durchgehen oder zur zweistufigen Form wechseln |
invalid character '-' in numeric literal |
Ein Multipart-Body wurde an einen JSON-Endpunkt gesendet | Kein Multipart an JSON-Endpunkten, und Content-Type nicht manuell setzen |
one of file_path, file_base64, file_url, or multipart file is required |
Es wurde kein Audio mitgegeben | file_base64 / file_url / eine Multipart-file ergänzen |
model is required |
Der Body war leeres gültiges JSON (zum Beispiel {}) |
Mindestens model mitsenden |
Invalid request: Invalid request, ... |
Wrapper-Meldung für einen nicht auswertbaren Body | Die zweite Hälfte für den konkreten Grund lesen (meist einer der obigen) |
Verwandte Endpunkte: API zum Hochladen von Quellaudio (Schritt 1), Cover-aus-Quell-Clip-API (Schritt 2).
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