HiAPI
Blog

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

Nov 3, 2026
米色纸层与石墨色顶边、一块陶土色纸片层叠成阶梯状的封面图,呈现平静的地层节奏。

Qué hace la solicitud kandinsky-6.0-pro/text-to-video

kandinsky-6.0-pro/text-to-video convierte un prompt de texto en un clip de video corto. Tú envías el prompt y unos pocos parámetros de generación, y el modelo produce un archivo de video que puedes guardar y reproducir. Eso es todo el producto: entra un prompt, sale un clip.

El detalle arquitectónico clave es el siguiente: no es una llamada síncrona. No obtendrás el video directamente en el cuerpo de la respuesta de la primera solicitud. En su lugar, se crea un trabajo, la API devuelve el identificador de ese trabajo y el modelo trabaja en segundo plano. Tu código debe consultar el estado del trabajo hasta que reporte que está completo, momento en el que el resultado estará disponible para descargar.

Este patrón tiene varias consecuencias que deberías tener en cuenta desde el principio:

  • El cliente debe sondear. Un único POST no puede devolver el video terminado, por lo que cualquier integración necesita un bucle de sondeo de estado o una nueva verificación similar a un webhook.
  • La solicitud debe ser idempotente en tu lado. Si el script se cae después de enviar, no querrás crear en silencio un segundo trabajo. Captura el identificador del trabajo y persístelo.
  • La latencia es variable. La generación de video es más lenta que las llamadas de imagen o texto, así que esperar es normal, no un defecto.

El resto de este tutorial sigue ese ciclo de vida en orden: preparación, envío con curl, sondeo, descarga y luego reconstruir el mismo flujo en Python. Trata el código como un esqueleto funcional: las rutas de los endpoints y los nombres de los campos siempre deben confirmarse con la referencia de API del modelo, porque estos detalles cambian a medida que la plataforma evoluciona.

Antes de enviar la primera solicitud

Hay cuatro cosas que debes tener listas antes de la primera llamada.

1. Cuenta de HiAPI y clave de API

Autentícate con una clave de API emitida desde tu cuenta de HiAPI. Mantén la clave fuera del control de versiones y del historial del shell siempre que sea posible. La práctica habitual es exportarla como variable de entorno y hacer que el código la lea de ahí:

export HIAPI_API_KEY="your-key-here"

Cada solicitud a continuación asume que la clave se envía como token bearer en la cabecera Authorization. Si aún no has creado una clave, hazlo primero en el panel de tu cuenta.

2. Cliente HTTP

Con curl basta para verificar que la solicitud funciona. Para cualquier operación que deba repetirse, usa Python 3 con la biblioteca requests: una sola dependencia, código legible y fácil de integrar más adelante en un programador o servicio:

python3 -m pip install requests

3. Dónde guardar la salida

Los archivos de video son mucho más grandes que las respuestas JSON. Decide de antemano si escribirás en un directorio local o transmitirás a un almacenamiento de objetos. Para este tutorial, un directorio local ./output es suficiente:

mkdir -p output

4. Conoce tu prompt

Escribe el prompt antes de escribir el código. Un prompt concreto y descriptivo —sujeto, acción, comportamiento de cámara, estilo visual— te da una línea base con la que comparar cuando algo falle. Cuando el prompt es una constante con nombre en el script, en lugar de una cadena escrita en el intérprete de comandos, es mucho más fácil cambiar una sola variable a la vez.

Esa es la lista completa de requisitos previos. No hay SDK que instalar ni pasos de compilación; la plataforma se accede por HTTPS estándar.

La solicitud curl que funciona

El primer objetivo es obtener un comando que devuelva un trabajo (no un video). Hazlo funcionar antes de añadir código.

La solicitud consta de tres partes: el endpoint del modelo, la cabecera Authorization y un cuerpo JSON con el prompt y los parámetros de generación.

curl -X POST "https://api.hiapi.ai/v1/models/kandinsky-6.0-pro/text-to-video/jobs" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A slow drone shot over a misty pine forest at sunrise, soft golden light, cinematic",
    "duration_seconds": 5,
    "aspect_ratio": "16:9"
  }'

Lee la respuesta con atención. Busca:

  • Un identificador de trabajo: el handle que usarás para sondear. Puede llamarse id, job_id o similar.
  • Un campo de estado inicial, normalmente algo como queued o processing.
  • Cualquier parámetro devuelto que confirme que el cuerpo se analizó como esperabas.

Una respuesta que devuelve un identificador de trabajo y un estado no erróneo significa que la solicitud fue aceptada. Si esa respuesta contuviera directamente el archivo de video, significaría que está ocurriendo algo distinto a lo descrito en este artículo.

Confirma el contrato antes de construir sobre él

