Guía de inicio rápido de Imagen y Video

Aprende a generar imágenes y vídeos a partir de prompts de texto y contenido multimedia de referencia.

La API de Imagen y Video es asíncrona. Envías una generación y, cuando termina, descargas el resultado desde una URL firmada. Las imágenes y los vídeos tienen rutas de API independientes, pero las estructuras de solicitud y respuesta son las mismas para ambos.

Hay dos formas de obtener el resultado. La entrega mediante webhook es la recomendada y la que usan los ejemplos siguientes: ElevenLabs llama a tu ruta de API en cuanto una generación alcanza un estado final, por lo que no se pierde tiempo esperando. El sondeo es la alternativa si no tienes una ruta de API para recibir una devolución de llamada, y cada ejemplo muestra cómo recurrir a él.

La API de Imagen y Video requiere un plan Pro o superior. Las llamadas desde un espacio de trabajo de un nivel inferior se rechazan con un error 402 paid_plan_required. Tu clave de API también debe tener el permiso de Imagen y Video o Flows para el espacio de trabajo.

Genera una imagen

1

Crea una clave de API

Crea una clave de API aquí, en el panel, que usarás para acceder a la API de forma segura.

Guarda la clave como un secreto gestionado y pásala a los SDK como variable de entorno mediante un archivo .env, o directamente en la configuración de tu aplicación, según prefieras.

.env
ELEVENLABS_API_KEY=<your_api_key_here>
2

Instala el SDK

También usaremos la biblioteca dotenv para cargar nuestra clave de API desde una variable de entorno.

pip install elevenlabs
pip install python-dotenv
3

Envía la generación

Cada modelo tiene su propia clase de solicitud, y sus campos son los parámetros que acepta ese modelo, por lo que al cambiar de modelo pueden cambiar los campos disponibles. Los campos desconocidos se rechazan en lugar de ignorarse.

webhook solicita que el resultado terminado se entregue a los webhooks de tu espacio de trabajo, por lo que la llamada devuelve el control en cuanto la generación se pone en cola. Requiere un webhook suscrito a eventos de generación; consulta webhooks de Imagen y Video para configurarlo u omite el campo y usa el sondeo en su lugar.

# example.py
import os
from dotenv import load_dotenv
from elevenlabs import ImageGenerationRequest_Gemini3ProImage, WebhookTarget_All
from elevenlabs.client import ElevenLabs
load_dotenv()
elevenlabs = ElevenLabs(api_key=os.getenv("ELEVENLABS_API_KEY"))
generation = elevenlabs.flows.image.create(
request=ImageGenerationRequest_Gemini3ProImage(
prompt="A corgi in a tiny lifeguard chair on a sunlit beach at golden hour, photorealistic",
aspect_ratio="16:9",
resolution="2K",
webhook=WebhookTarget_All(),
)
)
print(generation.id, generation.status)

La respuesta contiene el ID de la generación y nada más. Una generación recién creada siempre está pending:

{
"id": "JWr5N6X9ZTqf8jD2LmQb",
"status": "pending"
}
4

Obtén el resultado

Como la solicitud incluía webhook, ElevenLabs envía un evento flows_generation a tu ruta de API cuando la generación alcanza completed o failed. Los data del evento son idénticos a los que devuelve la ruta de API GET, y los webhooks de Imagen y Video explican cómo implementar el controlador que lo recibe.

Si no tienes una ruta de API para recibir devoluciones de llamada, elimina webhook de la solicitud anterior y usa el sondeo. Obtén la generación hasta que su estado sea completed o failed, dejando al menos dos segundos entre solicitudes para una imagen; consulta las pautas de sondeo para conocer los intervalos que debes usar para cada modalidad.

import time
import requests
while True:
result = elevenlabs.flows.image.get(generation.id)
if result.status in ("completed", "failed"):
break
time.sleep(2)
if result.status == "failed":
raise RuntimeError(f"{result.failure_reason}: {result.error_message}")
with open("corgi.png", "wb") as f:
f.write(requests.get(result.content_url).content)

En ambos casos, una generación completada incluye los mismos campos:

{
"id": "JWr5N6X9ZTqf8jD2LmQb",
"status": "completed",
"content_url": "https://storage.googleapis.com/generations/JWr5N6X9ZTqf8jD2LmQb",
"content_mime_type": "image/png"
}
5

Ejecuta el código

python example.py

La generación se pone en cola y se muestra su ID. Con entrega mediante webhook, la imagen llega a tu ruta de API; con la variante de sondeo, se guarda en corgi.png.

Genera un vídeo

Las generaciones de vídeo usan flows.video y siguen el mismo patrón de envío y recogida. Un vídeo puede tardar varios minutos, así que este ejemplo usa la entrega mediante webhook con webhook en lugar de esperar el resultado.

from elevenlabs import VideoGenerationRequest_Veo31FastGenerate001, WebhookTarget_All
generation = elevenlabs.flows.video.create(
request=VideoGenerationRequest_Veo31FastGenerate001(
prompt="A corgi rides a tiny surfboard across a sunlit wave at golden hour, cinematic",
duration_secs=8,
aspect_ratio="16:9",
resolution="1080p",
generate_audio=True,
webhook=WebhookTarget_All(),
)
)
print(generation.id)

