HiAPI
Blog

Tutorial

API de imagen a video de Kling 3.0 Turbo en Python: esquema, script completo y manejo de errores

Referencia específica de esta versión sobre el esquema de una sola imagen de Turbo, el límite de 3–15 segundos, los niveles 720p/1080p y los modos de fallo.

Jul 11, 2026
API de imagen a video de Kling 3.0 Turbo en Python: esquema, script completo y manejo de errores

El esquema de kling-3.0-turbo/image-to-video es compacto y estricto: una URL de imagen pública, un prompt de movimiento obligatorio, una duración entera de 3 a 15 segundos y una salida de 720p o 1080p. Esta página es la referencia específica de esta versión para validar ese cuerpo de solicitud y distinguir los errores HTTP 400 de los resultados asíncronos TASK_FAILED.

Para el flujo general de creación, sondeo, callback y descarga, consulta la guía del ejecutor de tareas de Kling en Python y de selección entre Omni/Turbo.

Esquema de entrada de Turbo

Campo Tipo ¿Obligatorio? Valores aceptables
prompt string Sí Describe el movimiento y el comportamiento de la cámara
image_urls array de strings Sí Exactamente una URL de imagen accesible públicamente
duration integer No De 3 a 15 segundos
resolution string No 720p o 1080p

Turbo no acepta sound, aspect_ratio, negative_prompt, seed ni mode, ni tampoco una segunda URL de imagen. El esquema estricto rechaza las propiedades adicionales en lugar de ignorarlas silenciosamente.

La imagen de entrada determina la forma del fotograma. Antes de crear la tarea, súbela a un bucket de almacenamiento público o a una CDN; el renderizador no puede acceder a localhost, a paneles privados ni a URL firmadas caducadas.

Solicitud mínima funcional

curl -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kling-3.0-turbo/image-to-video",
    "input": {
      "prompt": "The runner accelerates as the camera tracks from the side",
      "image_urls": ["https://cdn.example.com/first-frame.jpg"],
      "duration": 6,
      "resolution": "1080p"
    }
  }'

La respuesta correcta contiene data.taskId. Un HTTP 200 solo indica que la creación se realizó, no que haya finalizado; el renderizado del video continúa de forma asíncrona.

Validación previa en Python

Valida las restricciones antes de la llamada de red para que los errores evidentes nunca lleguen a crear una tarea:

from urllib.parse import urlparse

import requests


def turbo_input(prompt: str, image_url: str, duration: int, resolution: str) -> dict:
    if not prompt.strip():
        raise ValueError("prompt is required")
    if type(duration) is not int or not 3 <= duration <= 15:
        raise ValueError("duration must be an integer from 3 to 15")
    if resolution not in {"720p", "1080p"}:
        raise ValueError("resolution must be 720p or 1080p")
    parsed = urlparse(image_url)
    if parsed.scheme not in {"http", "https"} or not parsed.netloc:
        raise ValueError("image_url must be a public HTTP(S) URL")

    return {
        "prompt": prompt,
        "image_urls": [image_url],
        "duration": duration,
        "resolution": resolution,
    }


payload = {
    "model": "kling-3.0-turbo/image-to-video",
    "input": turbo_input(
        prompt="The runner accelerates as the camera tracks from the side",
        image_url="https://cdn.example.com/first-frame.jpg",
        duration=6,
        resolution="1080p",
    ),
}

response = requests.post(
    "https://api.hiapi.ai/v1/tasks",
    headers={"Authorization": "Bearer sk-your-key"},
    json=payload,
    timeout=30,
)
response.raise_for_status()
task_id = response.json()["data"]["taskId"]
print(task_id)

Esta comprobación local detecta problemas de forma en los valores, pero no puede demostrar que la imagen remota pueda descargarse públicamente. El renderizador realiza esa descarga después de crear la tarea.

Script completo en Python: envío, sondeo y descarga

El fragmento anterior termina en el ID de tarea. Esta versión ejecuta el trabajo completo y guarda el MP4. Envía la cabecera Idempotency-Key, de modo que reintentar el mismo envío tras un tiempo de espera agotado devuelve la tarea original en lugar de crear y facturar una segunda tarea:

import os
import time
import uuid

import requests

API = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}"}


def run_turbo(prompt: str, image_url: str, duration: int = 5,
              resolution: str = "720p", out_path: str = "turbo.mp4") -> str:
    body = {
        "model": "kling-3.0-turbo/image-to-video",
        "input": turbo_input(prompt, image_url, duration, resolution),
    }
    key = str(uuid.uuid4())  # reuse this key if you retry the same submission
    r = requests.post(API, json=body, headers={**HEADERS, "Idempotency-Key": key}, timeout=30)
    if r.status_code == 400:
        raise ValueError(f"schema error, no task created: {r.text}")
    r.raise_for_status()
    task_id = r.json()["data"]["taskId"]

    deadline = time.time() + 900
    while time.time() < deadline:
        data = requests.get(f"{API}/{task_id}", headers=HEADERS, timeout=30).json()["data"]
        if data["status"] == "success":
            video = requests.get(data["output"][0]["url"], timeout=120)
            video.raise_for_status()
            with open(out_path, "wb") as f:
                f.write(video.content)  # the output URL is temporary, so save it now
            return out_path
        if data["status"] == "fail":
            raise RuntimeError(f"TASK_FAILED {task_id}: {data.get('error')}")
        time.sleep(10)
    raise TimeoutError(task_id)


