Documentação
Geração de música
Geração de música a partir de texto com Suno V5 / V5.5 — vocais, letras e controle de estilo. Dois formatos de API: um endpoint síncrono de etapa única que aguarda até as faixas ficarem prontas e um par assíncrono de envio e consulta (com webhooks assinados) para produção.
Endpoints: POST /v1/audio/music (síncrono, apresentado primeiro) e POST /v1/audio/music/jobs + GET /v1/audio/music/jobs/{id} (assíncrono, recomendado para produção). Cada solicitação gera duas faixas; a geração leva cerca de 1–3 minutos. Preço: $0.09 por solicitação de geração em suno-v5, $0.09 em suno-v5-5 — as duas faixas são cobradas uma vez, com saldo pré-pago, e uma geração malsucedida não é cobrada.
Início rápido (síncrono)
Envie um prompt e um modelo Suno. A solicitação permanece aberta até as duas faixas ficarem prontas e, então, retorna as URLs permanentes delas.
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"))Parâmetros
| Parâmetro | Tipo | Observações |
|---|---|---|
model | string (obrigatório) | Um slug de modelo de música — suno-v5 ou suno-v5-5. |
prompt | string (obrigatório) | Descrição da música (ou a letra, no modo personalizado). |
instrumental | bool | true = sem vocais. Padrão: false. |
customMode | bool | Modo Suno avançado — controle explicitamente a estrutura / letra / estilo. |
style | string | Indicação de estilo / gênero, por exemplo, "lofi, jazz, chill". |
title | string | Título da faixa. |
webhook_url | string (https) | Somente no modo assíncrono — envie aqui um evento terminal assinado. Consulte Webhooks. |
Modelos de música
| Slug | Provedor | Observações |
|---|---|---|
suno-v5 | Suno | Suno V5 — vocais, letras e combinação de estilos. |
suno-v5-5 | Suno | Suno V5.5 — mais recente, com maior fidelidade e gerações mais longas. |
Consulte /models para ver a lista atual e os preços por chamada.
API assíncrona (envio + consulta)
Endpoints: POST /v1/audio/music/jobs + GET /v1/audio/music/jobs/{id}. Segue o padrão da API assíncrona de vídeo, então o mesmo código de consulta / webhook funciona em diferentes modalidades.
O endpoint síncrono mantém uma conexão HTTP aberta por minutos — conveniente para scripts, mas pouco confiável em dispositivos móveis. O par assíncrono retorna imediatamente um ID msc_*; consulte GET /v1/audio/music/jobs/{id} até que status seja completed ou failed. Mesmos modelos, mesmos preços e mesmas URLs permanentes de CDN.
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 da resposta
| Campo | Tipo | Observações |
|---|---|---|
id | string | ID de tarefa com prefixo msc_. |
object | string | "music". |
status | string | queued | in_progress | completed | failed. |
model | string | O slug do modelo enviado. |
created_at | int | Segundos Unix em que aceitamos o envio. |
completed_at | int | null | Segundos Unix em que a tarefa terminou — null enquanto estiver pendente. |
expires_at | int | Segundos Unix após os quais o resultado é removido (~30 dias). |
progress | int | 0 até a tarefa terminar; depois, 100. |
output | object | null | {tracks[], archived} quando concluído. |
output. | array | Cada um: {url, stream_url, image_url}. url / image_url são links permanentes de CDN. |
error | object | null | {code, message} quando falha. |
Cabeçalhos e convenções
Idempotency-Key(opcional, ≤128 caracteres) — se você enviar duas vezes a mesma chave na mesma conta, receberá a tarefa original em vez de criar uma duplicata.POST /v1/audio/music/jobsretorna 202 Accepted em um novo envio e 200 OK quando uma chave de idempotência reproduz um resultado.GETé restrito ao proprietário: consultar uma tarefa pertencente a outra conta retorna 404.- Frequência de consulta recomendada: 5 s, aumentando gradualmente até 30 s.
Webhooks
Envie webhook_url (https) ao submeter a solicitação, e Kunavo fará um POST de um evento assinado music.completed / music.failed assim que a tarefa terminar — com entrega e novas tentativas com intervalo crescente. O campo data do evento corresponde exatamente ao conteúdo da solicitação GET acima.
# 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... } }HMAC-SHA256 sobre {timestamp}.{rawBody}, enviada como X-Kunavo-Webhook-Signature: sha256=<hex>. O mesmo método dos webhooks de vídeo, então um único verificador atende a ambos.Quando usar cada um
| Síncrono /v1/ | Assíncrono /v1/ | |
|---|---|---|
| Melhor para | Scripts e notebooks de uso pontual | Produção, dispositivos móveis e webhooks |
| Rede | Mantém a conexão aberta por 1–3 min | Envie em segundos; consulte ou receba a atualização automaticamente |
| Recuperação de falhas | Perder a resposta = perder o resultado | Consulte o ID novamente a qualquer momento antes de expires_at |
| Webhooks | — | Eventos music. |
Resposta e armazenamento
O url (áudio) e o image_url (arte da capa) de cada faixa são links permanentes files.kunavo.com — Kunavo arquiva cada resultado em sua própria CDN, então, ao contrário das URLs brutas do Suno, eles nunca expiram. stream_url é o link original de streaming do Suno (útil para reprodução instantânea). Cada faixa também aparece em /app/assets.
output.archived será false e as URLs voltarão a ser links temporários do Suno (que expiram após cerca de 24 h) — nesse caso, hospede-os novamente por conta própria.