HiAPI
Blog

Tutorial

Cómo usar grok-imagine-1.5/image-to-video mediante la API de hiapi: curl, Python y una solicitud lista para ejecutar

Jul 7, 2026
Cómo usar grok-imagine-1.5/image-to-video mediante la API de hiapi: curl, Python y una solicitud lista para ejecutar

Resumen conciso

  • Qué es: una guía reproducible que explica cómo animar una imagen estática en un vídeo corto con grok-imagine-1.5/image-to-video mediante la API de tareas unificada de hiapi.
  • Flujo: crea una tarea con POST /v1/tasks, consulta GET /v1/tasks/<taskId> (o registra un callback) y, antes de que expire, descarga el MP4 desde data.output[0].url.
  • Esquema de entrada (verificado contra la API en producción): acepta exactamente un elemento image_urls, prompt opcional, duration de 1 a 15 segundos, resolution en 480p/720p y aspect_ratio entre auto, 1:1, 16:9, 9:16, 3:2, 2:3. No se aceptan otros campos.

Qué vas a construir y qué necesitas preparar

Objetivo: enviar una imagen de origen más un prompt de movimiento y obtener un clip MP4 corto generado por Grok Imagine 1.5.

Requisitos previos:

  • Una clave de API de hiapi: créala en el panel de control. La clave tiene el formato sk-... y se coloca en la cabecera Authorization: Bearer.
  • Una URL de imagen de origen accesible públicamente (JPEG/PNG). La API obtiene la imagen en el servidor, por lo que los enlaces a localhost o los archivos que requieren autenticación no funcionan.
  • Cualquier cliente HTTP. Los ejemplos siguientes usan curl y requests de Python.

El id del modelo es la cadena simple grok-imagine-1.5/image-to-video, sin sufijo.

Ejemplo mínimo ejecutable: curl

Crear la tarea:

curl -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/image-to-video",
    "input": {
      "image_urls": ["https://example.com/product-shot.jpg"],
      "prompt": "slow cinematic push-in, soft studio light drifting across the subject",
      "duration": 6,
      "resolution": "720p",
      "aspect_ratio": "16:9"
    }
  }'

Un envío correcto devuelve 200 y un taskId:

{
  "code": 200,
  "data": { "taskId": "tk-hiapi-01KWVVSTX0TJ32AD45F6ZQ08W5", "status": "queued" },
  "message": "success"
}

Consulta hasta que la tarea llegue a un estado terminal (status pasa por queued → handling → success o fail):

curl "https://api.hiapi.ai/v1/tasks/tk-hiapi-01KWVVSTX0TJ32AD45F6ZQ08W5" \
  -H "Authorization: Bearer sk-YOUR_KEY"

Tarea completada (respuesta real, truncada):

{
  "code": 200,
  "data": {
    "taskId": "tk-hiapi-01KWVVSTX0TJ32AD45F6ZQ08W5",
    "model": "grok-imagine-1.5/image-to-video",
    "status": "success",
    "storage": "temp",
    "output": [
      {
        "type": "video",
        "url": "https://temp.hiapi.ai/.../01KWVVSTX0TJ32AD45F6ZQ08W5-0.mp4",
        "expireAt": 1783951451
      }
    ]
  },
  "message": "success"
}

⚠️ storage: "temp" y expireAt significan que la URL de descarga es temporal. Descarga el MP4 inmediatamente después de que la tarea tenga éxito y guárdalo en tu propia infraestructura: no uses hotlinking.

Ejemplo mínimo ejecutable: Python

Script completo: crear, consultar, descargar:

import time
import requests

API_KEY = "sk-YOUR_KEY"
BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

# 1. Create the task
resp = requests.post(BASE, headers=HEADERS, json={
    "model": "grok-imagine-1.5/image-to-video",
    "input": {
        "image_urls": ["https://example.com/product-shot.jpg"],
        "prompt": "slow cinematic push-in, soft studio light drifting across the subject",
        "duration": 6,
        "resolution": "720p",
        "aspect_ratio": "16:9",
    },
})
resp.raise_for_status()
task_id = resp.json()["data"]["taskId"]
print("task:", task_id)

# 2. Poll for the result (image-to-video usually lands well within a few minutes)
deadline = time.time() + 600
while time.time() < deadline:
    task = requests.get(f"{BASE}/{task_id}", headers=HEADERS).json()["data"]
    status = task["status"]
    if status == "success":
        break
    if status == "fail":
        raise RuntimeError(f"generation failed: {task.get('error')}")
    time.sleep(5)
else:
    raise TimeoutError(f"task {task_id} still not finished after 10 min")

# 3. Download immediately — the output URL expires
video_url = task["output"][0]["url"]
mp4 = requests.get(video_url, timeout=120)
mp4.raise_for_status()
with open("clip.mp4", "wb") as f:
    f.write(mp4.content)
print("saved clip.mp4,", len(mp4.content), "bytes")

Referencia de entrada (lo que el esquema acepta realmente)

Estas restricciones provienen directamente del validador en producción, no son suposiciones: enviar cualquier otra cosa devuelve 400 INVALID_REQUEST con un mensaje preciso:

Campo Tipo Regla
image_urls array de cadenas obligatorio, exactamente 1 URL (maxItems: 1)
prompt cadena opcional: describe el movimiento, el movimiento de cámara y el ánimo
duration entero 1–15 segundos
resolution cadena 480p o 720p
aspect_ratio cadena auto, 1:1, 16:9, 9:16, 3:2, 2:3

