Zum Hauptinhalt springen
Die Videogenerierung ist asynchron. Sende einen Job, speichere die queue_id und pollte /video/retrieve, bis die Antwort video/mp4 ist.

Endpoints

EndpointZweckPflicht
POST /video/quotePreis in USD vor der Generierung abrufenNein
POST /video/queueGenerierungsanfrage einreichenJa
POST /video/retrieveStatus pollen oder Video herunterladenJa
POST /video/completeVideo aus dem Speicher löschenNein

Schritt 1: Generierung in die Queue stellen

Request:
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"
}
Antwort (200):
{
  "model": "wan-2.5-preview-text-to-video",
  "queue_id": "123e4567-e89b-12d3-a456-426614174000"
}
Für Grok-Imagine-Private-Modelle enthält die Queue-Antwort ein zusätzliches Feld 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 ist eine vorsignierte URL, mit der du das fertige Video herunterlädst, statt es aus der Retrieve-Antwort zu lesen. Sie wird nur einmal in der Queue-Antwort zurückgegeben – persistiere sie also zusammen mit der queue_id. Das gilt für alle vier Grok-Imagine-Private-Varianten:
  • grok-imagine-text-to-video-private
  • grok-imagine-image-to-video-private
  • grok-imagine-reference-to-video-private
  • grok-imagine-video-to-video-private
Im Gegensatz zu den öffentlichen grok-imagine-*-video-Varianten werden Grok-Imagine-Private-Modelle bei Inhalts-Moderation-Ablehnungen nicht berechnet – du zahlst also nur für erfolgreiche Generierungen. Speichere model, queue_id und ggf. download_url für alle weiteren Aufrufe. Bei Private-Modellen ist download_url der Weg, die fertige Datei abzuholen, sobald der Job fertig ist. Der Link ist kurzlebig und zweckgebunden: Er soll dir das MP4 ausliefern und nicht als langfristige oder breit geteilte URL dienen. Wenn ein Download abbricht, kannst du denselben GET ein paar Mal aus derselben Umgebung wiederholen, bis die Datei fertig ist. Diese Retries sind für Netzwerk-Hänger gedacht – nicht dafür, denselben Link unbegrenzt zu pollen, ihn auf viele Clients zu verteilen oder ihn wie eine permanente Medien-URL einzubetten. Solche Muster zeigen sich oft als 429 oder 410, was überraschend sein kann, wenn du den Link wie reguläres File-Hosting erwartet hast. Für Zuverlässigkeit sollten GET-Anfragen aus einem Client-Netzwerk kommen. Etwas Flexibilität gibt es, wenn sich deine IP einmal ändert (z. B. VPN trennen und erneut versuchen), aber starke Variation der Quell-IPs funktioniert in der Regel nicht. Die URL bleibt bis zu 24 Stunden lang gültig oder bis das Objekt entfernt wird.
Wenn du eine stabile URL, öffentliche Wiedergabe oder wiederholten Zugriff über die Zeit brauchst, speichere die Datei zuerst in deinem eigenen Storage und liefere sie von dort aus.
Privacy: Link mit DELETE widerrufen Sobald du die Datei abgeholt hast – oder wenn du sie nicht behalten willst – kannst du DELETE auf denselben download_url aufrufen. Für diesen Request ist kein Venice-API-Schlüssel nötig. Das ist optional, aber bei datenschutzrelevanten Fällen empfohlen, weil einige Proxies und Middleboxen außerhalb von Venice vollständige URLs loggen, und das Löschen des Links ist der einfachste Weg, das Zeitfenster der vorsignierten URL zu verkleinern.
curl -X DELETE "$DOWNLOAD_URL"
Flow: /video/retrieve pollen bis COMPLETEDGET auf den download_url (bei Abbruch leicht retrien) → Datei dort speichern, wo du sie brauchst → optional DELETE auf den download_url → optional /video/complete aufrufen, falls du Queue-basiertes Cleanup nutzt.

Schritt 2: Auf Fertigstellung pollen

Request:
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"
}
Die Antwort hängt vom Status ab:
Content-TypeBedeutungAktion
application/jsonWird verarbeitet5 s warten, erneut pollen
video/mp4FertigResponse-Body ist die Videodatei
application/json mit "COMPLETED"Fertig, Video nicht inlineGET auf den download_url aus der Queue-Antwort
Processing-Antwort (200, application/json):
{
  "status": "PROCESSING",
  "average_execution_time": 145000,
  "execution_duration": 53200
}
Zeiten in Millisekunden. Nutze average_execution_time zur Abschätzung der verbleibenden Wartezeit. Complete-Antwort (200, video/mp4): Response-Body ist rohes Binär-Video. In Datei speichern. Complete-Antwort (200, application/json mit "COMPLETED"): Für Modelle, die beim Queue-Eintrag eine download_url geliefert haben, liefert Retrieve immer JSON. Hol das Video per GET download_url (ohne Auth-Header). Siehe Private Download-Links für Details, Retries und optional DELETE.

Schritt 3: Cleanup (optional)

Entweder automatisch beim Abruf löschen:
{
  "model": "wan-2.5-preview-text-to-video",
  "queue_id": "123e4567-e89b-12d3-a456-426614174000",
  "delete_media_on_completion": true
}
Oder nach dem Speichern /video/complete aufrufen:
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"
}
Antwort (200):
{
  "success": true
}

