Skip to content

Image to Video API

Animate a still image with one API call. Send the image as a first frame or a reference, add a prompt, and get a video back. 8 models, billed per second of output from $0.042/s.

Image to video API models

Every model below takes an image and returns a video: Seedance 2.5, Seedance 2.0 Mini, Seedance 2.0 Fast, Seedance 2.0 Pro, Kling 4.0, Wan 3.0, Wan 3.0 Prime and MiniMax H3. The table lists the image inputs each one accepts.

Image to video models
ModelResolutionsClip lengthImage inputsFrom
Seedance 2.5480p, 720p and 1080p4–30 sFirst frame, last frame and reference images$0.132/s480p · 26.4 Credits/s
Seedance 2.0 Mini480p and 720p4–15 sFirst frame, last frame and reference images$0.042/s480p · 8.4 Credits/s
Seedance 2.0 Fast480p and 720p4–15 sFirst frame, last frame and reference images$0.067/s480p · 13.4 Credits/s
Seedance 2.0 Pro480p, 720p, 1080p and 4K4–15 sFirst frame, last frame and reference images$0.084/s480p · 16.8 Credits/s
Kling 4.0720p and 1080p3–30 sFirst frame, middle frame, last frame and reference images$0.157/s720p · 31.4 Credits/s
Wan 3.0480p, 720p and 1080p2–30 sFirst frame, last frame and reference images$0.05/s480p · 10 Credits/s
Wan 3.0 Prime720p2–30 sFirst frame, last frame and reference images$0.14/s720p · 28 Credits/s
MiniMax H3768p4–15 sFirst frame, last frame and reference images$0.09/s768p · 18 Credits/s

Send an image to the image to video API

An image goes in as a public HTTPS link or as the asset ID of a file you uploaded first. To upload, ask for an upload URL, send the bytes to it, then mark the upload complete and use the asset ID in the input.

This example asks Seedance 2.5 for a 5 second 720p clip that starts from your image. With a first frame, the ratio must be adaptive.

cURL

API=https://api.vizoapi.com/v1
AUTH="Authorization: Bearer $VIZO_API_KEY"

# Create the task once and keep its ID.
ID=$(curl -fsS $API/generations -H "$AUTH" -H "Content-Type: application/json" \
  -d '{
  "model": "seedance-2-5",
  "input": {
    "content": [
      {
        "type": "text",
        "text": "A slow dolly shot through a rainy neon street"
      },
      {
        "type": "image_url",
        "role": "first_frame",
        "image_url": {
          "url": "https://example.com/first-frame.jpg"
        }
      }
    ],
    "resolution": "720p",
    "ratio": "adaptive",
    "duration": 5
  },
  "metadata": {
    "client_reference": "my-unique-reference-1"
  }
}' | jq -r .id)

# Poll until the task closes, then read its status and result.
until curl -fsS $API/generations/$ID -H "$AUTH" | jq -e '.closed_at != null' > /dev/null; do sleep 5; done
curl -fsS $API/generations/$ID -H "$AUTH" | jq '{status, result}'

Python

import os, time, requests

api = "https://api.vizoapi.com/v1"
headers = {"Authorization": f"Bearer {os.environ['VIZO_API_KEY']}"}

# Create the task once and keep its ID.
res = requests.post(f"{api}/generations", headers=headers, timeout=30, json={
    "model": "seedance-2-5",
    "input": {"content": [{"type": "text", "text": "A slow dolly shot through a rainy neon street"}, {"type": "image_url", "role": "first_frame", "image_url": {"url": "https://example.com/first-frame.jpg"}}], "resolution": "720p", "ratio": "adaptive", "duration": 5},
    "metadata": {"client_reference": "my-unique-reference-1"},
})
res.raise_for_status()
task = res.json()

# Poll until the task closes, then read its status and result.
while True:
    t = requests.get(f"{api}/generations/{task['id']}", headers=headers, timeout=30).json()
    if t.get("closed_at"):
        break
    time.sleep(5)
print(t["status"], t.get("result"))

Node.js

const api = "https://api.vizoapi.com/v1";
const headers = { Authorization: `Bearer ${process.env.VIZO_API_KEY}`, "Content-Type": "application/json" };

// Create the task once and keep its ID.
const res = await fetch(`${api}/generations`, { method: "POST", headers, body: JSON.stringify({
  model: "seedance-2-5",
  input: {
    "content": [
      {
        "type": "text",
        "text": "A slow dolly shot through a rainy neon street"
      },
      {
        "type": "image_url",
        "role": "first_frame",
        "image_url": {
          "url": "https://example.com/first-frame.jpg"
        }
      }
    ],
    "resolution": "720p",
    "ratio": "adaptive",
    "duration": 5
  },
  metadata: { client_reference: "my-unique-reference-1" },
}) });
if (!res.ok) throw new Error(await res.text());
const task = await res.json();

// Poll until the task closes, then read its status and result.
let t;
do {
  await new Promise((ok) => setTimeout(ok, 5000));
  t = await (await fetch(`${api}/generations/${task.id}`, { headers })).json();
} while (!t.closed_at);
console.log(t.status, t.result);

The quick start walks through a full request, and model inputs and media covers links, uploads and limits.

Image to video API pricing

Image to video uses the same per-second rates as text to video: the model and the output resolution set the rate, and only an input video has a rate of its own. Credits are held when a task is accepted and charged on delivery. If generation fails, the hold is released and nothing is charged. Credits never expire and there is no subscription.

See every rate on the pricing page, or open a model page for its full price table.

Image to video API FAQ

What is an image to video API?
An API that takes a still image, usually with a text prompt, and returns a video that starts from or follows that image. With VizoAPI you send both to one endpoint and download the video when the task finishes.
How do I send the image?
As a public HTTPS link, or as the asset ID of a file you uploaded to the same project first. The model's input reference shows which field takes it and its role, such as first frame or reference image. Read the media inputs guide.
Can I set both the first and the last frame?
Yes, with every model on this page. The video starts on the first image and ends on the last. Kling 4.0 also takes a middle frame.
Does an image input change the price?
No. The rate is set by the model and the output resolution. Only a request with an input video has its own rate.
How much does the image to video API cost?
Video is billed per second of output. The lowest rate is 8.4 Credits/s ($0.042/s), for Seedance 2.0 Mini at 480p. The final charge follows the actual length the model reports. See all prices.
Am I charged when a task fails?
No. If generation fails, or nothing is delivered within 24 hours of acceptance, all held Credits are released.