Skip to navigation

Korte introductie tot Afbeelding & Video

Leer hoe je afbeeldingen en video's genereert op basis van tekstprompts en referentiemedia.

De Image & Video API is asynchroon. Je dient een generatie in en downloadt het resultaat via een ondertekende URL zodra deze is voltooid. Afbeeldingen en video’s hebben afzonderlijke endpoints, maar de request- en responsestructuur is voor beide hetzelfde.

Er zijn twee manieren om het resultaat op te halen. Levering via webhooks is de aanbevolen methode, die ook in de onderstaande voorbeelden wordt gebruikt: ElevenLabs roept je endpoint aan zodra een generatie een eindstatus bereikt, zodat er niets wordt besteed aan wachten. Polling is het alternatief als je geen endpoint hebt om een callback te ontvangen. Elk voorbeeld laat zien hoe je daarop terugvalt.

De Image & Video API vereist een Pro-abonnement of hoger. Calls vanuit een workspace met een lager abonnement worden afgewezen met een 402 paid_plan_required-fout. Je API-sleutel moet voor de workspace ook de machtiging Image & Video of Flows hebben.

Een afbeelding genereren

1

Een API-sleutel maken

Maak hier een API-sleutel in het dashboard, die je gebruikt voor veilige toegang tot de API.

Sla de sleutel op als beheerd geheim en geef deze aan de SDK’s door als omgevingsvariabele via een .env-bestand, of rechtstreeks in de configuratie van je app, afhankelijk van je voorkeur.

.env
ELEVENLABS_API_KEY=<your_api_key_here>
2

De SDK installeren

We gebruiken ook de dotenv-bibliotheek om onze API-sleutel uit een omgevingsvariabele te laden.

pip install elevenlabs
pip install python-dotenv
3

De generatie indienen

Elk model heeft een eigen requestklasse en de velden daarin zijn de parameters die dat model accepteert. Als je van model wisselt, kunnen dus andere velden beschikbaar zijn. Onbekende velden worden afgewezen in plaats van genegeerd.

webhook vraagt om het voltooide resultaat bij de webhooks van je workspace af te leveren, zodat de call wordt geretourneerd zodra de generatie in de wachtrij staat. Hiervoor is een webhook vereist die is geabonneerd op generatie- gebeurtenissen. Raadpleeg Image & Video- webhooks om er een in te stellen, of laat het veld weg en gebruik polling.

# 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)

De response bevat alleen de generatie-ID. Een nieuw gemaakte generatie heeft altijd de status pending:

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

Het resultaat ophalen

Omdat de request webhook gebruikt, post ElevenLabs een flows_generation-gebeurtenis naar je endpoint zodra de generatie completed of failed bereikt. De data van de gebeurtenis is identiek aan wat het GET-endpoint retourneert. In Image & Video-webhooks lees je hoe je de handler maakt die deze ontvangt.

Als je geen endpoint hebt om callbacks te ontvangen, verwijder je webhook uit de bovenstaande request en gebruik je polling. Haal de generatie op totdat de status completed of failed is, met minimaal twee seconden tussen requests voor een afbeelding — zie Richtlijnen voor polling voor de intervallen per modaliteit.

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)

Een voltooide generatie bevat in beide gevallen dezelfde velden:

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

De code uitvoeren

python example.py

De generatie wordt in de wachtrij geplaatst en de ID wordt weergegeven. Bij levering via webhook komt de afbeelding aan bij je endpoint; met de pollingvariant wordt deze opgeslagen als corgi.png.

Een video genereren

Videogeneraties gebruiken flows.video en volgen hetzelfde patroon van indienen en ophalen. Een video kan enkele minuten duren, dus dit voorbeeld gebruikt levering via webhook met webhook in plaats van op het resultaat te wachten.

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)

De call wordt geretourneerd zodra de generatie in de wachtrij staat en het voltooide resultaat wordt afgeleverd bij elke webhook in je workspace die is geabonneerd op generatiegebeurtenissen. Video-output is MP4, dus de voltooide payload rapporteert een content_mime_type van video/mp4. Zie Image & Video-webhooks voor het configureren van een webhook en het schrijven van de handler die dit ontvangt.

webhook vereist minstens één workspace-webhook die is geabonneerd op generatiegebeurtenissen. Zonder zo’n webhook wordt de create-call afgewezen, in plaats van een generatie te starten waarvan het resultaat nergens naartoe kan. Verwijder het veld om terug te vallen op polling met flows.video.get, en voer polling niet vaker uit dan eens per 10 seconden.

Resultaten ophalen

Webhooks en polling retourneren dezelfde payload, dus de keuze gaat over hoe je erop wacht en niet over wat je ontvangt.

