How to use Venice's video generation API

Generating AI Videos with the Venice API

A practical guide to generating AI videos with Venice's async video API.

Venice.aiVenice.ai

Video generation is becoming an increasingly important tool in many content creators' workflows today. Whether you need to just generate a few short clips for a video or you are building entire generative content pipelines, Venice has you covered. In this article, we'll be diving into how you can use the Venice AI API effectively to be able to create generative videos - focusing on Wan 2.7, one of our most popular models for video creation.

Before we continue: if you want to execute any of the code in this article, you'll need a Venice API key. You will also want to have it as an environment variable. If you are using the bash snippets, you can simply add it like so:

How Venice's Video API works

In terms of generating videos, the Venice API follows a simple async pattern: queue it, poll until the result is ready, then retrieve the stored media and optionally delete it. That same flow works whether you're generating from text, animating an image, or using reference assets for consistency. You can also get a price quote from our API in case you need price tracking.

Below is a short table of our current endpoints and what each of them does:

EndpointWhat it does
POST /video/quoteReturns the price in USD before you generate
POST /video/queueQueues a new video job and returns a queue_id
POST /video/retrieveReturns processing status or the finished video
POST /video/completeDeletes stored media after you've downloaded it

Unlike Venice's image generation API, video is asynchronous due to video generation comparatively taking a long time.

Finding video models on Venice

Venice has a variety of models that you can use for video generation. Many of them also differ in the types of parameters they accept. Some support audio, some do not. Some accept image_url, some expect reference arrays, and some expose only certain durations or aspect ratios.

If you are not sure what parameters the model you want to use accepts, don't forget that you can call the /models endpoint. You'll also need to ensure that you append a type=video query parameter onto the end of the URL - this will ensure you only get results related to video generation models. A usage example (with bash) can be found below:

The results will tell you which models are text-to-video, image-to-video, reference-driven, or upscaling models, plus their supported durations, resolutions, aspect ratios, audio support, and prompt limits.

Getting a price quote for video generation

If you need to do price tracking for specific requests, you can use our /video/quote endpoint by sending a POST request with the details of the model and other details you are using for the generation. While not mandatory, this is particularly useful if you are interested in cost tracking (or want to pass the costs onto your end users!).

Response:

The quote is returned in USD. Note that $1 = 100 credits, so in terms of credits, $0.085 would be 8.5 Venice API credits. For models that support configurable audio or aspect ratios, don't forget to include those fields in the quote request - you can check all the supported input fields in our API reference.

Queueing a text to video job

Once you know the model and settings you want, you can then queue the generation request with POST /video/queue.

Response:

Save both values. You'll need the model and the queue_id for every later call.

Some VPS-backed models may also return a download_url in this first response. When that happens, keep it. You'll still poll /video/retrieve, but once the job reaches COMPLETED, you'll fetch the file from the pre-signed URL instead of receiving raw video/mp4 directly from the retrieve endpoint.

The end video should look something like this:

Image to Video

For image-to-video, the only real difference is that your queue request includes an image_url field containing a normal HTTPS URL or a base64 data URL. A sample request body can be found below.

One practical prompting note: for image-to-video, the prompt should describe motion, camera movement, and atmosphere. The source image already provides the composition and visual identity. Don't forget also that if you're doing this programatically, you can convert an image buffer to image URL by encoding it in Base64.

As an example - let's use the following image:

Using the prior request, it should generate something that looks like the video below:

Reference to Video

If you need consistency across shots, Venice also supports reference-driven video models - meaning that you can add image references and scene image references to be used in your video generation. This is where the API becomes more model-specific, so it is worth checking both the model metadata and the Reference-to-Video guide before you lock in your integration.

A typical reference to video request looks like this:

The important point is that you do not switch endpoints for reference-to-video. You still use POST /video/queue, POST /video/retrieve, and POST /video/complete. Only the request body changes. Again, like with Image to Video, we can also still use base64-encoded reference image URLs.

Using the following two images and the prior prompt:

We can create a video of the subject walking in the background, like in the video below:

Retrieving generated video

The retrieve endpoint has two modes:

  • If the job is still running, you get JSON back with status and timing data.
  • If the job is finished, you get either raw video/mp4 or a completed status that tells you it is time to fetch the earlier download_url.

A request in bash to retrieve a given video looks like this:

A JSON response for a video that's still being generated would look like below:

In practice, you will need to poll the retrieval endpoint multiple times until a successful (or failed!) response, using a loop. A good time to wait between attempts is usually around 5 seconds. The average_execution_time and execution_duration fields are both measured in milliseconds, so you can roughly judge how long your generation will take based on those two figures.

Using Venice video generation from JavaScript

In reality, not everything is handled with one-line Bash commands. It's much more often the case that you may be calling the video generation endpoint from a CLI or backend service - or an agent.

Below is an end-to-end snippet that you can copy if you want to just get straight into trying out video generation from JavaScript. It handles both retrieve modes: direct video/mp4 responses and jobs that complete through a pre-signed download_url.

To run this script as-is, ensure you save it to a file then use node <filename>.mjs. Because we're using import syntax and top-level await, Node needs to treat this file as an ES module. The simplest way is to use the .mjs extension, which tells Node to do that automatically - no config needed (if you're running this inside an existing Node project that already has "type": "module" in its package.json, a plain .js file works too).

Post-generation cleanup

Once you have the file, the media is not automatically deleted from the server. To do so, you can delete the media yourself in one of two ways.

Option 1: tell retrieve to delete the media automatically after a successful completion:

Option 2: call POST /video/complete after you've saved the file locally:

Response:

If you are sure that you won't need the media to stay on-server after you've initially downloaded it, enabling deleting media on completion mitigates the number of API calls you need to make. Otherwise, manually making a POST request to /video/complete is usually more resilient as networking issues may cause unpredictable scenarios.

Common Errors to Handle Up Front

StatusWhat it usually meansWhat to do
400Invalid request body or unsupported parameter for that modelValidate against the model's supported fields
401Bad API key or the model requires a higher access tierCheck auth and model access
402Insufficient balanceTop up your Venice balance, or fund your x402 wallet credits
403Model unavailable in your regionRemove VPN/proxy/Tor and retry from a supported region
404Invalid, expired, or already deleted mediaRe-check model and queue_id, or queue a new job
413Payload too largeShrink image, audio, or video inputs
422Content policy violationAdjust the prompt or input assets
500 / 503Provider-side failure or capacity issueRetry with backoff

If you are building a production integration, treat 500 and 503 as retriable, and treat 404 as terminal unless you know the job should still exist.

X402 Support

In addition to regular authentication, video generation additionally supports X402 via X-Sign-In-With-X (SIWE) headers for micropayments.

If you want to use wallet-native payments with Venice, don't forget to read our guide on using Venice with X402, which will explain everything you need to know from manually creating your own X402 headers from scratch to using our X402 client library to do the whole thing for you.

Conclusion

Thanks for reading! Venice is constantly shipping new models on our platform - feel free to try them out and let us know what you think.

For the latest model list and full parameter details, keep these pages bookmarked:

Back to all posts
Room