Tutorial
Cómo llamar a la API mirelo-sfx-2.0 a través de HiAPI: curl, Python y sondeo asíncrono
Funciones y escenarios de aplicación de mirelo-sfx-2.0
mirelo-sfx-2.0 es un modelo de texto a efectos de sonido disponible a través de HiAPI. Le proporcionas una descripción en lenguaje natural —por ejemplo, «una pesada puerta de madera que se abre lentamente con un chirrido» o «una moneda que cae sobre una mesa de mármol»— y genera un fragmento de audio breve que coincide con el prompt.
Este es el endpoint que debes usar cuando necesites diseño de sonido generado bajo demanda, en lugar de obtener licencias de una biblioteca de samples:
- Prototipado de juegos y aplicaciones: genera sonidos provisionales o definitivos para interacciones, eventos de UI y bucles ambientales.
- Postproducción de vídeo y pódcast: rellena huecos con audio estilo foley sin necesidad de reservar un estudio de grabación.
- Pipelines generativos: obtén prompts a partir de guiones, storyboards o entradas del usuario y adjunta el WAV generado a la salida.
El modelo rinde mejor cuando la descripción del sonido es clara y la duración es corta. Si necesitas música, voz o audio largo, eso pertenece a otra familia de modelos: mirelo-sfx-2.0 se centra en efectos de sonido discretos.
Dado que la generación es asíncrona, planifica tu integración en torno a tareas en lugar de llamadas HTTP bloqueantes. El resto de este tutorial construye esa integración, desde la petición curl en bruto hasta un cliente Python que sondea hasta obtener el WAV final.
Requisitos previos y configuración de la autenticación
Antes de la primera llamada, asegúrate de disponer de:
- Una cuenta de HiAPI y una clave de API. Puedes crear y gestionar claves en la consola de HiAPI. Trata la clave como una contraseña: cárgala desde una variable de entorno o un gestor de secretos y nunca la confirmes en un repositorio de código.
- Una herramienta para enviar peticiones HTTP. Para este tutorial basta con
curl; los ejemplos de código usan Python 3.8+. - Un cliente HTTP en Python. Los ejemplos usan
requestspor simplicidad, pero sirve cualquier cliente capaz de enviar JSON y cabeceras.
HiAPI usa una única URL base y un único método de autenticación para todos los modelos, así que las convenciones que aprendas aquí se aplican también a otros endpoints:
export HIAPI_API_KEY="your-api-key-here"
Cada petición envía la clave en la cabecera Authorization:
Authorization: Bearer $HIAPI_API_KEY
Content-Type: application/json
El identificador del modelo se pasa en el cuerpo de la petición mediante "model": "mirelo-sfx-2.0". No hace falta instalar un SDK aparte: si tu cliente HTTP puede acceder a la URL base de HiAPI, puede llamar al modelo.
Un consejo práctico: guarda la URL base en una variable de configuración en lugar de codificarla directamente en cada archivo. Cuando pases de un script local a un servicio de preproducción o producción, querrás cambiarla en un solo sitio.
Análisis paso a paso de la petición curl
La petición de generación es una petición HTTP POST autenticada enviada al endpoint de creación de tareas de HiAPI. Esta es la llamada completa:
curl -sS -X POST "$HIAPI_BASE_URL/v1/tasks" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "mirelo-sfx-2.0",
"input": {
"prompt": "heavy wooden door creaking open slowly, old house ambience"
}
}'
Desglose por partes:
-X POST: la creación de tareas es una operación de escritura. UsarGETen esta ruta no iniciará ninguna tarea.- URL: el endpoint acepta nuevas tareas de generación. La URL base se guarda en
HIAPI_BASE_URL, de modo que el mismo comando funciona en cualquier entorno. Authorization: el token bearer identifica tu cuenta y es la base de la facturación. Una cabecera ausente o mal formada es la causa más habitual de un401.Content-Type: application/json: el cuerpo es JSON; sin esta cabecera, el servidor rechazará o analizará mal la carga útil.model: selecciona mirelo-sfx-2.0. Como HiAPI enruta según este campo, puedes cambiar de modelo sin modificar la URL.input.prompt: la descripción textual del sonido. Las descripciones concretas y físicas (material, acción, entorno) producen mejores resultados que las abstractas.
Un envío correcto no devuelve audio. Devuelve un objeto de tarea con un identificador (normalmente el campo id) que usarás para consultar el estado. Captura ese ID de la respuesta; es la pista que te permitirá recuperar después el WAV.
Si quieres confirmar la estructura de la petición antes de integrarla en código, ejecuta este comando exacto en el terminal. Una vez que funcione, trasladarlo a Python es una tarea mecánica.
La misma llamada en Python
La versión en Python mantiene la misma URL, cabeceras y cuerpo; simplemente los representa como diccionarios y llamadas del cliente:
import os
import requests
BASE_URL = os.environ["HIAPI_BASE_URL"]
API_KEY = os.environ["HIAPI_API_KEY"]
def create_sfx_task(prompt: str) -> str:
response = requests.post(
f"{BASE_URL}/v1/tasks",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json={
"model": "mirelo-sfx-2.0",
"input": {"prompt": prompt},
},
timeout=30,
)
response.raise_for_status()
return response.json()["id"]
Diferencias respecto a la versión de shell:
- Acceso al entorno:
os.environsustituye a la expansión del shell, por lo que la clave nunca aparece en el código fuente. json=en lugar de-d:requestsserializa el diccionario por ti y establece el tipo de contenido. Puedes quitar la cabecera manual, aunque dejarla tampoco está mal.raise_for_status(): convierte las respuestas que no son 2xx en excepciones; aquí es donde debe ir el manejo de errores.timeout: el tiempo de espera del cliente evita que una conexión estancada bloquee tu proceso de trabajo. La creación de tareas es rápida; las esperas largas ocurren durante el sondeo.
El valor devuelto es el ID de la tarea. Guárdalo: es tu único identificador de esa generación. En este punto, las rutas de Python y curl convergen: ambas necesitan el paso de sondeo para que el audio exista.
Como el cuerpo de la petición es solo datos, puedes parametrizar el prompt e iterar sobre una lista de descripciones para generar efectos de sonido por lotes, creando una tarea por cada prompt y recopilando los ID.
Gestión de tareas asíncronas y sondeo de resultados
La generación de sonido lleva tiempo (segundos, no milisegundos), por lo que HiAPI la modela como una tarea. La llamada de creación devuelve un ID de inmediato; un segundo endpoint informa si la tarea sigue en ejecución, ha terminado o ha fallado.
El bucle típico es:
- Crear la tarea y capturar el ID.
- Sondear el endpoint de estado de la tarea con ese ID.
- Si el estado sigue siendo de procesamiento, esperar brevemente y volver a sondear.
- Cuando el estado indique éxito, leer la salida de la respuesta.
- Si el estado indica fallo, detenerse y lanzar un error.
En Python:
import time
def wait_for_task(task_id: str, timeout_s: int = 300) -> dict:
deadline = time.time() + timeout_s
while time.time() < deadline:
response = requests.get(
f"{BASE_URL}/v1/tasks/{task_id}",
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=30,
)
response.raise_for_status()
task = response.json()
status = task.get("status")
if status == "succeeded":
return task
if status == "failed":
raise RuntimeError(task.get("error", "task failed"))
time.sleep(2)
raise TimeoutError(f"task {task_id} did not finish in time")
Hay varios puntos que conviene destacar:
- Intervalo de sondeo. Dos segundos es un valor predeterminado razonable para efectos de sonido. Sondear en un bucle ajustado desperdicia cuota y puede activar límites de tasa, sin que los resultados lleguen antes.
- Fecha límite total. Pon siempre un límite al bucle. Una tarea atascada debe hacer fallar tu trabajo, no dejar el proceso de trabajo colgado para siempre.
- Valores de estado. Trata los valores de estado desconocidos como «todavía en proceso» en lugar de asumir éxito, y ramifica explícitamente en los estados de éxito y de fallo.
- Webhooks (si están disponibles). Si tu cuenta de HiAPI admite callbacks de finalización, úsalos preferentemente al sondeo en código de producción del lado del servidor; para scripts y prototipos, el sondeo sigue siendo la opción más sencilla.
Guarda el ID de la tarea junto con el prompt en tu propia base de datos, para poder reintentar, auditar o volver a obtener la salida más adelante sin necesidad de regenerarla.
Lectura de la respuesta WAV devuelta
Cuando la tarea informa de éxito, la respuesta contiene el audio generado. Según la versión del endpoint, la salida puede aparecer como una URL de archivo WAV o como datos de audio en línea; trata ambos casos como «bytes almacenables».
El objeto de tarea correcto lleva la salida en campos como output, normalmente junto con metadatos como el nombre del modelo, el prompt original y la información temporal. El audio en sí es un contenedor WAV estándar, lo que significa que puedes pasarlo a cualquier biblioteca de audio sin decodificadores personalizados.
Para persistir un resultado basado en URL:
result = wait_for_task(task_id)
audio_url = result["output"]["audio_url"]
wav_bytes = requests.get(audio_url, timeout=60).content
with open(f"{task_id}.wav", "wb") as f:
f.write(wav_bytes)
Si el audio llega como datos decodificados, decodifícalo en base64 antes de escribirlo:
import base64
wav_bytes = base64.b64decode(result["output"]["audio_base64"])
with open(f"{task_id}.wav", "wb") as f:
f.write(wav_bytes)
Una vez que tengas los bytes:
- Verifica la cabecera. Los archivos WAV empiezan con el número mágico
RIFF. Comprobar los cuatro primeros bytes permite detectar descargas truncadas antes de que lleguen al almacenamiento. - Almacenamiento persistente. Escribe en el almacenamiento de objetos y guarda la clave junto con el ID de la tarea en la base de datos. Trata el audio generado como un artefacto almacenable en caché, no como una respuesta temporal.
- Reproducción o procesamiento. Las herramientas estándar (
wave,soundfileo cualquier reproductor de audio) pueden abrir el archivo directamente. Después puedes recortar el silencio, normalizar el volumen o convertirlo a otro formato para la entrega.
Como el archivo es un WAV normal, conectarlo a un endpoint web o al pipeline de assets de un motor de juegos no requiere ningún tratamiento especial.
Puntos de fallo habituales y cómo solucionarlos
La mayoría de los problemas de integración se agrupan en unas pocas categorías predecibles.
Errores de autenticación (401 / 403)
Un 401 casi siempre significa que la cabecera Authorization falta, está mal formada o se construyó a partir de una variable de entorno vacía. Comprueba que HIAPI_API_KEY esté exportada en el shell donde se ejecuta el proceso (no solo en el editor) y que la cabecera se lea como Bearer <key>, con un único espacio en medio. Un 403 suele significar que la clave es válida pero no tiene acceso a ese modelo; revisa los permisos de modelo de tu cuenta.
Cargas útiles mal formadas (400 / 422)
La causa más frecuente es que el cuerpo no sea JSON válido: las comillas desemparejadas en un comando curl son el ejemplo típico. Valídalo con un comprobador de JSON antes de enviarlo. La segunda causa más frecuente es que falte el campo model o que el prompt esté anidado en el nivel incorrecto; el modelo espera input.prompt, no un prompt de nivel superior. Por último, comprueba que el prompt no esté vacío y que su longitud esté dentro de los límites indicados en la documentación del modelo.
Sondeo demasiado frecuente
Un bucle while ajustado sin espera genera una gran cantidad de peticiones de estado que pueden activar límites de tasa y ralentizar la propia tarea que estás esperando. Usa un intervalo fijo de uno o dos segundos, añade jitter cuando ejecutes varios trabajos en paralelo y aplica siempre un tiempo máximo de espera.
Confundir la creación con la finalización
La respuesta de creación parece un éxito y devuelve 200, pero no contiene audio. Si tu código lee el campo output inmediatamente, fallará o escribirá un archivo vacío. Antes de tocar el resultado, pasa siempre por el endpoint de estado.
Tiempos de espera silenciosos y reintentos
Reintentar tras un tiempo de espera de red durante la creación de la tarea es seguro, pero reintentar la llamada de creación después de un tiempo de espera que en realidad ya tuvo éxito genera tareas duplicadas. Si el endpoint admite claves de idempotencia, úsalas; de lo contrario, enumera las tareas recientes para verificarlas antes de reintentar.
Casos límite de disco y almacenamiento
Al escribir los bytes del WAV, abre el archivo en modo binario ("wb"). El modo texto corrompe la cabecera. Si almacenas las salidas con el nombre del prompt, dos tareas con el mismo prompt se sobrescribirán entre sí: usa el ID de la tarea como clave del archivo.
Con estas protecciones, la integración de mirelo-sfx-2.0 es un pipeline corto: crear, sondear, persistir. Empieza con la llamada curl, pásala a Python y usa el ID de la tarea como tu fuente de verdad.
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