Los nombres de campo anteriores —la ruta del endpoint, duration_seconds, aspect_ratio, la clave del identificador— son los detalles más propensos a cambiar según el modelo y el tiempo. La fuente fiable de verdad es la página de referencia de API del modelo. Compruébalo una vez, copia los nombres exactos como constantes en tu script y estructura el código para que un cambio de nombre sea una edición de una línea, no una búsqueda en todo el código base.

Si recibes un 4xx, el cuerpo del error ofrece más información que el código de estado. 401 significa clave incorrecta o ausente; los errores de validación del tipo 422 suelen señalar el campo problemático.

Enviar y sondear el trabajo hasta completarlo

Una vez que la llamada de envío funciona, el ciclo de vida es: enviar, capturar el identificador, sondear, detenerse en el estado terminal.

Envío

El POST de la sección anterior crea el trabajo. Independientemente de lo que haga el código a continuación, debe almacenar el identificador devuelto en un lugar persistente: una variable en el script, una fila en una tabla de trabajos, un mensaje en una cola. Si el proceso muere después de recibir la respuesta del envío pero antes de persistir el identificador, perderás la capacidad de sondear ese trabajo.

Sondeo

Sondear consiste en hacer una solicitud GET al recurso del trabajo con el identificador que capturaste:

curl "https://api.hiapi.ai/v1/models/kandinsky-6.0-pro/text-to-video/jobs/$JOB_ID" \
  -H "Authorization: Bearer $HIAPI_API_KEY"

La respuesta informa del estado actual del trabajo. En la práctica verás unos pocos estados: en cola o pendiente, en proceso, completado y alguna forma de fallo o cancelación. Diseña el bucle en torno a esas categorías y no a las cadenas exactas: asigna lo que devuelva la API a running, done, failed en tu código, de modo que un cambio de nombre no rompa tu lógica de reintentos.

Decidir cuánto esperar

Importan dos números: el intervalo de sondeo y el tiempo de espera total.

  • Intervalo. Sondea cada pocos segundos, no en un bucle ajustado. Un bucle ajustado no aporta nada y puede activar los límites de tasa. Para trabajos de video, un intervalo de varios segundos entre solicitudes es razonable.
  • Tiempo de espera. Pon un límite. La generación de video tarda, pero "esperar para siempre" no es una respuesta aceptable para un script de producción. Elige un presupuesto máximo de tiempo realista y trata superarlo como un fallo que puedes registrar y reintentar de forma consciente.

Un patrón que resiste el uso real

En producción, el paso de sondeo suele desacoplarse del paso de envío, en lugar de residir en un proceso que duerme. Un worker envía, registra el trabajo y termina; una re-verificación periódica recoge los trabajos pendientes y los sondea. Esto es más robusto frente a reinicios y más fácil de observar. Para este tutorial, un bucle simple en un solo proceso es suficiente: solo organízalo como funciones en lugar de código en línea, y moverlo más adelante a un worker programado periódicamente será sencillo.

Descargar el clip generado

Un trabajo completado aún no es un archivo en tu disco. La respuesta de estado del trabajo completado apunta a la salida: normalmente una URL, a veces un objeto anidado que contiene la URL. Lee ese campo y úsalo como entrada para el paso de descarga.

curl -L "$OUTPUT_URL" -o output/clip.mp4

Comprueba estos puntos para confirmar que la descarga realmente funcionó:

  • Sigue las redirecciones. Las URL de salida suelen servirse mediante redirecciones; curl lo maneja con -L y Python con allow_redirects=True.
  • Verifica el tipo de contenido. Un trabajo completado debe producir una carga de video. Si lo que se guarda como clip.mp4 es JSON o una página de error HTML, el problema está en la descarga, no en la generación.
  • Comprueba el tamaño. Un archivo de cero bytes o sospechosamente pequeño indica un fallo de descarga. Si hay cabeceras de respuesta, compara el número de bytes con el tamaño declarado en ellas.
  • Ten en cuenta la caducidad. Las URL de salida suelen tener límite de tiempo. Descarga en cuanto termine el trabajo y, si necesitas persistencia, copia el archivo a tu propio almacenamiento en lugar de guardar la URL como referencia permanente.

Para cualquier uso más allá del tutorial, transmite la descarga al destino en lugar de cargar el archivo completo en memoria, y escribe primero en un nombre de archivo temporal para luego renombrarlo: así una descarga incompleta nunca parecerá un archivo completo al código posterior.

La misma solicitud en Python

Lo siguiente reconstruye el flujo de curl como una función invocable: enviar, sondear, descargar. Los nombres que podrías necesitar ajustar están reunidos arriba como constantes.

import os
import time
import requests

API_BASE = "https://api.hiapi.ai/v1"
MODEL_PATH = "/models/kandinsky-6.0-pro/text-to-video"
API_KEY = os.environ["HIAPI_API_KEY"]

HEADERS = {"Authorization": f"Bearer {API_KEY}"}

RUNNING_STATES = {"queued", "pending", "processing", "running"}
DONE_STATES = {"completed", "succeeded", "done"}
FAILED_STATES = {"failed", "cancelled", "error"}