Vollständiges Beispiel

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

Request-Parameter

Queue-Request

ParameterTypPflichtDefaultBeschreibung
modelstringJa-Modell-ID. wan-2.5-preview-text-to-video für Text-to-Video, wan-2.5-preview-image-to-video für Image-to-Video
promptstringJa-Was generiert werden soll. Max. 2500 Zeichen
negative_promptstringNein"low resolution, error, worst quality, low quality, defects"Was zu vermeiden ist
durationstringJa-"5s" oder "10s"
resolutionstringNein"720p""480p", "720p" oder "1080p"
aspect_ratiostringBedingt-Modellabhängig. Pflicht bei Modellen mit Aspect-Ratio-Optionen; weglassen bei Modellen ohne Aspect-Ratio-Auswahl
audiobooleanBedingttrue (wenn unterstützt)Nur für Modelle mit supportsAudioConfig: true; weglassen bei Modellen ohne Audio-Konfig
image_urlstringNur für Image-to-Video-URL oder Base64-Data-URL des Quellbilds
audio_urlstringBedingt-URL oder Base64-Data-URL eines Referenz-Audios für Modelle mit Audio-Input
Die Queue-Validierung ist modellspezifisch. Prüfe /models?type=video für die unterstützten Request-Felder pro Modell, bevor du /video/queue aufrufst.

Quote-Request

ParameterTypPflichtDefaultBeschreibung
modelstringJa-Modell-ID zum Bepreisen
durationstringJa-"5s" oder "10s"
resolutionstringNein"720p""480p", "720p" oder "1080p"
aspect_ratiostringBedingt-Angeben, wenn das Modell Aspect-Ratio-Auswahl unterstützt oder verlangt
audiobooleanBedingttrue (wenn unterstützt)Nur gültig für Modelle mit supportsAudioConfig: true

Retrieve-Request

ParameterTypPflichtDefaultBeschreibung
modelstringJa-Aus der Queue-Antwort
queue_idstringJa-Aus der Queue-Antwort
delete_media_on_completionbooleanNeinfalseVideo nach erfolgreichem Abruf löschen

Complete-Request

ParameterTypPflichtBeschreibung
modelstringJaAus der Queue-Antwort
queue_idstringJaAus der Queue-Antwort

Image-to-Video

Bei Image-to-Video-Modellen das Quellbild per image_url übergeben. Der Prompt beschreibt die gewünschte Bewegung, nicht den Bildinhalt.
{
  "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"
}
Oder mit 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"
}

Preis-Quote

Exakte Kosten vor der Generierung. Nur die Pricing-Inputs senden (model, duration und optional resolution, aspect_ratio, audio): Request:
{
  "model": "wan-2.5-preview-text-to-video",
  "duration": "10s",
  "resolution": "1080p"
}
Antwort:
{
  "quote": 0.085
}
Das Quote ist in USD.

Fehler

StatusVonBedeutungAktion
400queue, quote, retrieve, completeUngültige ParameterRequest-Body gegen Schema prüfen
401queue, retrieve, completeAuth fehlgeschlagenAPI-Schlüssel prüfen
402queueUnzureichendes GuthabenAufladen
404retrieve, download_urlMedia nicht gefunden (ungültig, abgelaufen oder gelöscht)model/queue_id prüfen oder neu queuen
410download_urlVorsignierte URL abgelaufen, voll ausgenutzt oder widerrufen (z. B. nach DELETE)Neue Generierung starten, wenn du eine weitere Datei brauchst; jeder Link ist bewusst kurzlebig
429download_urlRate-limitiert – oft durch viele Retries oder wiederholtes Abrufen desselben LinksDownload abschließen (ein paar Retries sind ok, wenn die Verbindung abbricht), lokal speichern und ggf. DELETE; laufenden Zugriff über eigenes Storage realisieren
413queuePayload zu großImage-/Audio-Größe reduzieren
422queue, retrieveContent-VerstoßPrompt anpassen
500queue, retrieve, completeInferenz/Processing fehlgeschlagenMit Backoff erneut versuchen; Support kontaktieren, wenn anhaltend
503retrieveModell ausgelastetMit Backoff erneut versuchen

Polling-Strategie

  1. /video/retrieve in einem Intervall pollen (z. B. alle 5 Sekunden)
  2. Wenn Content-Type application/json und status "PROCESSING" ist: warten und erneut pollen. average_execution_time und execution_duration (Millisekunden) zum Schätzen der Restzeit nutzen
  3. Wenn Content-Type video/mp4 ist: Response-Body als Output-Datei speichern
  4. Wenn Content-Type application/json und status "COMPLETED" ist: GET auf den download_url aus der Queue-Antwort, um das Video abzuholen (siehe Private Download-Links)
  5. Wenn du download_url genutzt hast: Erwäge DELETE auf diese URL, wenn du fertig bist, um das Zeitfenster der vorsignierten URL zu verkürzen; dann optional delete_media_on_completion: true bei Retrieve setzen oder /video/complete für Queue-basiertes Cleanup aufrufen
  6. 404 als ungültiges, abgelaufenes oder gelöschtes Media behandeln; 500/503 mit Retries/Backoff abfangen

Verfügbare Modelle

Aktuelle Modellliste und Preise unter Video-Modelle.