Dokumentation

Dokumentation

Musikgenerierung

Text zu Musik mit Suno V5 / V5.5 — Gesang, Liedtexte und Stilsteuerung. Zwei API-Formate: ein einzelner synchroner Endpunkt, der blockiert, bis die Tracks bereitstehen, und ein asynchrones Submit-and-Poll-Paar (mit signierten Webhooks) für den Produktionseinsatz.

Endpunkte: POST /v1/audio/music (synchron, zuerst behandelt) und POST /v1/audio/music/jobs + GET /v1/audio/music/jobs/{id} (asynchron, für den Produktionseinsatz empfohlen). Jede Anfrage generiert zwei Tracks; die Generierung dauert etwa 1–3 Minuten. Preis: $0.09 pro Generierungsanfrage bei suno-v5, $0.09 bei suno-v5-5 — beide Tracks werden einmalig aus einem vorausbezahlten Guthaben abgerechnet; eine fehlgeschlagene Generierung wird nicht berechnet.

Schnellstart (synchron)

Übergeben Sie ein prompt und ein Suno-Modell. Die Anfrage bleibt offen, bis beide Tracks bereitstehen; anschließend werden ihre permanenten URLs zurückgegeben.

import requests

# Synchronous: one request blocks until the tracks are ready (1-3 min).
resp = requests.post(
    "https://api.kunavo.com/v1/audio/music",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={
        "model": "suno-v5",
        "prompt": "upbeat lofi hip hop for late-night coding, mellow piano",
        "instrumental": True,
    },
    timeout=600,  # generation can take a few minutes
)
# Suno returns ~2 tracks per request.
for track in resp.json()["data"]:
    print(track["url"], track.get("image_url"))
Suno-Generierungen dauern 1–3 Minuten. Der synchrone Endpunkt hält die Verbindung serverseitig offen, bis die Tracks bereitstehen, und pollt dabei höchstens etwa 6 Minuten. Legen Sie daher für Ihren HTTP-Client einen entsprechenden Timeout fest (≥600s). Bei längerer Dauer, Produktionsverkehr oder mobilen beziehungsweise unzuverlässigen Netzwerken empfiehlt sich die asynchrone API — die Übermittlung wird in Sekunden abgeschlossen.

Parameter

ParameterTypHinweise
modelString (erforderlich)Ein Musikmodell-Slug — suno-v5 oder suno-v5-5.
promptString (erforderlich)Beschreibung der Musik (oder im benutzerdefinierten Modus der Liedtext).
instrumentalbooltrue = kein Gesang. Standardwert false.
customModeboolErweiterter Suno-Modus — Struktur, Liedtexte und Stil explizit steuern.
stylestringHinweis zu Stil oder Genre, z. B. „lofi, jazz, chill“.
titlestringTracktitel.
webhook_urlZeichenfolge (https)Nur asynchron — hier ein signiertes Abschlusssignal senden. Siehe Webhooks.

Musikmodelle

SlugAnbieterHinweise
suno-v5SunoSuno V5 — Gesang, Liedtexte, Stilüberblendung.
suno-v5-5SunoSuno V5.5 — neueste Version, höhere Klangtreue und längere Generierungen.

Unter /models finden Sie die aktuelle Liste und die Preise pro Aufruf.

Asynchrone API (Submit + Poll)

Endpunkte: POST /v1/audio/music/jobs + GET /v1/audio/music/jobs/{id}. Entspricht der asynchronen Video-API, sodass derselbe Polling- und Webhook-Code für beide Modalitäten funktioniert.

Der synchrone Endpunkt hält eine HTTP-Verbindung minutenlang offen — praktisch für Skripte, aber unzuverlässig auf Mobilgeräten. Das asynchrone Endpunktpaar gibt sofort eine msc_*-ID zurück. Fragen Sie GET /v1/audio/music/jobs/{id} wiederholt ab, bis status den Status completed oder failed hat. Modelle, Preise und permanente CDN-URLs sind dieselben.

import requests, time

# 1. Submit — returns immediately with a msc_ task id. No long-lived connection.
submit = requests.post(
    "https://api.kunavo.com/v1/audio/music/jobs",
    headers={
        "Authorization": f"Bearer {API_KEY}",
        # Optional: retrying with the same key inside ~24h returns the
        # original task rather than submitting again.
        "Idempotency-Key": "my-song-uuid",
    },
    json={
        "model": "suno-v5",
        "prompt": "dreamy synthwave with a driving bassline",
        "title": "Midnight Drive",
    },
    timeout=60,
).json()

task_id = submit["id"]              # "msc_abc..."
status  = submit["status"]          # "queued"

# 2. Poll until terminal. Recommended cadence: 5s, backing off to 30s.
while status not in ("completed", "failed"):
    time.sleep(5)
    r = requests.get(
        f"https://api.kunavo.com/v1/audio/music/jobs/{task_id}",
        headers={"Authorization": f"Bearer {API_KEY}"},
        timeout=30,
    ).json()
    status = r["status"]

