Saltar al contenido principal
La generación de vídeo es asíncrona. Envía un trabajo, guarda queue_id y haz polling de /video/retrieve hasta que la respuesta sea video/mp4.

Endpoints

EndpointPropósitoObligatorio
POST /video/quoteObtén precio en USD antes de generarNo
POST /video/queueEnvía la solicitud de generación
POST /video/retrieveConsulta estado o descarga el vídeo
POST /video/completeElimina el vídeo del almacenamientoNo

Paso 1: encola la generación

Solicitud:
POST https://api.venice.ai/api/v1/video/queue
Authorization: Bearer $VENICE_API_KEY
Content-Type: application/json

{
  "model": "wan-2.5-preview-text-to-video",
  "prompt": "A gondola gliding through Venice canals at sunset",
  "duration": "5s",
  "resolution": "720p",
  "aspect_ratio": "16:9"
}
Respuesta (200):
{
  "model": "wan-2.5-preview-text-to-video",
  "queue_id": "123e4567-e89b-12d3-a456-426614174000"
}
Para los modelos Grok Imagine Private, la respuesta de la cola incluye un campo extra download_url:
{
  "model": "grok-imagine-text-to-video-private",
  "queue_id": "123e4567-e89b-12d3-a456-426614174000",
  "download_url": "https://private-share.venice.ai/v1/share/read/..."
}
download_url es una URL pre-firmada que usas para descargar el vídeo terminado en lugar de leerlo desde la respuesta de retrieve. Solo se devuelve una vez en la respuesta de la cola, así que persístela junto con queue_id. Esto se aplica a las cuatro variantes Grok Imagine Private:
  • grok-imagine-text-to-video-private
  • grok-imagine-image-to-video-private
  • grok-imagine-reference-to-video-private
  • grok-imagine-video-to-video-private
A diferencia de las variantes públicas grok-imagine-*-video, los modelos Grok Imagine Private no se facturan por rechazos de moderación de contenido, por lo que solo pagas por generaciones exitosas. Guarda model, queue_id y download_url (si está presente) para todas las llamadas posteriores.

Enlaces de descarga privados

Para los modelos privados, download_url es la forma de obtener el archivo terminado una vez completado el trabajo. El enlace es de corta duración y de un solo propósito: está ahí para entregarte el MP4, no para servir como URL de larga duración o ampliamente compartida. Si una descarga se interrumpe, puedes reintentar el mismo GET unas cuantas veces desde el mismo entorno hasta que el archivo termine. Esos reintentos son para recuperarse de cortes de red — no para hacer polling indefinido del mismo enlace, compartirlo entre muchos clientes o incrustarlo como una URL de medios permanente. Patrones así suelen aparecer como 429 o 410, lo que puede ser sorprendente si esperabas que el enlace se comportara como hosting de archivos normal. Para fiabilidad, las solicitudes GET deben originarse desde una sola red de cliente. Hay cierta flexibilidad si tu IP cambia una vez (por ejemplo, desconectas una VPN y vuelves a intentarlo), pero una gran variación de IPs de origen normalmente no funcionará. La URL es válida durante hasta 24 horas, o hasta que el objeto sea eliminado.
Si necesitas una URL estable, reproducción pública o acceso repetido en el tiempo, guarda el archivo en tu propio almacenamiento primero y sírvelo desde allí.
Privacidad: revoca el enlace con DELETE Cuando termines de descargar el archivo — o si decides no conservarlo — puedes llamar a DELETE sobre el mismo download_url. No se requiere API key de Venice en esa solicitud. Esto es opcional, pero recomendado cuando la privacidad importa, porque algunos proxies y middleboxes fuera de Venice mantienen logs de URLs completas, y eliminar el enlace es la forma más simple de reducir la ventana en la que existe la URL pre-firmada.
curl -X DELETE "$DOWNLOAD_URL"
Flujo: haz polling de /video/retrieve hasta COMPLETEDGET del download_url (reintenta ligeramente si la transferencia falla) → guarda el archivo donde lo necesites → DELETE del download_url si quieres que el enlace se invalide → opcionalmente llama a /video/complete si aún usas la limpieza basada en cola.

Paso 2: polling de finalización