La llamada devuelve el control en cuanto la generación se pone en cola, y el resultado terminado se entrega a todos los webhooks de tu espacio de trabajo suscritos a eventos de generación. La salida de vídeo es MP4, por lo que la carga completada informa de un content_mime_type de video/mp4. Consulta los webhooks de Imagen y Video para configurar un webhook e implementar el controlador que recibe este evento.

webhook requiere al menos un webhook del espacio de trabajo suscrito a eventos de generación. Sin uno, la llamada de creación se rechaza en lugar de iniciar una generación cuyo resultado no tiene adónde ir. Elimina el campo para usar el sondeo con flows.video.get y no sondees más de una vez cada 10 segundos.

Recopilar resultados

Los webhooks y el polling devuelven la misma carga útil, así que la elección depende de cómo esperas a recibirla, no de lo que recibes.

Entrega mediante webhookPolling
Ideal paraLa opción predeterminada para ambas modalidades y producciónScripts y entornos sin una ruta de API pública
RequiereUna ruta de API HTTPS suscrita a eventos de generaciónNada
Coste de esperaNinguno; te llamamos cuando termina la generaciónUna solicitud por sondeo y generación

Usa webhooks siempre que puedas. Recurre al polling cuando no tengas dónde recibir una devolución de llamada y, cuando lo hagas, sigue los intervalos que indicamos a continuación.

Elegir destinos de webhook

webhook acepta dos formatos. WebhookTarget_All llega a todos los webhooks suscritos a eventos de generación, que es la opción predeterminada adecuada porque sigue funcionando aunque los webhooks se roten o sustituyan. WebhookTarget_Ids limita la entrega a webhooks específicos, para cuando un espacio de trabajo distribuye a varios consumidores y un trabajo concreto solo debe llegar a uno de ellos:

from elevenlabs import WebhookTarget_Ids
webhook = WebhookTarget_Ids(ids=["Q8mVr2LpXcT4nB6yJdKw"])

Todos los ID ya deben estar suscritos a eventos de generación; indicar un webhook no suscrito se rechaza en lugar de ignorarse sin aviso. La carga útil entregada es idéntica a la que devuelve la ruta de API GET, así que un controlador creado para uno sirve para el otro. La guía sobre webhooks explica cómo configurar un webhook, verificar la firma y gestionar el evento.

Pautas para el polling

El tiempo de ejecución de una generación depende del modelo, la resolución y, en el caso del vídeo, la duración, así que haz polling a un intervalo adaptado a lo que has solicitado, en lugar de hacerlo en un bucle fijo:

  • Imágenes: no hagas polling más de una vez cada 2 segundos. La mayoría terminan en unos segundos.
  • Vídeo: no hagas polling más de una vez cada 10 segundos. Espera minutos, no segundos, y ajusta el intervalo según duration_secs y resolution.

Hay dos reglas para ambos casos. Aumenta el intervalo si una generación tarda mucho — duplicarlo hasta aproximadamente un minuto evita que una generación lenta se convierta en cientos de solicitudes. Y establece un límite para el bucle, para que una generación bloqueada termine como un tiempo de espera en tu propio código en lugar de como un bucle ilimitado.

Hacer polling más rápido no aporta nada: el estado de una generación no cambia antes porque lo hayas consultado dos veces. Un polling agresivo y continuado puede devolver respuestas 429, que debes gestionar con una espera exponencial.

Ciclo de vida de una generación

Una generación pasa por cuatro estados. Los dos estados finales contienen campos distintos, así que depende de status antes de leer el resto de la respuesta.

EstadoSignificado
pendingLa generación está en cola. Es el estado de todas las generaciones recién creadas.
generatingEl modelo se está ejecutando.
completedEl resultado está listo. La respuesta contiene content_url y content_mime_type.
failedLa generación no produjo ningún resultado. La respuesta contiene los detalles del error.

content_url es una URL firmada que caduca aproximadamente una hora después de devolver la respuesta. Obtén la generación de nuevo para conseguir una URL actualizada, en lugar de guardar la propia URL firmada.

Gestionar errores

Una generación fallida informa de una categoría failure_reason junto con un error_message legible para las personas:

{
"id": "JWr5N6X9ZTqf8jD2LmQb",
"status": "failed",
"failure_reason": "moderated",
"error_message": "The prompt was rejected by content moderation. You were not charged for this generation."
}
failure_reasonCausa
timeoutEl modelo no devolvió un resultado a tiempo.
model_errorEl proveedor del modelo devolvió un error o no produjo ningún resultado.
moderatedEl prompt o una entrada fue rechazado por la moderación de contenido.
invalid_parametersLos parámetros se rechazaron cuando la generación llegó al modelo.
dependency_failedFalló una generación de la que depende esta.
charging_failedNo se pudo cobrar la generación al espacio de trabajo.
internal_errorSe produjo un error inesperado.

