Skip to main content
Video generation is async. Submit a job, save queue_id, then poll /video/retrieve until the response is video/mp4.

Endpoints

EndpointPurposeRequired
POST /video/quoteGet price in USD before generatingNo
POST /video/queueSubmit generation requestYes
POST /video/retrievePoll status or download videoYes
POST /video/completeDelete video from storageNo

Step 1: Queue Generation

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"
}
Response (200):
{
  "model": "wan-2.5-preview-text-to-video",
  "queue_id": "123e4567-e89b-12d3-a456-426614174000"
}
Save both model and queue_id - you need them for all subsequent calls.

Step 2: Poll for Completion

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"
}
Response depends on status:
Content-TypeMeaningAction
application/jsonStill processingWait 5s, poll again
video/mp4CompleteResponse body is the video file
Processing response (200, application/json):
{
  "status": "PROCESSING",
  "average_execution_time": 145000,
  "execution_duration": 53200
}
Times are in milliseconds. Use average_execution_time to estimate remaining wait. Complete response (200, video/mp4): Response body is raw binary video data. Save to file.

Step 3: Cleanup (Optional)

Either auto-delete on retrieval:
{
  "model": "wan-2.5-preview-text-to-video",
  "queue_id": "123e4567-e89b-12d3-a456-426614174000",
  "delete_media_on_completion": true
}
Or call /video/complete after saving:
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"
}
Response (200):
{
  "success": true
}

Complete Example

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"]

# 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
    time.sleep(5)

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

Request Parameters

Queue Request

ParameterTypeRequiredDefaultDescription
modelstringYes-Model ID. Use wan-2.5-preview-text-to-video for text-to-video, wan-2.5-preview-image-to-video for image-to-video
promptstringYes-What to generate. Max 2500 chars
negative_promptstringNo"low resolution, error, worst quality, low quality, defects"What to avoid
durationstringYes-"5s" or "10s"
resolutionstringNo"720p""480p", "720p", or "1080p"
aspect_ratiostringConditional-Model-dependent. Required for models that expose aspect-ratio options; omit for models that do not support aspect-ratio selection
audiobooleanConditionaltrue (when supported)Only valid for models with supportsAudioConfig: true; omit for models without audio config support
image_urlstringOnly for image-to-video-URL or base64 data URL of source image
audio_urlstringConditional-URL or base64 data URL of reference audio for models that support audio input
Queue validation is model-specific. Check /models?type=video for each model’s supported request fields before calling /video/queue.

Quote Request

ParameterTypeRequiredDefaultDescription
modelstringYes-Model ID to price
durationstringYes-"5s" or "10s"
resolutionstringNo"720p""480p", "720p", or "1080p"
aspect_ratiostringConditional-Include when the selected model supports or requires aspect-ratio selection
audiobooleanConditionaltrue (when supported)Only valid for models with supportsAudioConfig: true

Retrieve Request

ParameterTypeRequiredDefaultDescription
modelstringYes-From queue response
queue_idstringYes-From queue response
delete_media_on_completionbooleanNofalseDelete video after successful retrieval

Complete Request

ParameterTypeRequiredDescription
modelstringYesFrom queue response
queue_idstringYesFrom queue response

Image to Video

For image-to-video models, pass source image via image_url. The prompt describes desired motion, not the image content.
{
  "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"
}
Or with 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"
}

Price Quote

Get exact cost before generating. Send only pricing inputs (model, duration, and optional resolution, aspect_ratio, audio): Request:
{
  "model": "wan-2.5-preview-text-to-video",
  "duration": "10s",
  "resolution": "1080p"
}
Response:
{
  "quote": 0.085
}
Quote is in USD.

Errors

StatusReturned ByMeaningAction
400queue, quote, retrieve, completeInvalid parametersCheck request body against schema
401queue, retrieve, completeAuth failedCheck API key
402queueInsufficient balanceAdd funds
404retrieveMedia not found (invalid, expired, or deleted)Verify model/queue_id or re-queue
413queuePayload too largeReduce image/audio size
422queue, retrieveContent violationModify prompt
500queue, retrieve, completeInference/processing failedRetry with backoff; contact support if persistent
503retrieveModel at capacityRetry with backoff

Polling Strategy

  1. Poll /video/retrieve on an interval (for example, every 5 seconds)
  2. If Content-Type is application/json, status is still PROCESSING; inspect average_execution_time and execution_duration (milliseconds)
  3. If Content-Type is video/mp4, save the response body as your output file
  4. Optional cleanup: set delete_media_on_completion: true on retrieve, or call /video/complete after download
  5. Handle 404 as invalid, expired, or deleted media; handle 500/503 with retries/backoff

Available Models

See Video Models for current model list and pricing.