Solicitud:
POST https://api.venice.ai/api/v1/video/retrieve
Authorization: Bearer $VENICE_API_KEY
Content-Type: application/json

{
  "model": "wan-2.5-preview-text-to-video",
  "queue_id": "123e4567-e89b-12d3-a456-426614174000"
}
La respuesta depende del estado:
Content-TypeSignificadoAcción
application/jsonAún procesandoEspera 5s y vuelve a hacer polling
video/mp4CompletadoEl cuerpo de la respuesta es el archivo de vídeo
application/json con "COMPLETED"Completado, vídeo no inlineHaz GET del download_url de la respuesta de la cola
Respuesta en procesamiento (200, application/json):
{
  "status": "PROCESSING",
  "average_execution_time": 145000,
  "execution_duration": 53200
}
Los tiempos están en milisegundos. Usa average_execution_time para estimar la espera restante. Respuesta completada (200, video/mp4): El cuerpo de la respuesta son datos binarios en bruto del vídeo. Guárdalo en un archivo. Respuesta completada (200, application/json con "COMPLETED"): Para los modelos que devolvieron un download_url en la cola, retrieve siempre devuelve JSON. Obtén el vídeo con GET download_url (sin cabecera de auth). Consulta Enlaces de descarga privados para saber cómo funcionan estas URLs, los reintentos y el DELETE opcional.

Paso 3: limpieza (opcional)

O auto-eliminar al recuperar:
{
  "model": "wan-2.5-preview-text-to-video",
  "queue_id": "123e4567-e89b-12d3-a456-426614174000",
  "delete_media_on_completion": true
}
O llama a /video/complete tras guardar:
POST https://api.venice.ai/api/v1/video/complete
Authorization: Bearer $VENICE_API_KEY
Content-Type: application/json

{
  "model": "wan-2.5-preview-text-to-video",
  "queue_id": "123e4567-e89b-12d3-a456-426614174000"
}
Respuesta (200):
{
  "success": true
}

Ejemplo completo

import os
import time
import requests

API_KEY = os.environ.get("VENICE_API_KEY")
BASE_URL = "https://api.venice.ai/api/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}

# Queue
resp = requests.post(f"{BASE_URL}/video/queue", headers=HEADERS, json={
    "model": "wan-2.5-preview-text-to-video",
    "prompt": "A gondola gliding through Venice canals at sunset",
    "duration": "5s",
    "resolution": "720p",
    "aspect_ratio": "16:9"
})
data = resp.json()
model, queue_id = data["model"], data["queue_id"]
download_url = data.get("download_url")

# Poll
while True:
    resp = requests.post(f"{BASE_URL}/video/retrieve", headers=HEADERS,
                         json={"model": model, "queue_id": queue_id})
    if "video/mp4" in resp.headers.get("Content-Type", ""):
        with open("output.mp4", "wb") as f:
            f.write(resp.content)
        break
    if resp.json().get("status") == "COMPLETED" and download_url:
        with open("output.mp4", "wb") as f:
            f.write(requests.get(download_url).content)
        break
    time.sleep(5)

# Cleanup
requests.post(f"{BASE_URL}/video/complete", headers=HEADERS,
              json={"model": model, "queue_id": queue_id})

Parámetros de solicitud

Solicitud Queue

ParámetroTipoObligatorioPredeterminadoDescripción
modelstring-ID del modelo. Usa wan-2.5-preview-text-to-video para text-to-video, wan-2.5-preview-image-to-video para image-to-video
promptstring-Qué generar. Máx. 2500 caracteres
negative_promptstringNo"low resolution, error, worst quality, low quality, defects"Qué evitar
durationstring-"5s" o "10s"
resolutionstringNo"720p""480p", "720p" o "1080p"
aspect_ratiostringCondicional-Depende del modelo. Obligatorio para modelos que exponen opciones de aspect ratio; omítelo para modelos que no admiten selección de aspect ratio
audiobooleanCondicionaltrue (cuando se admite)Solo válido para modelos con supportsAudioConfig: true; omítelo para modelos sin soporte de configuración de audio
image_urlstringSolo para image-to-video-URL o data URL en base64 de la imagen fuente
audio_urlstringCondicional-URL o data URL en base64 del audio de referencia para modelos que admiten entrada de audio
La validación de la cola es específica del modelo. Comprueba /models?type=video para ver los campos de solicitud admitidos por cada modelo antes de llamar a /video/queue.

