Tutorial
Cómo usar la API de texto a video de grok-imagine-1.5-lite (curl + Python)
Si quieres generar un video corto con sonido a partir de una sola frase, grok-imagine-1.5-lite/text-to-video es la opción más barata de hiapi que llega a 1080P. Recibe un prompt y devuelve un MP4 de 1 a 15 segundos con el audio ya mezclado, y funciona sobre la misma API de tareas unificada que el resto de los modelos de la plataforma. Esta página ofrece peticiones listas para copiar y pegar, el esquema exacto (verificado contra el endpoint en vivo, no copiado de la especificación), cómo se ve una respuesta real y los problemas que encontré durante las pruebas.
Todo lo siguiente se verificó contra la API en vivo el 2026-10-21. Los precios son los que medí; si cambian, consulta la página de precios.
1. Qué vas a construir y qué necesitas preparar
Objetivo: enviar un prompt de texto y recibir un clip MP4 descargable con audio.
Solo necesitas una cosa: una clave de API de hiapi. Crea una en la consola y guárdala en el servidor; tiene la forma sk-... y se envía en la cabecera Authorization: Bearer. No hay ninguna ruta sin clave; todas las peticiones siguientes deben autenticarse.
El modelo es asíncrono. No obtienes el video directamente en la respuesta del POST. Primero creas una tarea, obtienes un taskId y luego sondeas (o usas un callback) hasta que la tarea termina y devuelve la URL de salida.
2. Ejemplo mínimo funcional
Dos pasos: crear la tarea y luego sondear el resultado.
Crear la tarea (curl)
curl -s -X POST "https://api.hiapi.ai/v1/tasks" \
-H "Authorization: Bearer sk-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "grok-imagine-1.5-lite/text-to-video",
"input": {
"prompt": "Al amanecer, un zorro rojo cruza la nieve recién caída, su aliento se convierte en vaho, luz suave de la mañana, viento ambiental tenue. Estilo cinematográfico, colores naturales. Sin texto.",
"duration": 5,
"resolution": "720p",
"aspect_ratio": "16:9"
}
}'
Fíjate en la estructura: model está en el nivel superior y todo lo demás va anidado dentro de input. Si envías los campos aplanados (sin el envoltorio input), la API rechaza todo el cuerpo con invalid input: must be a JSON object; este es el error más común.
Una creación correcta devuelve inmediatamente un id de tarea:
{ "code": 200, "data": { "taskId": "tk-hiapi-01M5E3QKSB2TAJRDHR5Y8EQNEB" }, "message": "success" }
Sondear el resultado (Python)
import time, requests
BASE = "https://api.hiapi.ai/v1/tasks"
HEAD = {"Authorization": "Bearer sk-YOUR_KEY", "Content-Type": "application/json"}
def generate(prompt, duration=5, resolution="720p", aspect_ratio="16:9"):
r = requests.post(BASE, headers=HEAD, json={
"model": "grok-imagine-1.5-lite/text-to-video",
"input": {
"prompt": prompt,
"duration": duration, # integer, 1–15
"resolution": resolution, # "480p" | "720p" | "1080p"
"aspect_ratio": aspect_ratio, # see schema below
},
})
r.raise_for_status()
task_id = r.json()["data"]["taskId"]
# Poll the SAVED task_id. A single transient network error is not a failure —
# keep polling the same id rather than re-creating (re-creating bills again).
deadline = time.time() + 300
while time.time() < deadline:
try:
d = requests.get(f"{BASE}/{task_id}", headers=HEAD, timeout=30).json()
except requests.RequestException:
time.sleep(5); continue
task = d.get("data") or {}
status = task.get("status")
if status == "success":
return task["output"][0]["url"]
if status == "fail":
raise RuntimeError(task.get("error"))
time.sleep(5)
raise TimeoutError(task_id)
print(generate("Al amanecer, un zorro rojo cruza la nieve recién caída, viento ambiental tenue. Estilo cinematográfico."))
Esquema (verificado en vivo)
Los campos van dentro de input. El esquema es cerrado: cualquier clave que no reconozca devuelve 400, así que no envíes seed, negative_prompt ni motion_mode (aquí no existen; todos los encuadres y direcciones de movimiento se expresan mediante la redacción del prompt).
| Campo | Tipo | ¿Obligatorio? | Valores aceptables |
|---|---|---|---|
prompt |
string | Sí | Texto libre |
duration |
integer | Sí | 1–15 (segundos enteros; 5.5 se rechaza) |
resolution |
string | — | 480p, 720p, 1080p |
aspect_ratio |
string | — | 16:9, 4:3, 3:2, 1:1, 2:3, 3:4, 9:16 |
Este modelo no tiene relación de aspecto auto (su modelo hermano de imagen a video sí la tiene; este endpoint de texto a video no). Especifica la relación explícitamente o recibirás la que el modelo use por defecto.
A continuación se muestra una respuesta real de una tarea completada:
{
"code": 200,
"data": {
"taskId": "tk-hiapi-01M5E3QKSB2TAJRDHR5Y8EQNEB",
"model": "grok-imagine-1.5-lite/text-to-video",
"status": "success",
"storage": "temp",
"output": [
{ "type": "video", "url": "https://temp.hiapi.ai/.../...-0.mp4", "expireAt": 1793153637 }
]
},
"message": "success"
}
Este es un clip generado por el modelo (una salida de referencia que hiapi ofrece para grok-imagine-1.5-lite/text-to-video, generada a partir del prompt de ejemplo de su documentación: "Al amanecer, un globo aerostático de cristal flota sobre terrazas de cultivo"):
3. Pasar a producción
Usa callbacks en lugar de sondeo. El sondeo está bien para scripts; para un servidor, añade callback para no tener que mantener la petición abierta. Cuando la tarea alcanza un estado terminal, la plataforma envía por POST los detalles de la tarea a tu URL:
{
"model": "grok-imagine-1.5-lite/text-to-video",
"input": { "prompt": "...", "duration": 5, "resolution": "720p", "aspect_ratio": "16:9" },
"callback": { "url": "https://your.app/hooks/hiapi", "when": "final" }
}
En este tipo de tarea, when solo acepta "final". Deduplica por taskId en tu handler: los callbacks pueden reintentarse, así que trata el handler como idempotente.
Las URL de salida caducan. Fíjate en storage: "temp" y en la marca de tiempo unix expireAt: las salidas temporales se alojan en temp.hiapi.ai durante unos 7 días y después devuelven 404. No guardes enlaces directos. Descarga los bytes en el momento en que la tarea tenga éxito o llama al endpoint de promoción de almacenamiento para mover el artefacto a almacenamiento permanente antes de que caduque el TTL.
El costo se cobra por segundos de salida. La facturación depende únicamente de duration y de la resolución solicitada. En mis pruebas: 480P $0.029/s, 720P $0.043/s, 1080P $0.20/s. Así, un clip de 5 segundos en 720P cuesta unos $0.215, uno de 5 segundos en 1080P unos $1.00, y uno de 1 segundo en 480P unos $0.029. La tarifa de 1080P es aproximadamente 5 veces la de 720P; úsala solo cuando realmente necesites esa resolución. Consulta las cifras más recientes en la página de precios.
Manejo de errores. Las peticiones rechazadas devuelven HTTP 400 con un mensaje preciso que puedes registrar y usar para actuar. La validación ocurre antes de crear ninguna tarea, así que un 400 aquí no genera costo. Respuestas reales que provoqué durante las pruebas:
invalid input: duration: maximum: got 999, want 15
invalid input: duration: minimum: got 0, want 1
invalid input: duration: got number, want integer
invalid input: resolution: value must be one of '480p', '720p', '1080p'
invalid input: aspect_ratio: value must be one of '16:9', '4:3', '3:2', '1:1', '2:3', '3:4', '9:16'
invalid input: prompt: missing required field "prompt"
invalid input: <root>: additional properties 'bogus_field' not allowed
Una tarea aceptada que falla después aparece como data.status: "fail" con un objeto data.error en el endpoint de detalles, no como un error HTTP; por lo tanto, revisa status y no te bases en el código de estado HTTP del sondeo.
4. Lo que observé realmente
Ejecuté una generación real para confirmar el flujo de extremo a extremo (no solo el esquema): duration: 1, resolution: "480p", aspect_ratio: "16:9".
- Realmente funciona y cobra: el POST devolvió un
taskIdy la tarea terminó con una URL de salida real. El renderizado del clip de 1 segundo tardó unos 51 segundos en el servidor; incluso los clips pequeños no son instantáneos, así que fija un plazo de sondeo generoso (yo puse 300 segundos). - La tarea pasa por estados intermedios. El campo
statuspasa porhandling→archiving→success. Solosuccessyfailson terminales; no consideresarchivingcomo completado. - 480P en 16:9 se renderiza como 848×480 H.264. Ejecuté
ffprobesobre el archivo descargado: un flujo de video H.264 (848×480) más un flujo de miniatura MJPEG incrustado. El archivo de 495 KB es un MP4 válido. - El audio siempre viene incluido. Aunque mi prompt solo mencionaba "viento ambiental tenue", la salida incluía una pista AAC; el modelo sintetiza audio acorde y lo mezcla en el mismo MP4. No hay una URL de audio separada ni un interruptor para desactivarlo; si necesitas un clip sin sonido, elimina la pista tú mismo (
ffmpeg -an).
Nota sobre el alcance: verifiqué el contrato de la API, los tres tipos de error anteriores y un renderizado en 480P. No hice pruebas comparativas de la calidad de salida en 720P/1080P ni de duraciones largas (15 segundos), así que no afirmo nada sobre su calidad; solo digo que el esquema los acepta y que se factura por segundo.
5. Comparación entre Lite y la API estándar de video de Grok Imagine
Elige bien el endpoint antes de construir:
grok-imagine-1.5-lite/text-to-video(esta página): 480P/720P/1080P, 1–15 segundos (por lo que puede generar clips de 1 o 2 segundos), precio$0.029–$0.20/s. Es el único endpoint de texto a video de generación 1.5 alojado por hiapi y el único nivel de Grok t2v que alcanza 1080P.grok-imagine/text-to-video(el nivel estándar más antiguo; consulta esta guía): más barato por segundo ($0.0114–$0.0214/s) y ofrece Motion Modes, pero solo llega a 720p y requiere una duración de 6–30 segundos; no puede generar clips de menos de 6 segundos.
Por lo tanto, aquí "lite" no es la opción más barata por segundo; es el nivel que desbloquea 1080P y clips muy cortos. Si vas a introducir una sola imagen estática en lugar de texto, usa el endpoint hermano grok-imagine-1.5-lite/image-to-video (mismo precio, entrada como image_urls).
6. Enlaces relacionados
- Página del modelo de texto a video grok-imagine-1.5-lite / zona de pruebas
- Crear tarea: referencia de la API
- Obtener detalles de la tarea: referencia de la API
- Precios
Preguntas frecuentes
¿Tengo que sondear o hay callbacks? Ambas opciones son válidas. Los scripts usan sondeo con GET /v1/tasks/{taskId}; los servidores añaden callback.url y establecen when en "final". Deduplica por taskId.
¿Por qué mi petición devuelve 400 con "must be a JSON object"? Tus campos no están dentro de input. El cuerpo de la petición debe ser {"model": "...", "input": { ... }}.
¿Se puede desactivar el audio? No al solicitarlo: cada salida incluye una pista AAC mezclada. Si necesitas silencio, elimínala aguas abajo con ffmpeg -an.
¿Cuánto dura la URL de salida? Es una URL temporal con expireAt (unos 7 días). Descárgala de inmediato o muévela a almacenamiento permanente; no la enlaces directamente.
¿Cuál es la petición válida más barata? 1 segundo en 480P cuesta unos $0.029. Antes de procesar en lote, es una buena forma de hacer una petición canaria para confirmar que tu clave tiene saldo.
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