Tutorial
Cómo usar mureka-9.5/instrumental a través de la API de HiAPI: guía con curl y Python
Qué hace mureka-9.5/instrumental en HiAPI
mureka-9.5/instrumental es un endpoint de texto a música en HiAPI, ajustado específicamente para salidas puramente instrumentales: música de fondo, bucles, música de ambiente y bandas sonoras. Describes la pista con un prompt, envías una sola tarea y HiAPI devuelve un recurso de audio terminado que puedes descargar y colocar en juegos, ediciones de vídeo, pódcast o demos de producto.
La palabra clave es instrumental. El endpoint está orientado a música sin interpretación vocal principal, por lo que encaja en escenarios donde la narración o el diálogo deben permanecer claros e inteligibles. Si necesitas pistas cantadas con letra, ese es otro problema; si necesitas una capa limpia de música de fondo bajo una locución, esta es la herramienta correcta.
Elige este endpoint cuando:
- Quieras generar música de fondo (BGM) en lugar de tomarla de una biblioteca musical.
- Necesites generar rápidamente y por programación muchas variantes, en lugar de un encargo personalizado puntual.
- Tu pipeline ya use HTTP y quieras tratar la música como cualquier otro paso de generación de recursos.
- Te importe una forma de petición predecible: enviar, consultar, descargar.
Como en otros endpoints de generación musical, el trabajo es asíncrono. Tras el envío se devuelve una tarea que debes seguir hasta que el audio esté generado. Si diseñas el código en torno a esto desde el principio, el resto de la integración es rutina.
Dónde encaja en un producto
El usuario típico es un pipeline de contenido que necesita pistas bajo demanda: un renderizador de vídeo que quiere una capa musical bajo cada clip, un juego que quiere bucles ambientales o una herramienta de prototipado que permite al usuario introducir un estado de ánimo y escuchar el resultado. Como el endpoint se controla por texto, puedes plantillar prompts con los metadatos que ya tengas (género, sensación rítmica, estado de ánimo y duración prevista) y generarlos en el momento del renderizado.
Trata cada petición como una tarea de generación con su propio ciclo de vida. Este enfoque mantiene razonables tu lógica de reintentos, el registro y el cálculo de costes.
Preparativos antes de enviar una petición
Antes de que la primera llamada tenga éxito hay que cumplir algunas condiciones. Ninguna es complicada, pero omitir una es la causa más habitual de que falle la primera petición.
Credenciales
Necesitas una clave de API de HiAPI. Trátala como un secreto: cárgala desde una variable de entorno como HIAPI_API_KEY, nunca la codifiques directamente en los scripts que envíes y rótala si se filtra. La clave se envía como token bearer en la cabecera Authorization.
export HIAPI_API_KEY="your_api_key_here"
Endpoint y transporte
Llamas al modelo mureka-9.5/instrumental a través de la API unificada de HiAPI. La URL base es el host de la API de HiAPI; el identificador del modelo se coloca en el payload de la petición o en la ruta según la convención que HiAPI documente para este endpoint. Usa HTTPS, envía Content-Type: application/json y envía un cuerpo JSON.
No adivines los nombres de los parámetros. HiAPI documenta los campos que acepta este modelo; cualquier cosa fuera de ese conjunto, en el mejor de los casos se ignora y, en el peor, se rechaza. Si el campo que quieres no está documentado, no forma parte del contrato: construye en torno a lo que sí lo está.
Qué tener preparado
- Un prompt que describa la música: género, instrumentación, estado de ánimo, sensación rítmica y uso previsto.
- Opciones de duración o variantes que el modelo exponga y documente.
- Un lugar donde almacenar el identificador de la tarea y, más tarde, la URL de descarga.
- Acceso de red desde donde se ejecuta el código hasta el host de HiAPI.
Una nota sobre los tiempos
La generación no es instantánea. Configura tiempos de espera holgados en el cliente y cuenta con tener que consultar el estado. El pensamiento síncrono (enviar la petición y bloquear hasta que el audio vuelva en la misma respuesta) produce código frágil.
Una petición curl que funciona
Empieza con curl. Elimina todas las capas entre tú y la conversación HTTP, así que si algo va mal lo ves de inmediato.
La llamada
curl -sS -X POST "$HIAPI_BASE_URL" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "mureka-9.5/instrumental",
"input": {
"prompt": "warm lo-fi hip hop instrumental, mellow electric piano, soft vinyl crackle, relaxed 80 bpm, no vocals"
}
}'
Configura primero las dos variables de entorno, de modo que no quede información sensible en claro en el historial del shell salvo el contenido que tú elijas:
export HIAPI_BASE_URL="https://api.hiapi.ai/v1/..." # usa la ruta documentada para este endpoint
export HIAPI_API_KEY="your_api_key_here"
Qué hace cada parte
-X POST: el envío es una operación de creación.-H "Authorization: Bearer ...": autentica la llamada con tu cuenta.-H "Content-Type: application/json": indica al servidor que el cuerpo es JSON; si lo omites, muchos servidores rechazan el cuerpo directamente.-d '{...}': el payload JSON. El campomodelespecifica el endpoint; el objetoinputtransporta tu prompt y otros campos documentados.-sS: silencia el progreso pero sigue mostrando errores. Resulta útil en scripts.
Leer la respuesta
La respuesta es JSON. Debes buscar un identificador de tarea o trabajo y un campo de estado. Imprímela de forma legible para poder inspeccionarla:
curl -sS -X POST "$HIAPI_BASE_URL" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d @payload.json | jq .
Conserva el identificador. Es el asa para cada comprobación de estado posterior. No analices todo el cuerpo de la respuesta en tu aplicación; extrae el ID de tarea y el estado, y guarda la respuesta sin procesar para depurar.
Si obtienes un estado que no sea 2xx, lee el cuerpo: HiAPI devuelve mensajes de error estructurados que suelen señalar el campo problemático.
La misma petición en Python
La versión en Python se corresponde exactamente con la llamada curl: mismas cabeceras, mismo cuerpo JSON. Usa requests por comodidad o la biblioteca estándar si prefieres cero dependencias.
Con requests
import os
import requests
API_KEY = os.environ["HIAPI_API_KEY"]
BASE_URL = os.environ["HIAPI_BASE_URL"]
payload = {
"model": "mureka-9.5/instrumental",
"input": {
"prompt": (
"warm lo-fi hip hop instrumental, mellow electric piano, "
"soft vinyl crackle, relaxed 80 bpm, no vocals"
)
},
}
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
resp = requests.post(BASE_URL, json=payload, headers=headers, timeout=30)
resp.raise_for_status()
data = resp.json()
job_id = data["id"] # use the documented field name
print("submitted:", job_id, data.get("status"))
Con la biblioteca estándar
Si no puedes añadir dependencias:
import json, os, urllib.request
req = urllib.request.Request(
os.environ["HIAPI_BASE_URL"],
data=json.dumps(payload).encode("utf-8"),
headers={
"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}",
"Content-Type": "application/json",
},
method="POST",
)
with urllib.request.urlopen(req, timeout=30) as r:
data = json.load(r)
Hábitos prácticos
- Usa
timeout=30solo al enviar. La consulta de estado necesita su propio bucle y su propio tiempo de espera. - Llama a
raise_for_status()antes de analizar la respuesta. El cuerpo de una respuesta de error no es una tarea. - Envuelve la extracción del ID de tarea en una pequeña función auxiliar, para que un cambio de nombre de campo se arregle en una sola línea.
- Nunca registres la clave de API; registra en su lugar el ID de tarea y el estado.
- Mantén el payload como un diccionario en el código, serialízalo una vez y así las pruebas pueden hacer aserciones sobre él.
Gestionar tareas asíncronas y la consulta de estado
El envío es el primer paso. La generación ocurre en el servidor y termina más tarde, así que consultas el endpoint de estado hasta que la tarea informa de un estado terminal.
Forma del bucle
- Envía la tarea y captura el ID.
- Espera brevemente.
- Consulta el estado de ese ID.
- Si el estado es en cola o en proceso, retrocede y repite.
- Si el estado es de éxito, lee la salida.
- Si el estado es de fallo, registra el error y detente: no reintentes a ciegas.
Una implementación fiable
import time, random, requests
def wait_for_job(job_id, base_status_url, headers,
timeout_s=600, initial_delay=2.0, max_delay=30.0):
deadline = time.monotonic() + timeout_s
delay = initial_delay
while time.monotonic() < deadline:
r = requests.get(f"{base_status_url}/{job_id}", headers=headers, timeout=30)
r.raise_for_status()
status = r.json()["status"]
if status in ("succeeded", "completed", "success"):
return r.json()
if status in ("failed", "error", "cancelled"):
raise RuntimeError(f"job {job_id} ended as {status}: {r.text}")
time.sleep(delay + random.uniform(0, 0.5)) # jitter
delay = min(delay * 1.5, max_delay) # exponential backoff
raise TimeoutError(f"job {job_id} did not finish in {timeout_s}s")
Por qué importa cada detalle
- Jitter: evita reintentos sincronizados cuando se ejecutan muchas tareas en paralelo.
- Backoff: evita martillear el endpoint de estado mientras se renderiza la pista.
- Deadline: convierte un bloqueo indefinido en una excepción limpia que el pipeline puede manejar.
- Comprobación de estado terminal: debe coincidir con las cadenas de estado documentadas por HiAPI. Confírmalas con la referencia de la API en lugar de fiarte de suposiciones.
- Reintentos: deben aplicarse a errores de red transitorios (tiempos de espera, 5xx), no a tareas que ya fallaron por un error de validación.
Consejos operativos
Persiste el job_id antes de empezar a consultar. Si tu proceso muere, puedes reanudar la consulta en lugar de pagar por una segunda generación. Registra las transiciones de estado con marca de tiempo para ver dónde se emplea el tiempo. Si ejecutas muchas tareas, consulta en paralelo un pequeño número de ellas mediante una cola, en lugar de bloquear un hilo de peticiones por tarea.
Obtener la salida instrumental y descargarla
El modo instrumental se expresa en tu petición, ya que el endpoint está dedicado a este tipo de salida. En la práctica, la redacción del prompt lo refuerza: nombra los instrumentos, describe el estado de ánimo y declara que no hay vocals. Un prompt que pide líneas vocales entra en conflicto con el propósito del endpoint.
Dónde aparece el audio
Cuando la tarea alcanza un estado de éxito, la respuesta de estado lleva el resultado. Lo esperable es que el audio se entregue como una URL obtenida por separado, no como base64 dentro del JSON de estado. Lee la respuesta y extrae la URL de descarga del campo de salida documentado.
result = wait_for_job(job_id, status_url, headers)
# Revisa el resultado con cuidado las primeras veces y luego fija el campo.
audio_url = result["output"]["audio_url"] # confirma el nombre del campo en la referencia de la API
with requests.get(audio_url, stream=True, timeout=60) as r:
r.raise_for_status()
with open(f"{job_id}.mp3", "wb") as f:
for chunk in r.iter_content(chunk_size=65536):
f.write(chunk)
Hábitos de descarga
- Escribe en disco en streaming. Los archivos de música son grandes; cargarlos por completo en memoria es una presión evitable.
- Comprueba el tipo de contenido. Guarda el archivo con la extensión que indique la respuesta, no con una extensión codificada a mano.
- Trata la URL como temporal. Descarga pronto o persiste la URL solo si la documentación indica que es estable. Copia los bytes a tu propio almacenamiento para conservarlos.
- Descarga una sola vez. Descargar dentro de un bucle de reintentos sin una marca de finalización crea fácilmente archivos parciales. Escribe con un nombre temporal y renombra al terminar correctamente.
- Registra la procedencia. Guarda el ID de tarea y el prompt junto al archivo. Así, cuando más adelante necesites una variante, tendrás las entradas exactas.
Puntos habituales de fallo y sus soluciones
La mayoría de los problemas de una primera integración caen en una lista corta. Esta es la lista de comprobación.
401 / 403: autenticación. La cabecera es incorrecta, falta la clave o la variable de entorno se resuelve como cadena vacía. Verifica que la clave está definida en el mismo shell o proceso en el que ejecutas el código y que la cabecera se lee exactamente como Authorization: Bearer <key>.
400: payload mal formado. Falta model, hay una errata en mureka-9.5/instrumental, el JSON no es válido o el endpoint no acepta algún campo. Envía primero el cuerpo con curl para aislar el payload del código. Valida el JSON antes de enviarlo; las comas finales son un clásico.
415 o errores de cuerpo vacío: tipo de contenido. Debe estar presente Content-Type: application/json. Algunos clientes HTTP lo configuran automáticamente cuando pasas json=, pero no todos.
Tiempo de espera agotado en la consulta. Tu plazo es demasiado corto, tu backoff es demasiado agresivo o la tarea realmente falló y la clasificaste como aún en ejecución. Comprueba las cadenas de estado exactas con la documentación e imprime cada transición al depurar.
Falta la URL de descarga. Leíste el campo equivocado o leíste la respuesta antes de que la tarea alcanzara el estado terminal de éxito. Registra una carga completa de éxito una vez, confirma la ruta de la URL de audio y luego fíjala.
Generaciones duplicadas. Tu consultor se cayó y algo volvió a enviar la tarea. Persiste el ID de tarea antes de consultar y comprueba si ya existe una tarea antes de enviar una nueva.
Límites de tasa. Ante respuestas 429, retrocede con jitter y pon el trabajo en cola, en lugar de lanzarlo simultáneamente desde muchos hilos.
Aborda estos puntos en este orden (autenticación, payload, tipo de contenido, consulta, salida) y normalmente darás con la causa a la primera. Una vez que la llamada curl y su gemela en Python funcionan de extremo a extremo, el endpoint está haciendo lo que le pides: convertir un prompt en una pista instrumental y entregarte una URL de descarga.
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