Solicitud Quote

ParámetroTipoObligatorioPredeterminadoDescripción
modelstring-ID del modelo para cotizar
durationstring-"5s" o "10s"
resolutionstringNo"720p""480p", "720p" o "1080p"
aspect_ratiostringCondicional-Inclúyelo cuando el modelo seleccionado admita o requiera selección de aspect ratio
audiobooleanCondicionaltrue (cuando se admite)Solo válido para modelos con supportsAudioConfig: true

Solicitud Retrieve

ParámetroTipoObligatorioPredeterminadoDescripción
modelstring-De la respuesta de la cola
queue_idstring-De la respuesta de la cola
delete_media_on_completionbooleanNofalseEliminar el vídeo tras la recuperación exitosa

Solicitud Complete

ParámetroTipoObligatorioDescripción
modelstringDe la respuesta de la cola
queue_idstringDe la respuesta de la cola

Imagen a vídeo

Para los modelos image-to-video, pasa la imagen fuente vía image_url. El prompt describe el movimiento deseado, no el contenido de la imagen.
{
  "model": "wan-2.5-preview-image-to-video",
  "prompt": "Camera slowly zooms in as leaves rustle in the wind",
  "image_url": "https://example.com/image.jpg",
  "duration": "5s"
}
O con base64:
{
  "model": "wan-2.5-preview-image-to-video",
  "prompt": "Camera slowly zooms in as leaves rustle in the wind",
  "image_url": "data:image/jpeg;base64,/9j/4AAQ...",
  "duration": "5s"
}

Cotización de precio

Obtén el coste exacto antes de generar. Envía solo entradas de precio (model, duration y los opcionales resolution, aspect_ratio, audio): Solicitud:
{
  "model": "wan-2.5-preview-text-to-video",
  "duration": "10s",
  "resolution": "1080p"
}
Respuesta:
{
  "quote": 0.085
}
La cotización es en USD.

Errores

EstadoDevuelto porSignificadoAcción
400queue, quote, retrieve, completeParámetros no válidosVerifica el cuerpo de la solicitud contra el schema
401queue, retrieve, completeAuth fallidaComprueba la API key
402queueSaldo insuficienteAñade fondos
404retrieve, download_urlMedia no encontrado (no válido, expirado o eliminado)Verifica model/queue_id o vuelve a encolar
410download_urlURL pre-firmada expirada, totalmente usada o revocada (por ejemplo, tras DELETE)Inicia una nueva generación si necesitas otro archivo; cada enlace es intencionadamente de corta duración
429download_urlRate-limited — a menudo por muchos reintentos o descargas repetidas del mismo enlaceTermina la descarga (algunos reintentos están bien si la conexión cae), guarda una copia local y usa DELETE si quieres limpiar el enlace; mantén el acceso continuado en tu propio almacenamiento
413queuePayload demasiado grandeReduce el tamaño de imagen/audio
422queue, retrieveInfracción de contenidoModifica el prompt
500queue, retrieve, completeInferencia/procesamiento fallidoReintenta con backoff; contacta con soporte si persiste
503retrieveModelo a capacidad máximaReintenta con backoff

Estrategia de polling

  1. Haz polling de /video/retrieve a intervalos (por ejemplo, cada 5 segundos)
  2. Si Content-Type es application/json y status es "PROCESSING", espera y vuelve a hacer polling. Usa average_execution_time y execution_duration (milisegundos) para estimar el tiempo restante
  3. Si Content-Type es video/mp4, guarda el cuerpo de la respuesta como tu archivo de salida
  4. Si Content-Type es application/json y status es "COMPLETED", haz GET del download_url de la respuesta de la cola para obtener el vídeo (consulta Enlaces de descarga privados)
  5. Si usaste download_url, considera hacer DELETE en esa URL cuando termines para reducir cuánto existe la URL pre-firmada; después, opcionalmente, establece delete_media_on_completion: true en retrieve o llama a /video/complete para limpieza basada en cola
  6. Gestiona 404 como media no válido, expirado o eliminado; gestiona 500/503 con reintentos/backoff

Modelos disponibles

Consulta Modelos de vídeo para la lista actual de modelos y precios.