Skip to content
Docs version r8
OpenAPIJSONYAML
Guides / Models

Wan 3.0 API

Every input field of Wan 3.0, the rules between them, the price and a complete request with its responses.

POST/v1/generations"model": "wan-3-0"

Generates a video from a prompt and optional media: image frames, or reference images, videos and audio, a document or a web page.

What it does

Wan 3.0 makes a video of 2 to 30 seconds, with a soundtrack by default, from a prompt and optional media: image frames, reference images, videos and audio, a document or a web page. The prompt goes in input.prompt, the media in input.media (each item is {"type", "url"}), and the settings in input.parameters, where duration is required. The media you send choose the mode:

Modemedia itemsOther fields to set
[Text to video](#text-to-video)—parameters.ratio
[First frame](#first-frame)one first_frame—
[First and last frame](#first-and-last-frame)first_frame and last_frame—
[Reference images and video](#reference-images-and-video)up to 10 reference_image, 5 reference_video—
[Reference audio](#reference-audio)up to 5 reference_audio, with or without other references—
[Document or web page](#document-or-web-page)one file or one link, optionally with references—

Every example below is a complete body for POST /v1/generations. Send the same body to POST /v1/estimates first: it is free, creates no task, holds no Credits, and refuses an invalid body with the same 422 as a create. The https://media.vizoapi.com/... files are public samples, so the examples run as they are; replace https://example.com/... with your own file or an uploaded ast_... asset ID (a file or link takes a URL only).

Modes

Text to video

Only prompt, up to 20,000 characters. Set parameters.ratio to 16:9, 4:3, 1:1, 3:4 or 9:16; adaptive is the default. parameters.duration is 2 to 30 seconds, or -1 to let the model choose.

Text to video
{
  "model": "wan-3-0",
  "input": {
    "prompt": "A paper boat drifts across a still pond at dawn, mist on the water, slow push-in, soft natural light",
    "parameters": {
      "resolution": "720P",
      "ratio": "16:9",
      "duration": 5,
      "audio": true
    }
  }
}

First frame

The video starts on your image. Send one first_frame and keep ratio at adaptive so the output takes the image's shape. The prompt describes what happens next; it may be left out.

First frame
{
  "model": "wan-3-0",
  "input": {
    "prompt": "The hominids step back as the sun rises behind the monolith, slow push-in",
    "media": [
      { "type": "first_frame", "url": "https://media.vizoapi.com/samples/seedance-2-5/odyssey-v1/keyframes/monolith.jpg" }
    ],
    "parameters": {
      "resolution": "720P",
      "duration": 5
    }
  }
}

First and last frame

The video moves from the first image to the last. Send at most one first_frame and one last_frame (rule frame_repeated). Frames cannot be combined with any reference item, file or link (rule frames_with_references).

First and last frame
{
  "model": "wan-3-0",
  "input": {
    "prompt": "The ring-shaped station slowly turns to face the camera as an amber planet rises behind it",
    "media": [
      { "type": "first_frame", "url": "https://media.vizoapi.com/samples/seedance-2-5/odyssey-v1/keyframes/station.jpg" },
      { "type": "last_frame", "url": "https://media.vizoapi.com/samples/seedance-2-5/odyssey-v1/keyframes/ending.jpg" }
    ],
    "parameters": {
      "resolution": "720P",
      "duration": 6
    }
  }
}

Reference images and video

Reference images give the model characters, objects, places or a style; reference videos give it motion, camera movement or a subject to reuse. Send up to 10 images and 5 videos (rules too_many_reference_images, too_many_reference_videos); the videos run at most 15 seconds together, and input plus output at most 30 seconds. Name each item in the prompt by kind and order: "image 1", "video 1". Any reference_video moves the task to the -video tier of its resolution, which bills the input video's seconds too (see [How it is billed](#how-it-is-billed)).

Reference images and video
{
  "model": "wan-3-0",
  "input": {
    "prompt": "Follow the camera movement of video 1, set on the space station from image 1, then cut to the black monolith from image 2",
    "media": [
      { "type": "reference_image", "url": "https://media.vizoapi.com/samples/seedance-2-5/odyssey-v1/keyframes/station.jpg" },
      { "type": "reference_image", "url": "https://media.vizoapi.com/samples/seedance-2-5/odyssey-v1/keyframes/monolith.jpg" },
      { "type": "reference_video", "url": "https://media.vizoapi.com/samples/seedance-2-5/odyssey-v1/1.mp4" }
    ],
    "parameters": {
      "resolution": "720P",
      "ratio": "16:9",
      "duration": 5
    }
  }
}

Reference audio

Reference audio gives the model a voice, rhythm or sound to follow. Send up to 5 items (rule too_many_reference_audios), at most 15 seconds together. Audio can be mixed with reference images and videos, and never changes the tier.

Reference audio
{
  "model": "wan-3-0",
  "input": {
    "prompt": "The astronaut from image 1 speaks to the camera inside the station, in the voice of audio 1",
    "media": [
      { "type": "reference_image", "url": "https://example.com/astronaut.png" },
      { "type": "reference_audio", "url": "https://example.com/voice.mp3" }
    ],
    "parameters": {
      "resolution": "720P",
      "ratio": "16:9",
      "duration": 8
    }
  }
}

Document or web page

A file (a document such as a slide deck) or a link (a public web page that needs no login) gives the model material to turn into a video, such as a product ad from its brochure. Send at most one of them, never both (rules too_many_files, too_many_links, file_with_link). Both take a public https URL only, not an asset ID, and the model fetches them itself, so their size and format are checked only when the task runs. They can be combined with reference items, but not with frames.

Web page
{
  "model": "wan-3-0",
  "input": {
    "prompt": "A minimal, futuristic 15-second product ad for the smart glasses on this page",
    "media": [
      { "type": "link", "url": "https://example.com/product-page" }
    ],
    "parameters": {
      "resolution": "720P",
      "ratio": "16:9",
      "duration": 15
    }
  }
}

Input limits

LimitValueChecked
Prompt and mediaA prompt, media or bothAt create, 422 invalid_input (prompt_or_media)
PromptUp to 20,000 charactersAt create (out_of_range)
media items1 to 22. At most one first_frame and one last_frame, never with other items; up to 10 reference images, 5 reference videos, 5 reference audios; one file or one linkAt create (too_many_items, too_few_items, frame_repeated, frames_with_references, too_many_reference_images, too_many_reference_videos, too_many_reference_audios, too_many_files, too_many_links, file_with_link)
Reference videos togetherAt most 15 seconds; no limit on a single video's length beyond thatAt create once the lengths that can be read pass it, 422 input_duration_out_of_range (video_total_too_long); otherwise when the task runs
Reference audio togetherAt most 15 secondsSame, rule audio_total_too_long
Reference video input + durationAt most 30 secondsAt create when every video's length can be read, rule input_plus_output_too_long; otherwise when the task runs
Image filePNG, JPEG, WebP; up to 30 MBAt create when readable: 422 input_media_invalid (format) or input_media_too_large (size)
Video fileMP4, MOV; up to 300 MBSame
Audio fileMP3, WAV; up to 15 MBSame
file and linkPublic https URL only; an ast_... ID is refusedThe URL at create (bad_format); format and size only when the task runs
Uploaded assetimage/png, image/jpeg, image/webp, video/mp4, audio/mpeg, audio/wav; up to 20,000,000 bytesWhen you request the upload, 422
Image pixel size, video resolution and other media propertiesChecked by the model onlyWhen the task runs: the task fails with input_media_invalid (a size, dimension or frame-rate refusal) or input_rejected (a parameter the model calls invalid) and is not charged

A media value is a public https URL (up to 4,000 characters) or, for images, videos and audio, an ast_... asset ID from your project. Plain http, private or local addresses, URLs with a user name or #fragment, and Base64 data are refused with 422 (rule bad_format). The model fetches a linked file itself, possibly some time after acceptance, so keep it reachable until the task closes; if it cannot, the task fails with input_media_unreachable. See Model inputs and media.

Output

SettingValues
parameters.resolution480P, 720P (default) or 1080P, in capitals
parameters.ratioadaptive (default), 16:9, 4:3, 1:1, 3:4 or 9:16. adaptive follows the input media
parameters.durationRequired: 2 to 30 seconds, or -1 for the model to choose. With a reference video, input plus output is at most 30 seconds
parameters.audiotrue (default) adds a soundtrack; false gives a silent video. The price is the same
parameters.seed0 to 2147483647 to repeat a result more closely; random when left out
parameters.watermarkfalse (default) or true for a visible watermark. The price is the same

A succeeded task lists one MP4 in result.outputs: take its asset_id and get a download URL with download an asset. Outputs are kept for 7 days. See Get results.

How it is billed

The input selects the tier: parameters.resolution alone, or resolution plus -video when media has any reference_video. Images, audio, file and link never change the tier or the price, and neither do ratio, audio, seed or watermark.

TierCredits per secondSeconds billed
480p, 720p, 1080p10, 19, 38Output seconds
480p-video, 720p-video, 1080p-video10, 19, 38Output + input seconds

Input seconds are the length of all reference videos together, rounded up, at most 15. When a video's length cannot be read at create, or the request also has a file or link, the hold counts 15 input seconds. With duration: -1 the hold counts 30 output seconds; when every reference video is measured, it counts only what fits in 30 seconds with the input, and the billed seconds stop at 30. The sample video in the examples runs 12.06 seconds, so it holds 13 input seconds.

Holds at 720p:

RequestOutputInputBilledHeld (Credits)
Text or frames, duration: 55—595.000
Text or frames, duration: -130—30570.000
Reference video of 12.06 s, duration: 551318342.000
The same, video length not readable51520380.000
Reference video of 12.06 s, duration: -1181330570.000
Reference video not readable, duration: -1301545855.000

A 5-second text video holds 50.000 Credits at 480p and 190.000 Credits at 1080p.

The hold is only the estimate. A succeeded task is charged for the output seconds the model reports, plus its reported input seconds on a -video tier, to the millisecond, at the tier's rate. So price.charged can be below the hold (the rest is released) or above it, with no cap. Usage above the hold comes from your available balance; what it cannot cover is owed, and new creates get 402 balance_negative until a top-up. A failed or unresolved task is not charged. Send the body to POST /v1/estimates to see the exact hold and its basis (output_seconds, input_seconds, billed_seconds, auto). See Billing.

Errors and behaviors

WhenResponseWhat to do
A field the schema does not list, a wrong value or type, no parameters.duration422 invalid_input, errors[].rule such as field_not_allowed, value_not_allowed, out_of_range, requiredSend only the fields in the reference below
More than 22 media items, or an empty list422 invalid_input, rule too_many_items or too_few_itemsSend 1 to 22 items, or leave media out
An ast_... ID in a file or link422 invalid_input, rule bad_formatSend a public https URL
Neither prompt nor media422 invalid_input, rule prompt_or_mediaSend a prompt, media or both
A media rule is broken422 invalid_input with the rule: frame_repeated, frames_with_references, file_with_link, too_many_reference_images, too_many_reference_videos, too_many_reference_audios, too_many_files, too_many_linksFix the item at errors[].path
Measured reference videos or audio are too long in total, or input plus output passes 30 seconds422 input_duration_out_of_range; errors[] names /media with rule video_total_too_long or audio_total_too_long, or /parameters/duration with rule input_plus_output_too_longTrim the media or lower duration
A linked file has the wrong format or is too large422 input_media_invalid or input_media_too_largeConvert or shrink it
The model refuses a media file's size, dimensions or frame rate when the task runsTask fails with input_media_invalid when the model names that cause; otherwise generation_failedCheck the file; nothing is charged
The model calls a setting or media invalid when the task runsTask fails with input_rejectedCheck the media and settings; nothing is charged
The model cannot download a fileTask fails with input_media_unreachable when the model names that cause; otherwise generation_failedKeep the URL public until the task closes, or upload the file
Content safety refuses the prompt or mediaTask fails with input_moderated when the model reports a safety refusal; otherwise generation_failedChange the prompt or media; nothing is charged
Content safety refuses the resultTask fails with output_moderated when the model reports a safety refusal; otherwise generation_failed; no resultChange the prompt; nothing is charged
The model refuses the request when it is sent, or fails for another reasonTask fails with generation_failedCheck the body, or retry; nothing is charged

Moderation is always on; no field turns it off. Each task has a deadline of 24 hours from acceptance. A task still unfinished then closes as unresolved, releases its hold and is not charged; if its result arrives later, it is added at no charge and late_result_available becomes true. See Errors and Get results.

Prompting tips

  • Name media by kind and order in media: "image 1", "image 2", "video 1", "audio 1". Say what to take from each: "the character from image 1", "the camera movement of video 1", "the voice of audio 1".
  • Write the shot, not just the subject: subject, action, setting, camera movement, light and style. For several shots, number them ("Shot 1: …, Shot 2: …").
  • Describe the sound you want when audio is on: ambience, effects, music, or a spoken line in quotes.
  • With first and last frames, describe the motion between them; the frames already fix the start and end.
  • With a file or link, say what kind of video to make from it (an ad, an explainer) and its tone; the model picks the content from the material.
  • Keep a reference video short when you want a long output: input and output share 30 seconds.
  • Iterate on the prompt at 480P, where a second costs least, then render the final video at 720P or 1080P.

Pricing

Your input selects the tier. Video is billed per second of output; a tier with input video also counts the input seconds.

TierSelected byPriceLength
480presolution = 480p10 Credits/s2–30 s
480p-videoresolution = 480p, input video10 Credits/s2–30 s
720presolution = 720p19 Credits/s2–30 s
720p-videoresolution = 720p, input video19 Credits/s2–30 s
1080presolution = 1080p38 Credits/s2–30 s
1080p-videoresolution = 1080p, input video38 Credits/s2–30 s

Rules

  • Send a prompt, media or both.
  • first_frame and last_frame (at most one each) cannot be combined with reference items, file or link.
  • Reference videos total at most 15 seconds, reference audios at most 15 seconds, and reference video input plus output length at most 30 seconds.

Input fields

Send these fields in input. A field the table does not list is refused with HTTP 422 invalid_input.

Input fields
FieldDescription
promptstring

Required: at least one of prompt or media

Up to 20000 characters. Cite media in order, for example image 1 or video 1. Send a prompt, media or both.

At most 20,000 characters

mediaarray of objects

Required: at least one of prompt or media

first_frame and last_frame (at most 1 each) cannot be combined with reference items, file or link. Up to 10 reference images, 5 reference videos (15 seconds in total) and 5 reference audios; at most one file or one link, not both.

At least 1 items · At most 22 items

media[].typestringRequired

Media kind.

Allowed valuesfirst_framelast_framereference_imagereference_videoreference_audiofilelink
media[].urlstringRequired

An https URL or an uploaded asset id (ast_...). file and link take a public https URL only.

At most 4000 characters · Pattern^(https://|ast_)

parametersobjectRequired
parameters.resolutionstringOptional

Output resolution. Defaults to 720P.

Allowed values480P720P1080P

Default 720P

parameters.ratiostringOptional

Output aspect ratio. Defaults to adaptive.

Allowed valuesadaptive16:94:31:13:49:16

Default adaptive

parameters.durationanyRequired

Output seconds, 2 to 30, or -1 for automatic length. Holds the maximum; known input reduces it to fit the 30-second total.

2 to 30, or -1

parameters.audiobooleanOptional

Adds a soundtrack. Defaults to true.

Default true

parameters.seedintegerOptional

Random seed.

Minimum 0 · Maximum 2,147,483,647

parameters.watermarkbooleanOptional

Add a visible watermark. Defaults to false; the tier price is unchanged.

Default false

Example

A complete create request, the 202 answer and the task once it has succeeded.

Request

cURL

curl https://api.vizoapi.com/v1/generations \
  -H "Authorization: Bearer $VIZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "wan-3-0",
  "input": {
    "prompt": "A paper boat drifting on a pond at dawn, slow dolly in",
    "parameters": {
      "ratio": "16:9",
      "duration": 5
    }
  },
  "metadata": {
    "client_reference": "my-unique-reference-1"
  }
}'

Python

import os, requests

# Send once: do not retry this request automatically.
task = requests.post(
    "https://api.vizoapi.com/v1/generations",
    headers={"Authorization": f"Bearer {os.environ['VIZO_API_KEY']}"},
    json={
      "model": "wan-3-0",
      "input": {
        "prompt": "A paper boat drifting on a pond at dawn, slow dolly in",
        "parameters": {
          "ratio": "16:9",
          "duration": 5
        }
      },
      "metadata": {
        "client_reference": "my-unique-reference-1"
      }
    },
    timeout=60,
).json()
print(task["id"], task["status"])

Node.js

// Send once: do not retry this request automatically.
const res = await fetch("https://api.vizoapi.com/v1/generations", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.VIZO_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "model": "wan-3-0",
    "input": {
      "prompt": "A paper boat drifting on a pond at dawn, slow dolly in",
      "parameters": {
        "ratio": "16:9",
        "duration": 5
      }
    },
    "metadata": {
      "client_reference": "my-unique-reference-1"
    }
  }),
});
const task = await res.json();
console.log(task.id, task.status);

This input selects the 480p tier at 10 Credits per second. For 5 seconds the API holds 50.000 Credits.

Response

202 Accepted

{
  "id": "gen_01JD8Z5QW3XR",
  "model": "wan-3-0",
  "source": "api",
  "created_at": "2026-11-08T09:00:00Z",
  "customer_resolution_deadline": "2026-11-09T09:00:00Z",
  "late_result_available": false,
  "metadata": {
    "client_reference": "my-unique-reference-1"
  },
  "status": "processing",
  "execution_status": "processing",
  "delivery_status": "pending",
  "billing_status": "pending",
  "version": 1,
  "price": {
    "unit": "credit",
    "estimated": "50.000",
    "reserved": "0.000",
    "charged": "0.000",
    "refunded": "0.000"
  },
  "allowed_actions": [],
  "closed_at": null,
  "error": null,
  "result": null
}

200 Succeeded

{
  "id": "gen_01JD8Z5QW3XR",
  "model": "wan-3-0",
  "source": "api",
  "created_at": "2026-11-08T09:00:00Z",
  "customer_resolution_deadline": "2026-11-09T09:00:00Z",
  "late_result_available": false,
  "metadata": {
    "client_reference": "my-unique-reference-1"
  },
  "status": "succeeded",
  "execution_status": "succeeded",
  "delivery_status": "ready",
  "billing_status": "settled",
  "version": 4,
  "price": {
    "unit": "credit",
    "estimated": "50.000",
    "reserved": "0.000",
    "charged": "50.000",
    "refunded": "0.000"
  },
  "allowed_actions": [],
  "closed_at": "2026-11-08T09:01:31Z",
  "error": null,
  "result": {
    "asset_id": "ast_01JD8Z9M2C4V",
    "outputs": [
      {
        "index": 0,
        "asset_id": "ast_01JD8Z9M2C4V",
        "content_type": "video/mp4"
      }
    ]
  }
}