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.








| Model | Resolutions | Clip length | Image inputs | From |
|---|---|---|---|---|
| Seedance 2.5 | 480p, 720p and 1080p | 4–30 s | First frame, last frame and reference images | $0.132/s480p · 26.4 Credits/s |
| Seedance 2.0 Mini | 480p and 720p | 4–15 s | First frame, last frame and reference images | $0.042/s480p · 8.4 Credits/s |
| Seedance 2.0 Fast | 480p and 720p | 4–15 s | First frame, last frame and reference images | $0.067/s480p · 13.4 Credits/s |
| Seedance 2.0 Pro | 480p, 720p, 1080p and 4K | 4–15 s | First frame, last frame and reference images | $0.084/s480p · 16.8 Credits/s |
| Kling 4.0 | 720p and 1080p | 3–30 s | First frame, middle frame, last frame and reference images | $0.157/s720p · 31.4 Credits/s |
| Wan 3.0 | 480p, 720p and 1080p | 2–30 s | First frame, last frame and reference images | $0.05/s480p · 10 Credits/s |
| Wan 3.0 Prime | 720p | 2–30 s | First frame, last frame and reference images | $0.14/s720p · 28 Credits/s |
| MiniMax H3 | 768p | 4–15 s | First 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.