Documentación

Documentación

Generación de música

Generación de música a partir de texto con Suno V5 / V5.5: voces, letras y control del estilo. Dos formatos de API: un endpoint síncrono que espera hasta que las pistas estén listas y otro par asíncrono de envío y consulta (con webhooks firmados) para producción.

Endpoints: POST /v1/audio/music (síncrono, explicado primero) y POST /v1/audio/music/jobs + GET /v1/audio/music/jobs/{id} (asíncrono, recomendado para producción). Cada solicitud genera dos pistas; la generación tarda aproximadamente entre 1 y 3 minutos. Precio: $0.09 por solicitud de generación en suno-v5, $0.09 en suno-v5-5: ambas pistas se facturan una sola vez con cargo a un saldo prepagado; las generaciones fallidas no se facturan.

Inicio rápido (síncrono)

Envía un prompt y un modelo Suno. La solicitud se mantiene abierta hasta que ambas pistas estén listas y, entonces, devuelve sus URL permanentes.

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"))
Las generaciones de Suno tardan entre 1 y 3 minutos. El endpoint síncrono mantiene abierta la conexión en el servidor hasta que las pistas estén listas, con un límite de espera de consulta de unos 6 minutos, así que configura el cliente HTTP con un tiempo de espera equivalente (≥600s). Para cualquier tarea más lenta, tráfico de producción o redes móviles o poco fiables, prefiere la API asíncrona: el envío tarda segundos.

Parámetros

ParámetroTipoNotas
modelcadena (obligatorio)Un slug de modelo de música: suno-v5 o suno-v5-5.
promptcadena (obligatorio)Descripción de la música (o la letra, en modo personalizado).
instrumentalbooltrue = sin voces. Predeterminado: false.
customModeboolModo avanzado de Suno: controla explícitamente la estructura, las letras y el estilo.
stylestringIndicación de estilo o género, por ejemplo, «lofi, jazz, chill».
titlestringTítulo de la pista.
webhook_urlcadena (https)Solo asíncrono: envía aquí un evento terminal firmado. Consulta Webhooks.

Modelos de música

SlugProveedorNotas
suno-v5SunoSuno V5: voces, letras y mezcla de estilos.
suno-v5-5SunoSuno V5.5: el más reciente, con mayor fidelidad y generaciones más largas.

Consulta /models para ver la lista actualizada y los precios por llamada.

API asíncrona (enviar + consultar)

Endpoints: POST /v1/audio/music/jobs + GET /v1/audio/music/jobs/{id}. Sigue el mismo patrón que la API asíncrona de vídeo, así que el mismo código de consulta y webhook sirve para ambas modalidades.

El endpoint síncrono mantiene abierta una conexión HTTP durante varios minutos: es práctico para scripts, pero poco fiable en móviles. El par asíncrono devuelve de inmediato un identificador msc_*; consulta GET /v1/audio/music/jobs/{id} hasta que status sea completed o failed. Los modelos, los precios y las URL permanentes de CDN son los mismos.

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"])

Formato de la respuesta

CampoTipoNotas
idstringIdentificador de tarea con el prefijo msc_.
objectstring"music".
statusstringen cola | en curso | completada | fallida.
modelstringEl slug del modelo que enviaste.
created_atintSegundos Unix en que aceptamos la solicitud.
completed_atint | nullSegundos Unix en que la tarea llegó a un estado terminal; null mientras está pendiente.
expires_atintSegundos Unix tras los cuales se elimina el resultado (unos 30 días).
progressint0 hasta que la tarea llegue a un estado terminal; después, 100.
outputobject | null{tracks[], archived} al completarse.
output.tracksarrayCada uno: {url, stream_url, image_url}. url / image_url son enlaces permanentes de CDN.
errorobject | null{code, message} si falla.

Encabezados y convenciones

  • Idempotency-Key (opcional, ≤128 caracteres): si se envía dos veces la misma clave en la misma cuenta, se devuelve la tarea original en lugar de crear un duplicado.
  • POST /v1/audio/music/jobs devuelve 202 Accepted en un envío nuevo y 200 OK cuando una clave de idempotencia reproduce un resultado.
  • GET está limitado al propietario: consultar una tarea que pertenece a otra cuenta devuelve 404.
  • Frecuencia de consulta recomendada: cada 5 s, aumentando gradualmente hasta 30 s.

Webhooks

Al enviar la solicitud, proporciona webhook_url (https) y Kunavo enviará un evento terminal firmado music.completed / music.failed en cuanto termine la tarea, con reintentos y espera progresiva. El campo data del evento es exactamente el contenido de la respuesta GET anterior.

# 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... } }
La firma es HMAC-SHA256 sobre {timestamp}.{rawBody} y se envía como X-Kunavo-Webhook-Signature: sha256=<hex>. El mismo procedimiento que para los webhooks de vídeo, así que un solo verificador sirve para ambos.

Cuándo usar cada uno

Síncrono /v1/audio/musicAsíncrono /v1/audio/music/jobs
Ideal paraScripts puntuales y notebooksProducción, móviles y webhooks
RedMantiene la conexión abierta entre 1 y 3 minEnvía en segundos; consulta o recibe el resultado automáticamente
Recuperación tras fallosPerder la respuesta = perder el resultadoVuelve a consultar el identificador en cualquier momento antes de expires_at
Webhooks—Firmado music.completed / music.failed

Respuesta y almacenamiento

El url (audio) y el image_url (ilustración de portada) de cada pista son enlaces permanentes files.kunavo.com: Kunavo archiva cada resultado en su propia CDN, así que, a diferencia de las URL originales de Suno, nunca caducan. stream_url es el enlace original de streaming de Suno (útil para la reproducción inmediata). Todas las pistas también aparecen en /app/assets.

Si alguna vez falla el archivado, output.archived será false y las URL pasarán a ser enlaces temporales de Suno (que caducan al cabo de unas 24 h); en ese caso, vuelve a alojarlas por tu cuenta.

Próximos pasos