Tutorial
Cómo usar la API MiniMax Music (minimax-music-1.5): curl, Python y una solicitud ejecutable
Esta guía explica cómo usar minimax-music-1.5 en la API de tareas unificada de hiapi para generar una canción completa —con voces, instrumentos y estructura— a partir de un prompt de estilo y una letra. Todo lo siguiente se ha verificado contra el endpoint real y se puede copiar, pegar y ejecutar directamente.
Qué vas a construir y qué necesitas preparar
Objetivo: enviar una descripción textual de un estilo musical y tu letra, y obtener una pista de audio descargable.
Solo necesitas una cosa: una clave de API de hiapi. Obténla desde tu panel de control; empieza por sk-. Todos los ejemplos siguientes asumen que está guardada en una variable de entorno:
export HIAPI_KEY="sk-your-key-here"
La generación de música en hiapi usa la misma interfaz de tareas asíncronas que todos los demás modelos: POST /v1/tasks crea la tarea y luego o bien consultas repetidamente GET /v1/tasks/<taskId>, o bien recibes una callback cuando la tarea finaliza.
Esquema de entrada (verificado)
minimax-music-1.5 acepta los siguientes campos dentro de input; cualquier otro campo se rechaza con un 400:
| Campo | ¿Obligatorio? | Tipo | Restricción |
|---|---|---|---|
prompt |
Sí | string | 10–300 caracteres. Describe el género, el estado de ánimo, la instrumentación y el estilo vocal. |
lyrics |
Sí | string | 10–600 caracteres. La letra que se va a cantar; admite etiquetas de sección como [Verse] y [Chorus]. |
sample_rate |
No | integer | Uno de 16000, 24000, 32000, 44100. |
bitrate |
No | integer | Uno de 32000, 64000, 128000, 256000. |
Hay dos puntos en los que es fácil tropezar:
promptylyricsson ambos obligatorios. El prompt controla cómo suena; la letra controla qué se canta. Si falta cualquiera de los dos, obtendrásinvalid input: ... missing required field.- El esquema es estricto. Los campos que podrías esperar de otras API de música —
duration,seed,format,instrumental— no se aceptan. Enviarlos devuelveadditional properties ... not allowed.
Ejemplo mínimo ejecutable: curl
Crear la tarea:
curl -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "minimax-music-1.5",
"input": {
"prompt": "Uplifting acoustic pop, warm female vocals, gentle guitar and light percussion",
"lyrics": "[Verse]\nMorning light on a quiet street\nCoffee steam and a steady beat\n[Chorus]\nWe keep on going, we find our way\nOne small step at a time, every day",
"sample_rate": 44100,
"bitrate": 256000
}
}'
Una creación correcta devuelve un id de tarea:
{"code": 200, "data": {"taskId": "task_abc123..."}}
Luego consulta repetidamente hasta que la tarea llegue a un estado terminal:
curl https://api.hiapi.ai/v1/tasks/task_abc123 \
-H "Authorization: Bearer $HIAPI_KEY"
Mientras la tarea se ejecuta verás un status no terminal; al completarse, status pasa a success y la URL del audio aparece en output:
{
"code": 200,
"data": {
"taskId": "task_abc123",
"status": "success",
"output": [{"url": "https://.../track.mp3"}]
}
}
Descarga el archivo cuanto antes: las URL de salida tienen caducidad; trátalas como una ventana de recogida, no como almacenamiento permanente:
curl -o track.mp3 "https://.../track.mp3"
Script completo de Python: enviar, consultar, descargar
import os
import time
import requests
API_BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {
"Authorization": f"Bearer {os.environ['HIAPI_KEY']}",
"Content-Type": "application/json",
}
def create_task() -> str:
payload = {
"model": "minimax-music-1.5",
"input": {
"prompt": ("Uplifting acoustic pop, warm female vocals, "
"gentle guitar and light percussion"),
"lyrics": ("[Verse]\nMorning light on a quiet street\n"
"Coffee steam and a steady beat\n"
"[Chorus]\nWe keep on going, we find our way\n"
"One small step at a time, every day"),
"sample_rate": 44100,
"bitrate": 256000,
},
}
r = requests.post(API_BASE, headers=HEADERS, json=payload, timeout=60)
data = r.json()
task_id = (data.get("data") or {}).get("taskId")
if not task_id:
raise RuntimeError(f"create failed: {data}")
return task_id
def wait_task(task_id: str, timeout_s: int = 600, poll_s: int = 5) -> dict:
deadline = time.time() + timeout_s
while time.time() < deadline:
r = requests.get(f"{API_BASE}/{task_id}", headers=HEADERS, timeout=30)
task = (r.json().get("data") or {})
status = task.get("status")
if status == "success":
return task
if status == "fail":
err = task.get("error") or {}
raise RuntimeError(f"task failed: {err.get('code')} {err.get('message')}")
time.sleep(poll_s)
raise TimeoutError(f"task {task_id} still running after {timeout_s}s")
def download(url: str, path: str = "track.mp3") -> str:
r = requests.get(url, timeout=120)
r.raise_for_status()
with open(path, "wb") as f:
f.write(r.content)
return path
if __name__ == "__main__":
task_id = create_task()
print(f"submitted: {task_id}")
task = wait_task(task_id)
url = task["output"][0]["url"]
print(f"done, downloading: {url}")
print(f"saved to {download(url)}")
Ejecútalo con python3 make_song.py. El script envía la tarea, consulta cada 5 segundos y guarda la pista terminada en local.
Patrones para producción
Usar callbacks en lugar de consultas repetidas
Para cualquier uso que vaya más allá de un script rápido, registra una callback para que hiapi te envíe el resultado cuando la tarea llegue a un estado terminal. Añade un objeto callback de nivel superior (al mismo nivel que model, no dentro de input):
{
"model": "minimax-music-1.5",
"input": {"prompt": "...", "lyrics": "..."},
"callback": {"url": "https://your.domain.example/hiapi/callback", "when": "final"}
}
Solo se admite "when": "final": recibirás un único POST cuando la tarea tenga éxito o falle, no eventos de progreso incrementales. La consulta repetida va bien para desarrollo y tareas puntuales; las callbacks son mejores cuando generas muchas pistas o ejecutas en cola, porque no tienes que mantener un bucle abierto y no activarás límites de velocidad por consultar con demasiada frecuencia. Si la callback nunca llega, revisa la lista de comprobación de por qué no se dispara tu callback de tareas de hiapi.
Idempotencia y reintentos
La creación de tareas no es idempotente: reintentar un POST /v1/tasks que ha expirado puede crear dos tareas (y generar dos cargos). Persiste el taskId en cuanto la llamada de creación devuelva, y al reiniciar recupera consultando ese id en lugar de reenviar a ciegas. Si una tarea parece atascada, no la mates y la recrees de inmediato; consulta cuando una tarea de hiapi /v1/tasks se cuelga o expira para saber cómo distinguir una tarea lenta de una muerta.
Manejo de errores
Los dos tipos de fallo se comportan de forma distinta:
- Errores a nivel de solicitud se devuelven de forma síncrona. Una clave errónea o no autorizada devuelve un error
permission_denied("This API key cannot use the selected model..."), junto con unrequest_idque puedes citar al equipo de soporte. Las infracciones del esquema devuelven400 INVALID_REQUESTcon un mensaje preciso, por ejemploprompt: minLength: got 1, want 10. - Fallos a nivel de tarea aparecen en el resultado de la consulta o la callback como
status: "fail", conerror.codeyerror.message: la llamada de creación tuvo éxito, pero la generación no. Estos son los fallos que deben entrar en tu lógica de reintentos.
Valida las longitudes en el cliente antes de enviar: prompt admite como máximo 300 caracteres y lyrics como máximo 600; la API rechaza las entradas demasiado largas en lugar de truncarlas.
Precios y límites
MiniMax Music 1.5 se factura por pista generada, con precios según uso; consulta las tarifas actuales en la página de precios de hiapi y en la página del modelo minimax-music-1.5, donde además puedes probar el modelo en el playground antes de escribir código.
Preguntas frecuentes
¿Qué campos de entrada acepta minimax-music-1.5?
Exactamente cuatro: prompt (obligatorio, 10–300 caracteres), lyrics (obligatorio, 10–600 caracteres), sample_rate (opcional, 16000/24000/32000/44100) y bitrate (opcional, 32000/64000/128000/256000). Cualquier otro campo se rechaza con additional properties not allowed.
¿Se puede controlar la estructura de la canción?
Sí: usa etiquetas de sección como [Verse] y [Chorus] dentro de lyrics para organizar la estructura. El modelo aprovecha esas etiquetas para dar forma al arreglo. La cadena completa de la letra (incluidas las etiquetas) debe mantenerse dentro del límite de 600 caracteres.
¿Se puede generar música puramente instrumental?
El esquema de entrada no tiene un interruptor de instrumental. Este endpoint está guiado por la letra, así que describe en prompt la instrumentación y el estado de ánimo que quieres; para casos de uso puramente instrumentales, consulta la página del modelo para ver la lista actual de capacidades.
¿Cómo se obtiene el archivo de audio?
Cuando el estado de la tarea es success, data.output[0].url contiene el enlace de descarga. Obtenlo de inmediato y guarda los bytes por tu cuenta: las URL de salida caducan.
¿Debo consultar repetidamente o usar callbacks?
Para desarrollo y tareas individuales, consulta repetidamente (un intervalo de 5 segundos es suficiente). En producción, usa callback con when: "final" para no mantener conexiones abiertas, sobre todo si generas pistas en lote.
¿Por qué recibo permission_denied?
Tu clave no es válida o no tiene permiso para acceder a ese modelo. Verifica la clave en el panel de control y asegúrate de enviarla como Authorization: Bearer sk-....
Artículos relacionados
Ver todos los artículos →-
Tutorial
Cómo llamar a hailuo-2.3-fast/image-to-video a través de la API de HiAPI: práctica con curl y Python
La primera solicitud ejecutable del nivel rápido y de bajo coste de imagen a vídeo: del ID del modelo a la descarga del MP4
-
Tutorial
Cómo llamar a hailuo-2.3/text-to-video mediante la API de HiAPI: curl, Python y ejemplos de solicitud ejecutables
-
Tutorial
Uso de Kandinsky 6.0 Pro texto a video en HiAPI: tutorial con curl y Python
Demostración práctica centrada en la solicitud: construir la llamada de prompt a clip de video, enviar la solicitud, sondear el estado de finalización y descargar el resultado