def generate_clip(prompt, out_path, timeout_s=600, interval_s=5):
    # 1. submit
    resp = requests.post(
        API_BASE + MODEL_PATH + "/jobs",
        headers={**HEADERS, "Content-Type": "application/json"},
        json={"prompt": prompt, "duration_seconds": 5, "aspect_ratio": "16:9"},
        timeout=30,
    )
    resp.raise_for_status()
    job = resp.json()
    job_id = job["id"]
    print(f"submitted job {job_id}")

    # 2. poll
    deadline = time.monotonic() + timeout_s
    while time.monotonic() < deadline:
        status_resp = requests.get(
            f"{API_BASE}{MODEL_PATH}/jobs/{job_id}",
            headers=HEADERS,
            timeout=30,
        )
        status_resp.raise_for_status()
        data = status_resp.json()
        state = str(data.get("status", "")).lower()

        if state in DONE_STATES:
            break
        if state in FAILED_STATES:
            raise RuntimeError(f"job {job_id} ended in state {state}: {data}")
        time.sleep(interval_s)
    else:
        raise TimeoutError(f"job {job_id} did not finish within {timeout_s}s")

    # 3. download
    url = data["output"]["url"] if isinstance(data.get("output"), dict) else data["output"]
    with requests.get(url, stream=True, allow_redirects=True, timeout=60) as r:
        r.raise_for_status()
        tmp = out_path + ".part"
        with open(tmp, "wb") as f:
            for chunk in r.iter_content(chunk_size=1 << 16):
                f.write(chunk)
        os.replace(tmp, out_path)
    print(f"saved {out_path}")
    return job_id


if __name__ == "__main__":
    generate_clip(
        "A slow drone shot over a misty pine forest at sunrise, soft golden light, cinematic",
        "output/clip.mp4",
    )

Por qué está escrito así

  • Conjuntos de estados en lugar de coincidencia exacta. Asignar los estados devueltos a running/done/failed significa que un nuevo estado intermedio no romperá el bucle.
  • Fecha límite monótona. time.monotonic() no se ve afectado por ajustes del reloj, así que el tiempo de espera es preciso.
  • Escritura atómica. Escribir en .part y luego renombrar significa que una descarga interrumpida nunca deja un archivo truncado que parezca válido.
  • Devuelve el ID del trabajo. El llamador puede registrarlo, almacenarlo y volver a sondearlo si es necesario: es el primer paso para sacar el sondeo de este proceso.

Ajusta la ruta del endpoint, los nombres de campo de la solicitud y las claves de respuesta para que coincidan con la referencia de API del modelo. Todo lo demás —el bucle, los tiempos de espera, la descarga— es genérico.

Estados de error y lista de comprobación para depurar

Cuando algo falla, aísla primero la etapa antes de cambiar nada. Cada etapa tiene un perfil de fallo distinto.

Fallo de autenticación

Un 401 o 403 al enviar significa que la clave falta, es incorrecta o no se envió. Comprueba que la variable de entorno está realmente definida en el shell o proceso que ejecuta el código: una clave exportada en un terminal es invisible para una tarea cron. Imprime los primeros caracteres de la clave para confirmar que se resolvió; nunca imprimas la clave completa.

Formato de solicitud incorrecto

Un error del tipo 400 o 422 al enviar significa que el cuerpo no superó la validación. El cuerpo de la respuesta normalmente señala el campo. Causas comunes: un parámetro mal escrito, una duración fuera del rango admitido o un prompt vacío. Compara tu JSON campo a campo con la referencia de API; una sola clave renombrada es la causa más frecuente.

El trabajo se queda en estado de ejecución

Si el sondeo nunca llega a un estado terminal, confirma tres cosas: el identificador que estás sondeando es el que enviaste; el intervalo de sondeo no es tan frecuente como para activar límites de tasa; el tiempo de espera es suficientemente largo para el modelo. Registra la respuesta de estado en bruto en cada sondeo para ver si el estado avanza o se congela.

El trabajo se completa pero la descarga falla

Que el trabajo se complete pero la descarga falle es un problema de manejo de archivos, no de generación. Comprueba si se siguen las redirecciones, si la URL no ha caducado y si el tipo de contenido es video y no JSON. Prueba la URL por separado con curl -L para aislarla del script.

El mismo prompt falla repetidamente

Si un prompt falla de forma persistente mientras otros funcionan, sospecha primero de la política de contenido o de la longitud del prompt, no de la infraestructura. Cambia una variable —acorta el prompt, simplifica la descripción de la escena— y vuelve a intentarlo.

Una regla general

Registra cuatro cosas por trabajo: el identificador del trabajo, el estado final, el tiempo real transcurrido y el estado HTTP de la descarga. Estos cuatro valores convierten la mayoría de los informes de "no funcionó" en una etapa concreta y corregible en menos de un minuto.

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