if status == "failed":
    raise RuntimeError(r["error"]["message"])
for track in r["output"]["tracks"]:
    print(track["url"])

Antwortformat

FeldTypHinweise
idstringAufgaben-ID mit Präfix msc_.
objectstring"music".
statusstringqueued | in_progress | completed | failed.
modelstringDer übermittelte Modell-Slug.
created_atintUnix-Zeit in Sekunden, zu der wir die Übermittlung angenommen haben.
completed_atint | nullUnix-Zeit in Sekunden beim Abschluss — bei ausstehenden Aufgaben null.
expires_atintUnix-Zeit in Sekunden, ab der das Ergebnis bereinigt wird (~30 Tage).
progressintBis zum Abschluss 0, danach 100.
outputobject | null{tracks[], archived} bei abgeschlossenem Vorgang.
output.tracksarrayJeder Eintrag: {url, stream_url, image_url}. url / image_url sind dauerhafte CDN-Links.
errorobject | null{code, message} bei fehlgeschlagenem Vorgang.

Header und Konventionen

  • Idempotency-Key (optional, ≤128 Zeichen) — wird derselbe Schlüssel im selben Konto zweimal verwendet, wird die ursprüngliche Aufgabe zurückgegeben, statt ein Duplikat zu erstellen.
  • POST /v1/audio/music/jobs gibt bei einer neuen Übermittlung 202 Accepted und bei der erneuten Ausgabe eines Ergebnisses mithilfe eines Idempotenzschlüssels 200 OK zurück.
  • GET ist auf den jeweiligen Inhaber beschränkt: Wird eine Aufgabe abgefragt, die zu einem anderen Konto gehört, wird 404 zurückgegeben.
  • Empfohlenes Polling-Intervall: 5 s, schrittweise verlängert bis auf 30 s.

Webhooks

Übergeben Sie bei der Übermittlung webhook_url (https). Kunavo sendet dann beim Abschluss der Aufgabe ein signiertes Ereignis music.completed / music.failed per POST. Die Zustellung erfolgt mit Wiederholungsversuchen und schrittweise verlängerten Intervallen. Das Feld data des Ereignisses entspricht exakt der oben gezeigten GET-Antwort.

# Pass webhook_url on submit to be pushed a signed event on terminal —
# instead of (or alongside) polling:
#   {"model": "suno-v5", "prompt": "...", "webhook_url": "https://you.com/hook"}
#
# Verify the HMAC signature on your receiver (Flask shown):
import hmac, hashlib
from flask import request, abort

def verify(secret: str) -> dict:
    ts  = request.headers["X-Kunavo-Webhook-Timestamp"]
    sig = request.headers["X-Kunavo-Webhook-Signature"]   # "sha256=<hex>"
    raw = request.get_data(as_text=True)
    expected = "sha256=" + hmac.new(
        secret.encode(), f"{ts}.{raw}".encode(), hashlib.sha256
    ).hexdigest()
    if not hmac.compare_digest(expected, sig):
        abort(401)
    return request.get_json()

# Event body:
#   { "id": "evt_...", "object": "event",
#     "type": "music.completed" | "music.failed",
#     "created_at": 1700000000,
#     "data": { ...the GET /v1/audio/music/jobs/{id} payload... } }
Die Signatur ist HMAC-SHA256 über {timestamp}.{rawBody} und wird als X-Kunavo-Webhook-Signature: sha256=<hex> gesendet. Das Verfahren entspricht den Video-Webhooks, sodass ein Verifizierer für beide genügt.

Wann welche Variante verwenden

Synchron /v1/audio/musicAsynchron /v1/audio/music/jobs
Am besten geeignet fürEinmalige Skripte, NotebooksProduktion, Mobilgeräte, Webhooks
NetzwerkHält die Verbindung 1–3 Minuten offenIn Sekunden einreichen; abfragen oder Push-Benachrichtigungen erhalten
FehlerbehebungAntwort verloren = Ergebnis verlorenID jederzeit vor Ablauf von expires_at erneut abfragen
Webhooks—Signierte music.completed- / music.failed-Ereignisse

Antwort und Speicherung

Der url-Link (Audio) und der image_url-Link (Coverbild) jedes Tracks sind permanente files.kunavo.com-Links. Kunavo archiviert jedes Ergebnis auf dem eigenen CDN; anders als die ursprünglichen Suno-URLs laufen sie deshalb nie ab. stream_url ist der ursprüngliche Suno-Streaming-Link (praktisch für sofortige Wiedergabe). Jeder Track erscheint außerdem in /app/assets.

Falls die Archivierung fehlschlägt, ist output.archived false und die URLs verweisen auf die temporären Suno-Links (die nach etwa 24 Stunden ablaufen) — hosten Sie sie in diesem Fall selbst erneut.

Nächste Schritte