Tutorial
Llamar a la API de texto a vídeo de HappyHorse 1.1 a través de HiAPI: un tutorial funcional con curl + Python
- Modelo
- happyhorse-1.1
HappyHorse 1.1 es el modelo de texto a vídeo de Alibaba: admite clips de vídeo en 720p / 1080p, con una duración de 3 a 15 segundos, y genera audio nativo en una sola llamada (sin necesidad de un paso de música independiente). HiAPI expone este modelo a través del mismo endpoint asíncrono unificado que todos los demás modelos generativos, así que si ya has llamado a modelos de imagen en /v1/tasks, lo único que cambia es el id del modelo y algunos campos de input.
Esta página ofrece el mínimo necesario para entregar una integración funcional: el esquema exacto, curl que puedes copiar directamente, un cliente de sondeo en Python y el patrón de callback para producción. También señala dos cosas poco obvias que el modelo no acepta (un interruptor audio y un seed), para que no desperdicies una solicitud por un 400.
Requisitos previos. Obtén una clave desde la consola de HiAPI y expórtala como
HIAPI_API_KEY. Cada solicitud se autentica medianteAuthorization: Bearer sk-…; si necesitas un repaso, consulta Authentication.
Endpoint y estructura de la solicitud
Todo pasa por el mismo endpoint:
POST https://api.hiapi.ai/v1/tasks
Authorization: Bearer sk-<your-key>
Content-Type: application/json
El cuerpo de la solicitud tiene tres claves de nivel superior:
model—happyhorse-1.1/text-to-video(el id del modelo literal — conserva la barra).input— campos específicos del modelo. Para HappyHorse 1.1 T2V:prompt(cadena, obligatorio) — describe el clip de vídeo.resolution(720p|1080p, predeterminado1080p).aspect_ratio(16:9|9:16|3:4|4:3|4:5|5:4|1:1|9:21|21:9, predeterminado16:9).duration(entero, 3–15, predeterminado5). El coste aumenta con los segundos.
callback(opcional, objeto) — endpoint HTTPS encallback.url+callback.when: "final". HiAPI enviará exactamente un POST con el resultado final a esa dirección por cada tarea.
Dos cosas que parecen deberían funcionar pero en realidad no:
- ❌ No existe el campo
audio. El audio se genera de forma nativa junto con el vídeo; no hay interruptor. Enviar"audio": truedevuelveadditional properties 'audio' not allowed. - ❌ No existe el campo
seed. También devuelve 400. Si necesitas determinismo por lote ahora mismo, genera varias versiones y elige entre ellas — no hay ninguna palanca de seed que ajustar.
Un cuerpo de solicitud mínimo válido:
{
"model": "happyhorse-1.1/text-to-video",
"input": {
"prompt": "A golden retriever running on a beach, slow motion, gentle waves, warm sunset tones",
"resolution": "1080p",
"aspect_ratio": "16:9",
"duration": 5
}
}
Ejemplo mínimo funcional: curl
Crear la tarea — la respuesta se devuelve de inmediato y solo contiene un taskId:
curl -sS -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "happyhorse-1.1/text-to-video",
"input": {
"prompt": "A snow mountain lake in morning mist, slow camera push-in, warm cinematic light",
"resolution": "1080p",
"aspect_ratio": "16:9",
"duration": 5
}
}'
# => {"code":200,"data":{"taskId":"tk-hiapi-01KW3..."},"message":"success"}
Luego sondea hasta llegar a un estado terminal:
TASK_ID=tk-hiapi-01KW3...
curl -sS "https://api.hiapi.ai/v1/tasks/$TASK_ID" \
-H "Authorization: Bearer $HIAPI_API_KEY"
# while .data.status is "handling", sleep a few seconds and retry.
# On success:
# {
# "code": 200,
# "data": {
# "status": "success",
# "model": "happyhorse-1.1/text-to-video",
# "output": [
# {"type":"video","url":"https://temp.hiapi.ai/.../...-0.mp4","expireAt":1783130616}
# ],
# ...
# }
# }
La URL del mp4 es temporal (expireAt es una marca de tiempo Unix de aproximadamente 7 días después). Descarga y guarda de forma persistente en cuanto la tarea tenga éxito — no enlaces en caliente. Si prefieres que HiAPI gestione el almacenamiento a largo plazo, consulta la documentación de Output Storage para saber cómo promover las salidas de almacenamiento temporal a persistente.
Python: un cliente pequeño con forma de producción
Un cliente real necesita tres cosas: create_task que devuelva el id, wait_task que sondee con una fecha límite y un paso de descarga. Este esqueleto incluye las tres y se acerca al punto de partida de la página del SDK de Python de HiAPI — mantenlo pequeño y amplíalo a partir de ahí.
# pip install requests
import os, time, json, requests
API_BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}"}
def create_task(prompt: str, *, resolution="1080p", aspect_ratio="16:9", duration=5) -> str:
body = {
"model": "happyhorse-1.1/text-to-video",
"input": {
"prompt": prompt,
"resolution": resolution,
"aspect_ratio": aspect_ratio,
"duration": duration,
},
}
r = requests.post(API_BASE, headers={**HEADERS, "Content-Type": "application/json"},
data=json.dumps(body), timeout=60)
r.raise_for_status()
data = r.json()
if data.get("code") != 200:
raise RuntimeError(f"create failed: {data}")
return data["data"]["taskId"]
def wait_task(task_id: str, *, timeout_s: int = 600, poll: int = 5) -> dict:
deadline = time.time() + timeout_s
while time.time() < deadline:
r = requests.get(f"{API_BASE}/{task_id}", headers=HEADERS, timeout=30)
r.raise_for_status()
task = r.json().get("data") or {}
status = task.get("status")
if status == "success":
return task
if status == "fail":
raise RuntimeError(f"task {task_id} failed: {task.get('error')}")
time.sleep(poll)
raise TimeoutError(f"task {task_id} did not finish within {timeout_s}s")
def download(url: str, path: str) -> None:
with requests.get(url, stream=True, timeout=120) as r:
r.raise_for_status()
with open(path, "wb") as f:
for chunk in r.iter_content(1 << 14):
f.write(chunk)
if __name__ == "__main__":
task_id = create_task(
"A neon street at night after rain, reflections on the ground, "
"cyberpunk mood, slow pan",
resolution="720p", aspect_ratio="9:16", duration=5,
)
task = wait_task(task_id)
url = task["output"][0]["url"]
download(url, "out.mp4")
print("saved out.mp4")
Algunas consideraciones para producción:
- Campo de estado. Trata cualquier valor distinto de
successofailcomo en curso (la plataforma usa actualmentehandling). raise_for_statusno es suficiente. Para algunos errores de validación, HiAPI devuelve HTTP 200 perocodeno es 200 — comprueba siempre tambiéndata["code"]. Para integraciones nuevas, lo más común es401 permission_denied, lo que significa que el token bearer es incorrecto o falta — vuelve a exportarHIAPI_API_KEYy confírmalo en la consola.
Producción: preferir callbacks en lugar de sondeo
Para cualquier escenario más allá de un inicio rápido, proporciona a HiAPI un webhook para que te llame cuando la tarea se complete:
{
"model": "happyhorse-1.1/text-to-video",
"input": {
"prompt": "A snow mountain lake in morning mist, slow camera push-in, warm cinematic light",
"resolution": "1080p",
"aspect_ratio": "16:9",
"duration": 5
},
"callback": {
"url": "https://your-domain.com/hiapi/callback",
"when": "final"
}
}
Asegúrate de que tu manejador de callbacks haga lo siguiente:
- Deduplicar por
taskId. Tantosuccesscomofailson estados terminales — tu servicio debe tratar recibir el mismotaskIddos veces como una no-operación (escritura idempotente con clavetaskId). - Devolver 2xx rápidamente. Pon el trabajo pesado (descargar el mp4, persistir, notificar al usuario) en una cola. El manejador del webhook debe confirmar en pocos segundos.
- Mantener
GET /v1/tasks/:idcomo respaldo. Si el webhook se pierde (despliegue, fluctuaciones de red), una tarea programada de reconciliación que obtenga por id las tareas atascadas y aplique el mismo manejador es la red de seguridad más sencilla.
Si tienes que elegir un camino: el sondeo es adecuado para scripts puntuales y depuración local, mientras que cualquier lugar con tráfico real debería usar callbacks.
Elegir los parámetros correctos (resolution × aspect_ratio × duration)
| Necesidad | resolution | aspect_ratio | duration |
|---|---|---|---|
| Clip vertical corto para redes sociales, coste más bajo | 720p |
9:16 |
5 |
| Vista previa cuadrada / bucle de miniatura | 720p |
1:1 |
3 |
| Toma narrativa horizontal / anuncio | 1080p |
16:9 |
5–8 |
| Clip de imagen principal en pantalla ancha | 1080p |
21:9 |
8–12 |
El coste aumenta con la resolución y la duración — consulta los precios exactos por segundo en Precios de HiAPI. Cuando no estés seguro de los valores correctos, no los rellenes: resolution toma 1080p por defecto, aspect_ratio toma 16:9 por defecto y duration toma 5 por defecto.
Preguntas frecuentes
¿El texto a vídeo de HappyHorse 1.1 tiene un parámetro seed?
No. La API rechaza seed con additional properties 'seed' not allowed. Si necesitas varias opciones entre las que elegir, envía varias tareas con el mismo prompt — ejecuciones distintas producirán variaciones de forma natural.
¿Cómo se activa o desactiva el audio?
No puedes hacerlo — HappyHorse 1.1 genera la pista de audio de forma nativa en la misma llamada. No hay ningún interruptor audio en el esquema; enviar uno devuelve 400. Si necesitas un clip sin sonido, elimina el audio en posproducción.
¿Cuáles son las duraciones válidas?
Un entero de 3 a 15 (segundos). Cualquier valor fuera de ese rango devuelve duration: minimum: got 0, want 3 o duration: maximum: got 20, want 15. Los decimales también se rechazan (el tipo del campo es entero).
¿Qué relaciones de aspecto admite?
Nueve: 16:9, 9:16, 3:4, 4:3, 4:5, 5:4, 1:1, 9:21, 21:9. El valor predeterminado es 16:9.
¿Cuánto tiempo sigue siendo válida output[].url?
Alrededor de una semana — la respuesta incluye una marca de tiempo Unix expireAt. Descarga el mp4 de inmediato y vuelve a alojarlo (S3, R2, tu CDN), o promuévelo a almacenamiento persistente mediante la API de Output Storage.
¿Y el texto a vídeo desde imagen?
HappyHorse 1.1 tiene una variante I2V en el mismo endpoint — consulta HappyHorse 1.1 I2V. La misma autenticación, el mismo ciclo de vida asíncrono, un esquema de input distinto.
¿Dónde está la referencia completa de la API asíncrona? Consulta Create Task para el sobre de la solicitud, Get Task Detail para el endpoint de sondeo y la página del modelo HappyHorse 1.1 T2V para el esquema de entrada canónico. Si empiezas desde cero, Quickstart te guía de principio a fin en tu primera llamada.
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