Saltar a contenido

API Reference

API empresarial async — drop-in replacement de la API de Suno AI, ejecutada localmente.

Lanzar

# 1. Redis broker
docker run -p 6379:6379 -d redis:7

# 2. Worker GPU (1 por GPU)
celery -A src.api.worker.app worker -P solo --concurrency=1 --loglevel=info

# 3. API
uvicorn src.api.main:app --host 0.0.0.0 --port 8000 --workers 1

Endpoints

GET /health

Comprobación de vida.

GET /api/v1/voices

Lista VAEs registrados, LoRAs disponibles y rutas del SmartRouter.

curl http://localhost:8000/api/v1/voices
Respuesta:
{
  "vae_variants": ["oobleck", "scragvae", "xcodec", "rvq_codec"],
  "lora_styles": ["lana_del_rey_inspired", "trap_2024", "vallenato_old_school"],
  "routes": ["fast", "stereo_mix", "ace", "dual_stem", "auto"]
}

POST /api/v1/generate

Encola una generación. Respuesta inmediata con task_id.

Payload:

{
  "prompt": "Una bachata romántica en La menor sobre un amor de verano",
  "lyrics": "[VERSE]\nLa luna brilla sobre el mar\n[CHORUS]\nQuédate conmigo esta noche",
  "duration_s": 60,
  "mode": "ace",
  "cfg_scale": 4.0,
  "dcw_mode": "double",
  "n_steps": 50,
  "seed": 42,
  "genre": "bachata",
  "mood": "romantico",
  "bpm": 125,
  "key": "Amin"
}

Modos: - "auto" — router heurístico decide - "fast" — DDIM con menos pasos (~25), latencia mínima - "stereo_mix" — pipeline clásico (SongGenerator) - "ace" — ACE-Step híbrido (default para >60s) - "dual_stem" — SongGen interleaving (vocals + instrumental separados)

Respuesta:

{"task_id": "f4a8...", "status": "queued"}

POST /api/v1/inpaint

Repintado de una ventana temporal de una canción ya generada.

{
  "source_song_id": "f4a8-...",
  "mask_start_s": 45.0,
  "mask_end_s": 60.0,
  "new_prompt": "guitarra solo más expresiva",
  "new_lyrics": "",
  "seed": 7,
  "n_steps": 50
}

GET /api/v1/status/{task_id}

Polling del estado.

{
  "task_id": "f4a8...",
  "status": "processing",
  "progress": 0.65,
  "meta": {"step": "DDIM sampling (50 steps)"}
}

Cuando termina:

{
  "task_id": "f4a8...",
  "status": "completed",
  "url": "out/api/f4a8.../master.wav",
  "elapsed_s": 12.34,
  "meta": {"plan": {...}, "mode": "ace", "duration_s": 60.0}
}

GET /api/v1/files/{task_id}/{filename}

Descarga del WAV producido (con protección anti path-traversal).

Filenames típicos: - master.wav — mezcla maestra final - vocals_stem.wav (solo en dual_stem) - instrumental_stem.wav (solo en dual_stem) - master_preview.wav (suma vocal+instr para preview rápido)

DELETE /api/v1/jobs/{task_id}

Cancela / revoca un trabajo en cola.

Cliente Python

import time
import requests

BASE = "http://localhost:8000"

def generate(prompt, **kw):
    r = requests.post(f"{BASE}/api/v1/generate",
                       json={"prompt": prompt, **kw}, timeout=30)
    r.raise_for_status()
    return r.json()["task_id"]

def wait(task_id, timeout=600):
    t0 = time.time()
    while time.time() - t0 < timeout:
        s = requests.get(f"{BASE}/api/v1/status/{task_id}").json()
        if s["status"] in ("completed", "failed"):
            return s
        print(f"  {s['status']}  progress={s.get('progress', 0):.0%}")
        time.sleep(2)
    raise TimeoutError

task = generate("Bachata romántica en La menor, 125 BPM",
                lyrics="[VERSE]\nLa luna brilla...",
                duration_s=45, mode="ace")
res = wait(task)
print(res["url"])

Cliente curl

TASK=$(curl -s -X POST http://localhost:8000/api/v1/generate \
  -H "Content-Type: application/json" \
  -d '{"prompt":"Bachata 125 BPM en La menor","duration_s":30,"mode":"ace"}' \
  | jq -r .task_id)
while :; do
  STATE=$(curl -s "http://localhost:8000/api/v1/status/$TASK" | jq -r .status)
  echo "  $STATE"
  [ "$STATE" = "completed" ] && break
  [ "$STATE" = "failed" ] && exit 1
  sleep 2
done
curl -s "http://localhost:8000/api/v1/status/$TASK" | jq

Seguridad y observabilidad

  • En producción, montar detrás de un reverse proxy (nginx / Caddy) con TLS.
  • Activar require_api_key: true en configs/api.yaml para forzar header X-API-Key.
  • Rate limit por IP via middleware (no incluido por defecto; añadir slowapi).
  • Logs estructurados en stdout (recoger con Loki / Vector).
  • Métricas Prometheus en /metrics si se instala prometheus-fastapi-instrumentator.