print(run_turbo(
    "The runner accelerates as the camera tracks from the side",
    "https://cdn.example.com/first-frame.jpg",
))

Un clip de 5 segundos en 720p cuesta $0.65. En producción, sustituye el bucle de sondeo por el callback de nivel superior "callback": {"url": "https://your-app.example.com/hiapi/callback"} y deduplica las notificaciones por ID de tarea.

HTTP 400: la tarea nunca se creó

Una respuesta HTTP 400 es el resultado de la validación síncrona del esquema. Las causas típicas incluyen:

Entrada no válida Motivo del fallo Solución
"duration": "5" Se envió una cadena en lugar de un entero Envía 5
"duration": 20 El máximo es 15 Elige entre 3 y 15
Dos image_urls Turbo solo acepta una Conserva solo el fotograma inicial
"resolution": "4K" Turbo admite 720p y 1080p Usa 720p o 1080p, o elige Omni
"sound": true sound no está en el esquema de Turbo Elimina el campo o elige Omni
Falta prompt Turbo requiere un prompt Añade un prompt de movimiento no vacío

Como la validación falla antes de la creación, no hay ningún ID de tarea que sondear. Registra el cuerpo de la respuesta y el ID de solicitud, corrige el cuerpo y vuelve a enviar una nueva solicitud.

TASK_FAILED: la creación se realizó, pero el renderizado falló

Si POST /v1/tasks devuelve HTTP 200 y un ID de tarea, un fallo posterior es un problema del ciclo de vida de la tarea asíncrona y debe tratarse de forma distinta a un 400.

Las causas comunes incluyen:

  • La URL de la imagen requiere cookies o cabeceras de autorización;
  • La URL de imagen firmada caducó antes de que el renderizador la descargara;
  • El host bloquea la descarga del lado del servidor o redirige a una página HTML;
  • El archivo está dañado o su tipo de medio no coincide con el contenido;
  • El proveedor no pudo completar ese renderizado.

Registra el ID de tarea, el código y mensaje de error final, la URL de entrada original y la hora de la solicitud. Antes de reintentar, confirma que un servidor sin autenticación puede descargar esa imagen con una respuesta 2xx y un tipo de contenido de imagen. Reintentar a ciegas la misma URL inaccesible solo crea otra tarea fallida.

La guía general de Python contiene el bucle compartido de sondeo de estados terminales y el código de descarga de la salida; consérvalo allí para evitar duplicar la lógica del ciclo de vida en esta página de referencia de la versión.

Precios de Turbo y selección de modelo

Las tarifas de producción actuales son:

Nivel de Turbo Precio por segundo Tarea de 5 segundos
720p $0.130 $0.65
1080p $0.160 $0.80

Antes de usarlo a gran escala, consulta la página de precios en tiempo real. El nombre Turbo describe una variante del modelo; no garantiza que sea más barato en todas las resoluciones ni que las tareas cumplan un SLA fijo de tiempo de renderizado.

Cuando necesites fotograma final, audio o 4K, elige el Kling 3.0 estándar (kling-3.0/image-to-video): acepta una o dos imágenes (fotograma inicial y final), incluye un interruptor sound, cuesta $0.10/s en 720p sin audio y $0.129/s en 1080p sin audio. Cuando necesites imágenes o videos de referencia, elige Omni. Para un único fotograma de entrada en 720p o 1080p, compara estas variantes con tu propio prompt de movimiento y evalúa la calidad de salida, el tiempo de cola y el coste total.

Preguntas frecuentes

¿Cuántas imágenes acepta Kling 3.0 Turbo de imagen a video?

Exactamente una URL de imagen pública. Una segunda imagen provoca un error de esquema (image_urls: maxItems: got 2, want 1); si necesitas control de fotograma inicial y final, usa el Kling 3.0 estándar de imagen a video.

¿Qué valores de duración son válidos?

Envía un entero de 3 a 15. Los números entre comillas como "5" son cadenas y fallarán la validación.

¿Turbo admite 4K o audio?

No admite 4K: este endpoint acepta 720p o 1080p. No tiene el campo sound, pero los clips de Turbo incluyen audio propio, que no se puede desactivar. Cuando necesites 4K o salida sin sonido, usa el Kling 3.0 estándar u Omni.

¿Cuál es la diferencia entre HTTP 400 y TASK_FAILED?

HTTP 400 significa que la solicitud incumple el esquema, por lo que no se creó ninguna tarea. TASK_FAILED ocurre después de una respuesta de creación válida, en la fase de descarga de entrada o de generación.

¿Por qué una URL de imagen aparentemente pública provoca TASK_FAILED?

Puede que la URL dependa de cookies, que su firma haya caducado, que bloquee la descarga del lado del servidor o que devuelva HTML en lugar de bytes de imagen. Antes de reintentar, pruébala sin autenticación de navegador.

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