Levering via webhookPolling
Beste voorDe standaard voor beide modaliteiten en elk productiegebruikScripts en omgevingen zonder openbaar endpoint
VereistEen HTTPS-endpoint dat is geabonneerd op generatiegebeurtenissenNiets
Kosten van wachtenGeen; je wordt aangeroepen zodra de generatie is voltooidEén request per polling, per generatie

Gebruik waar mogelijk webhooks. Gebruik polling wanneer je nergens een callback kunt ontvangen en houd je dan aan de onderstaande intervallen.

Webhookdoelen kiezen

webhook accepteert twee vormen. WebhookTarget_All bereikt elke webhook die is geabonneerd op generatie- gebeurtenissen. Dit is de juiste standaard, omdat deze blijft werken als webhooks worden geroteerd of vervangen. WebhookTarget_Ids beperkt de levering tot specifieke webhooks, voor wanneer één workspace wordt verdeeld over meerdere ontvangers en een bepaalde taak slechts één daarvan moet bereiken:

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

Elke ID moet al zijn geabonneerd op generatiegebeurtenissen. Het opgeven van een webhook zonder abonnement wordt afgewezen in plaats van stilzwijgend genegeerd. De afgeleverde payload is identiek aan wat het GET-endpoint retourneert, dus een handler die voor het ene is geschreven, werkt ook voor het andere. In de webhookshandleiding lees je hoe je een webhook configureert, de handtekening verifieert en de gebeurtenis afhandelt.

Richtlijnen voor polling

De uitvoeringstijd van een generatie hangt af van het model, de resolutie en, voor video, de duur. Voer polling daarom uit met een interval dat past bij wat je hebt aangevraagd, en niet in een vaste loop:

  • Afbeeldingen: voer polling niet vaker uit dan eens per 2 seconden. De meeste zijn binnen enkele seconden klaar.
  • Video: voer polling niet vaker uit dan eens per 10 seconden. Reken op minuten in plaats van seconden, en schaal het interval met duration_secs en resolution.

Voor beide gelden twee regels. Verhoog het interval wanneer een generatie lang duurt — door het interval te verdubbelen tot ongeveer een minuut voorkom je dat een langzame generatie honderden requests veroorzaakt. Geef de loop ook een limiet, zodat een vastgelopen generatie in je eigen code eindigt met een time-out in plaats van een onbeperkte loop.

Sneller pollen levert niets op: de status van een generatie verandert niet eerder omdat je twee keer hebt gevraagd. Aanhoudend agressieve polling kan 429-responses retourneren, die je moet afhandelen met exponentiële backoff.

Levenscyclus van een generatie

Een generatie doorloopt vier statussen. De twee eindstatussen bevatten verschillende velden, dus vertak op status voordat je de rest van de response leest.

StatusBetekenis
pendingDe generatie staat in de wachtrij. Dit is de status van elke nieuw gemaakte generatie.
generatingHet model wordt uitgevoerd.
completedDe output is klaar. De response bevat content_url en content_mime_type.
failedDe generatie heeft geen output opgeleverd. De response bevat de foutdetails.

content_url is een ondertekende URL die ongeveer een uur nadat de response is geretourneerd verloopt. Haal de generatie opnieuw op voor een nieuwe URL, in plaats van de ondertekende URL zelf op te slaan.

Fouten afhandelen

Een mislukte generatie rapporteert een categorie failure_reason naast een leesbare error_message:

{
"id": "JWr5N6X9ZTqf8jD2LmQb",
"status": "failed",
"failure_reason": "moderated",
"error_message": "The prompt was rejected by content moderation. You were not charged for this generation."
}
failure_reasonOorzaak
timeoutHet model retourneerde niet op tijd een resultaat.
model_errorDe modelprovider retourneerde een fout of produceerde geen output.
moderatedDe prompt of een invoer is afgewezen door contentmoderatie.
invalid_parametersDe parameters zijn afgewezen toen de generatie het model bereikte.
dependency_failedEen generatie waarvan deze afhankelijk is, is mislukt.
charging_failedDe kosten voor de generatie konden niet bij de workspace in rekening worden gebracht.
internal_errorEr is een onverwachte fout opgetreden.

Voor mislukte generaties worden geen kosten in rekening gebracht. Parameterproblemen die vooraf kunnen worden gedetecteerd — een niet-ondersteund veld, een waarde buiten het toegestane bereik van een model of een ongeldige combinatie van referentie- invoer — worden in plaats daarvan door de create-request afgewezen, voordat een generatie begint.

Prijzen