Notas:

  • Este modelo no tiene los campos seed, negative_prompt, fps, motion_strength ni camera_fixed. El esquema rechaza propiedades desconocidas (additional properties ... not allowed), así que controla el movimiento y el comportamiento de la cámara exclusivamente mediante prompt.
  • Cada tarea admite una sola imagen de referencia. Si pasas dos, devuelve image_urls: maxItems: got 2, want 1.
  • aspect_ratio: "auto" respeta la proporción de la propia imagen de origen; esto suele ser lo que se busca con imágenes de producto.
  • El modelo anterior grok-imagine/image-to-video acepta hasta 30 segundos por clip; la versión 1.5 tiene un límite de 15 segundos. Ambos tienen el mismo precio por segundo: $0.015 a 480p y $0.0282 a 720p.

Consideraciones para producción

Usa callbacks en lugar de sondeo. Para cualquier escenario que vaya más allá de un script, registra un webhook al crear la tarea y omite el bucle de sondeo:

{
  "model": "grok-imagine-1.5/image-to-video",
  "input": { "image_urls": ["https://example.com/shot.jpg"], "duration": 6 },
  "callback": { "url": "https://yourapp.com/hooks/hiapi", "when": "final" }
}

callback.url debe ser un endpoint http(s) público, y when solo admite "final": recibirás un único POST cuando la tarea llegue a success o fail. El sondeo sirve para CLI y tareas por lotes; los callbacks son mejores cuando necesitas generar muchos clips en lote y no quieres desplegar un ejército de sondeadores. Mantén un sondeo de respaldo (por ejemplo, revisar cada pocos minutos las tareas que no recibieron callback) para que un webhook perdido no deje la tarea varada.

Idempotencia. La creación de tareas no se deduplica en el servidor, por lo que un reintento simple tras un timeout de red puede provocar envíos duplicados y facturación duplicada. Persiste el taskId inmediatamente después de que regrese la llamada de creación y, en los reintentos, revisa primero tu propio almacenamiento; si fallas entre el envío y la persistencia, lista las tareas recientes (GET /v1/tasks) y haz coincidir por modelo + hora de creación antes de reenviar.

Gestión de errores. Los modos de fallo que realmente encontrarás:

  • 401 con {"error": {"code": "permission_denied", "type": "hiapi_error", ...}}: la clave es incorrecta o no tiene acceso a ese modelo. La respuesta incluye un request_id para soporte.
  • 400 con error_code: "INVALID_REQUEST": infracción del esquema; el message indicará el campo y la regla concretos (por ejemplo, duration: maximum: got 99, want 15). Corrige el cuerpo de la solicitud, no reintentes a ciegas.
  • 402 saldo insuficiente: los modelos de vídeo comprueban tu cuota al enviar. Recarga y vuelve a enviar.
  • La propia tarea en status: "fail": fallo del lado de la generación; revisa data.error y reintenta con backoff. Una causa habitual es que la imagen de origen no sea accesible.

Almacena la salida de inmediato. Vale la pena repetirlo: output[0].url está en almacenamiento temporal y lleva una marca de tiempo expireAt. En el momento en que veas success, transmite el MP4 a tu propio bucket. Si tu pipeline falla después del éxito y antes de la descarga, vuelve a obtener la tarea por id: la URL sigue siendo válida hasta expireAt, no para siempre.

Lecturas relacionadas

Preguntas frecuentes

¿Cuánto puede durar un vídeo de grok-imagine-1.5? De 1 a 15 segundos, configurado por el campo entero duration. Si pides más, devuelve 400 (duration: maximum: got X, want 15). Si necesitas hasta 30 segundos, usa el modelo anterior grok-imagine/image-to-video.

¿Qué resoluciones y proporciones de aspecto admite? resolution es 480p o 720p; aspect_ratio es auto, 1:1, 16:9, 9:16, 3:2 o 2:3. 9:16 a 720p es la combinación preferida para clips verticales estilo Shorts/Reels.

¿Puedo pasar varias imágenes de referencia? No: el image_urls de este modelo acepta exactamente una URL. Para flujos de trabajo con varias referencias, encadena tareas o compón primero las imágenes de referencia en una única imagen de entrada.

¿Hay seed o prompt negativo? No. El esquema de entrada rechaza directamente seed, negative_prompt, fps y campos similares. El estilo de movimiento, el movimiento de cámara y el ánimo se controlan íntegramente mediante la cadena prompt.

¿Cuánto cuesta? Se factura por los segundos de vídeo generado: $0.015/segundo a 480p y $0.0282/segundo a 720p. Un clip de 6 segundos cuesta $0.09 a 480p y $0.1692 a 720p. Si no envías duration, el valor predeterminado es 8 segundos. Para más ejemplos, consulta el desglose de precios de Grok Imagine 1.5.

¿Por qué mi solicitud devuelve 401 permission_denied? O bien la clave de API es incorrecta o está revocada, o bien no tiene acceso a ese modelo. Verifica la clave en el panel de control y asegúrate de enviar Authorization: Bearer sk-...: omitir el prefijo Bearer produce el mismo error.

¿Cómo sé que el vídeo está listo sin hacer sondeo? Al crear la tarea, adjunta "callback": {"url": "https://your-endpoint", "when": "final"}. Cuando la tarea llega a un estado terminal, hiapi envía un POST a tu endpoint. Como respaldo, consulta GET /v1/tasks/<taskId>.

¿Por qué la URL de mi vídeo deja de funcionar a los pocos días? La salida está en almacenamiento temporal: cada entrada de salida lleva una marca de tiempo expireAt. Descarga el archivo inmediatamente después de success y sírvelo desde tu propio almacenamiento.

Artículos relacionados

Ver todos los artículos →

Empieza a crear con artefactos de IA persistentes

Consigue tu API key y llama a modelos de imagen, vídeo y audio a través de una única API basada en tasks.

Leer la documentación de la API