Las generaciones fallidas no se cobran. Los problemas de parámetros que pueden detectarse de antemano — un campo no compatible, un valor fuera del rango permitido de un modelo o una combinación no válida de entradas de referencia — se rechazan en la solicitud de creación antes de que comience ninguna generación.

Precios

Las generaciones se cobran en créditos. El coste depende del modelo, de los parámetros que elijas, como la resolución y la duración, y de las entradas que proporciones. Una generación cuesta lo mismo mediante la API que en la app de ElevenLabs, donde se muestra el coste antes de enviarla. Consulta Imagen y Video en el playground para saber cómo se presenta el coste de una combinación concreta de modelo y ajustes.

Consulta tus generaciones

Cada ruta de API enumera las generaciones creadas a través de ella, empezando por las más recientes. Los resultados se limitan a tu espacio de trabajo y a esta API, por lo que las generaciones creadas en la app de ElevenLabs no aparecen.

page = elevenlabs.flows.image.list(page_size=20, status="completed")
for item in page.generations:
print(item.id, item.content_url)
while page.has_more:
page = elevenlabs.flows.image.list(page_size=20, status="completed", cursor=page.next_cursor)
for item in page.generations:
print(item.id, item.content_url)

page_size acepta valores de 1 a 100 y el valor predeterminado es 30. Pasa status para devolver solo las generaciones en un estado del ciclo de vida y model_id para devolver solo las generaciones de un único modelo. Trata next_cursor como un valor opaco: devuelve el valor exacto y detente cuando has_more sea false.

Modelos disponibles

La API expone un subconjunto de los modelos disponibles en la app de ElevenLabs. Cada modelo acepta solo los parámetros indicados para él; enviar un campo compatible con otro modelo devuelve un error de validación.

Los modelos de ByteDance están desactivados de forma predeterminada y requieren aprobación explícita antes de usarlos. Hasta que se conceda el acceso, se rechazará una solicitud que indique uno de ellos con un error model_access_denied. Los clientes Enterprise pueden contactar con soporte para solicitar acceso.

Modelos de imagen

model_idImágenes de referenciaControles de salida
gpt-image-1Hasta 5, más una maskaspect_ratio (1:1, 3:2, 2:3), quality, background
gpt-image-1.5Hasta 5, más una maskaspect_ratio (1:1, 3:2, 2:3), quality, background
gpt-image-2Hasta 10, más una mask15 relaciones de aspecto, resolution (1K, 2K, 4K), quality
gpt-image-2.5-sunburstHasta 10, más una mask15 relaciones de aspecto, resolution (1K, 2K, 4K), quality (hasta max)
gpt-image-2.5-flareHasta 10, más una mask15 relaciones de aspecto, resolution (1K, 2K, 4K), quality (hasta max)
gemini-2.5-flash-imageHasta 5aspect_ratio
gemini-3-pro-imageHasta 10aspect_ratio, resolution (1K, 2K, 4K)
gemini-3.1-flash-imageHasta 14aspect_ratio (incluidas 1:4, 4:1, 1:8, 8:1), resolution (de 512 a 4K)
gemini-3.1-flash-lite-imageHasta 14aspect_ratio, resolution (1K)
bytedance-seedream-5-liteHasta 10aspect_ratio, resolution (2K, 3K), seed
bytedance-seedream-5-proHasta 10aspect_ratio, resolution (1K, 2K), seed

Los modelos GPT Image 2.5 aceptan los valores low, medium, high, xhigh y max para quality, y el valor predeterminado es high. GPT Image 2 llega hasta high y el valor predeterminado es medium.

Modelos de vídeo

model_idEntradas multimediaControles de salida
veo-3.1-generate-001start_frame, end_frame, hasta 3 images con un roleduration_secs (4, 6, 8), aspect_ratio (16:9, 9:16), resolution (720p, 1080p, 4K), generate_audio
veo-3.1-fast-generate-001start_frame, end_frame, hasta 3 images con un roleduration_secs (4, 6, 8), aspect_ratio (16:9, 9:16), resolution (720p, 1080p, 4K), generate_audio
bytedance-seedance-v2start_frame, end_frame, hasta 9 images, 3 videos, 3 audiosduration_secs (de 4 a 15), 7 relaciones de aspecto, resolution (de 480p a 4k), generate_audio
bytedance-seedance-v2-faststart_frame, end_frame, hasta 9 images, 3 videos, 3 audiosduration_secs (de 4 a 15), 7 relaciones de aspecto, resolution (480p, 720p), generate_audio
bytedance-seedance-v2-ministart_frame, end_frame, hasta 9 images, 3 videos, 3 audiosduration_secs (de 4 a 15), 7 relaciones de aspecto, resolution (480p, 720p), generate_audio
bytedance-seedance-v2.5start_frame, end_frame, hasta 30 images, 10 videos, 10 audiosduration_secs (de 4 a 30), 7 relaciones de aspecto, resolution (480p, 720p), generate_audio
creatify-auroraimage y audio, ambos obligatoriosresolution (480p, 720p), guidance_scale, audio_guidance_scale

Para consultar las capacidades, la disponibilidad y los precios de los modelos, consulta la visión general de Imagen y Video.

Próximos pasos