Voor generaties worden credits in rekening gebracht. De kosten hangen af van het model, de parameters die je kiest, zoals resolutie en duur, en de invoer die je opgeeft. Een generatie kost via de API evenveel als in de ElevenLabs-app, waar de kosten worden weergegeven voordat je indient. Zie Image & Video in de playground voor hoe de kosten van een bepaalde combinatie van model en instellingen worden weergegeven.

Je generaties weergeven

Elk endpoint geeft de generaties weer die ermee zijn gemaakt, met de nieuwste eerst. Resultaten zijn beperkt tot je workspace en deze API, dus generaties die in de ElevenLabs-app zijn gemaakt, worden niet weergegeven.

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 accepteert 1 tot en met 100 en is standaard 30. Geef status door om alleen generaties in één levenscyclusstatus te retourneren, en model_id om alleen generaties van één model te retourneren. Behandel next_cursor als doorschijnend: geef de exacte waarde terug en stop wanneer has_more false is.

Beschikbare modellen

De API biedt toegang tot een subset van de modellen die beschikbaar zijn in de ElevenLabs-app. Elk model accepteert alleen de parameters die ervoor worden vermeld — als je een veld stuurt dat door een ander model wordt ondersteund, krijg je een validatiefout.

ByteDance-modellen zijn standaard uitgeschakeld en vereisen expliciete goedkeuring voordat je ze kunt gebruiken. Tot toegang is verleend, wordt een request waarin een van deze modellen wordt genoemd afgewezen met een foutmelding model_access_denied. Enterprise- klanten kunnen contact opnemen met support om toegang aan te vragen.

Afbeeldingsmodellen

model_idReferentieafbeeldingenUitvoerinstellingen
gpt-image-1Maximaal 5, plus een maskaspect_ratio (1:1, 3:2, 2:3), quality, background
gpt-image-1.5Maximaal 5, plus een maskaspect_ratio (1:1, 3:2, 2:3), quality, background
gpt-image-2Maximaal 10, plus een mask15 beeldverhoudingen, resolution (1K, 2K, 4K), quality
gpt-image-2.5-sunburstMaximaal 10, plus een mask15 beeldverhoudingen, resolution (1K, 2K, 4K), quality (tot max)
gpt-image-2.5-flareMaximaal 10, plus een mask15 beeldverhoudingen, resolution (1K, 2K, 4K), quality (tot max)
gemini-2.5-flash-imageMaximaal 5aspect_ratio
gemini-3-pro-imageMaximaal 10aspect_ratio, resolution (1K, 2K, 4K)
gemini-3.1-flash-imageMaximaal 14aspect_ratio (inclusief 1:4, 4:1, 1:8, 8:1), resolution (512 tot 4K)
gemini-3.1-flash-lite-imageMaximaal 14aspect_ratio, resolution (1K)
bytedance-seedream-5-liteMaximaal 10aspect_ratio, resolution (2K, 3K), seed
bytedance-seedream-5-proMaximaal 10aspect_ratio, resolution (1K, 2K), seed

De GPT Image 2.5-modellen accepteren quality-waarden van low, medium, high, xhigh en max, en gebruiken standaard high. GPT Image 2 gaat tot high en gebruikt standaard medium.

Videomodellen

model_idMedia-inputsUitvoerinstellingen
veo-3.1-generate-001start_frame, end_frame, maximaal 3 images met een 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, maximaal 3 images met een roleduration_secs (4, 6, 8), aspect_ratio (16:9, 9:16), resolution (720p, 1080p, 4K), generate_audio
bytedance-seedance-v2start_frame, end_frame, maximaal 9 images, 3 videos, 3 audiosduration_secs (4 tot 15), 7 beeldverhoudingen, resolution (480p tot 4k), generate_audio
bytedance-seedance-v2-faststart_frame, end_frame, maximaal 9 images, 3 videos, 3 audiosduration_secs (4 tot 15), 7 beeldverhoudingen, resolution (480p, 720p), generate_audio
bytedance-seedance-v2-ministart_frame, end_frame, maximaal 9 images, 3 videos, 3 audiosduration_secs (4 tot 15), 7 beeldverhoudingen, resolution (480p, 720p), generate_audio
bytedance-seedance-v2.5start_frame, end_frame, maximaal 30 images, 10 videos, 10 audiosduration_secs (4 tot 30), 7 beeldverhoudingen, resolution (480p, 720p), generate_audio
creatify-auroraimage en audio, beide vereistresolution (480p, 720p), guidance_scale, audio_guidance_scale

Zie voor modelmogelijkheden, beschikbaarheid en prijzen het overzicht van Afbeelding & Video.

Volgende stappen