Wan 3.0 All-in-One Video Generation
curl --request POST \
--url https://toapis.com/v1/videos/generations \
--header 'Authorization: <authorization>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"prompt": "<string>",
"duration": 123,
"ratio": "<string>",
"resolution": "<string>",
"audio": true,
"watermark": true,
"seed": 123,
"image_with_roles": [
{}
],
"reference_images": [
"<string>"
],
"video_list": [
{}
],
"audio_with_roles": [
{}
],
"metadata": {}
}
'import requests
url = "https://toapis.com/v1/videos/generations"
payload = {
"model": "<string>",
"prompt": "<string>",
"duration": 123,
"ratio": "<string>",
"resolution": "<string>",
"audio": True,
"watermark": True,
"seed": 123,
"image_with_roles": [{}],
"reference_images": ["<string>"],
"video_list": [{}],
"audio_with_roles": [{}],
"metadata": {}
}
headers = {
"Authorization": "<authorization>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: '<string>',
prompt: '<string>',
duration: 123,
ratio: '<string>',
resolution: '<string>',
audio: true,
watermark: true,
seed: 123,
image_with_roles: [{}],
reference_images: ['<string>'],
video_list: [{}],
audio_with_roles: [{}],
metadata: {}
})
};
fetch('https://toapis.com/v1/videos/generations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://toapis.com/v1/videos/generations",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => '<string>',
'prompt' => '<string>',
'duration' => 123,
'ratio' => '<string>',
'resolution' => '<string>',
'audio' => true,
'watermark' => true,
'seed' => 123,
'image_with_roles' => [
[
]
],
'reference_images' => [
'<string>'
],
'video_list' => [
[
]
],
'audio_with_roles' => [
[
]
],
'metadata' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://toapis.com/v1/videos/generations"
payload := strings.NewReader("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"duration\": 123,\n \"ratio\": \"<string>\",\n \"resolution\": \"<string>\",\n \"audio\": true,\n \"watermark\": true,\n \"seed\": 123,\n \"image_with_roles\": [\n {}\n ],\n \"reference_images\": [\n \"<string>\"\n ],\n \"video_list\": [\n {}\n ],\n \"audio_with_roles\": [\n {}\n ],\n \"metadata\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://toapis.com/v1/videos/generations")
.header("Authorization", "<authorization>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"duration\": 123,\n \"ratio\": \"<string>\",\n \"resolution\": \"<string>\",\n \"audio\": true,\n \"watermark\": true,\n \"seed\": 123,\n \"image_with_roles\": [\n {}\n ],\n \"reference_images\": [\n \"<string>\"\n ],\n \"video_list\": [\n {}\n ],\n \"audio_with_roles\": [\n {}\n ],\n \"metadata\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://toapis.com/v1/videos/generations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"duration\": 123,\n \"ratio\": \"<string>\",\n \"resolution\": \"<string>\",\n \"audio\": true,\n \"watermark\": true,\n \"seed\": 123,\n \"image_with_roles\": [\n {}\n ],\n \"reference_images\": [\n \"<string>\"\n ],\n \"video_list\": [\n {}\n ],\n \"audio_with_roles\": [\n {}\n ],\n \"metadata\": {}\n}"
response = http.request(request)
puts response.read_body{
"id": "tsk_vid_xxx",
"object": "generation.task",
"model": "wan3.0-video",
"status": "in_progress",
"progress": 10,
"created_at": 1781577600
}
Wan 3.0
Wan 3.0 All-in-One Video Generation
Generate videos with the Wan 3.0 All-in-One model — supports text-to-video, first/last-frame control, and multimodal references including images, video, and audio
POST
/
v1
/
videos
/
generations
Wan 3.0 All-in-One Video Generation
curl --request POST \
--url https://toapis.com/v1/videos/generations \
--header 'Authorization: <authorization>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"prompt": "<string>",
"duration": 123,
"ratio": "<string>",
"resolution": "<string>",
"audio": true,
"watermark": true,
"seed": 123,
"image_with_roles": [
{}
],
"reference_images": [
"<string>"
],
"video_list": [
{}
],
"audio_with_roles": [
{}
],
"metadata": {}
}
'import requests
url = "https://toapis.com/v1/videos/generations"
payload = {
"model": "<string>",
"prompt": "<string>",
"duration": 123,
"ratio": "<string>",
"resolution": "<string>",
"audio": True,
"watermark": True,
"seed": 123,
"image_with_roles": [{}],
"reference_images": ["<string>"],
"video_list": [{}],
"audio_with_roles": [{}],
"metadata": {}
}
headers = {
"Authorization": "<authorization>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: '<string>',
prompt: '<string>',
duration: 123,
ratio: '<string>',
resolution: '<string>',
audio: true,
watermark: true,
seed: 123,
image_with_roles: [{}],
reference_images: ['<string>'],
video_list: [{}],
audio_with_roles: [{}],
metadata: {}
})
};
fetch('https://toapis.com/v1/videos/generations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://toapis.com/v1/videos/generations",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => '<string>',
'prompt' => '<string>',
'duration' => 123,
'ratio' => '<string>',
'resolution' => '<string>',
'audio' => true,
'watermark' => true,
'seed' => 123,
'image_with_roles' => [
[
]
],
'reference_images' => [
'<string>'
],
'video_list' => [
[
]
],
'audio_with_roles' => [
[
]
],
'metadata' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://toapis.com/v1/videos/generations"
payload := strings.NewReader("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"duration\": 123,\n \"ratio\": \"<string>\",\n \"resolution\": \"<string>\",\n \"audio\": true,\n \"watermark\": true,\n \"seed\": 123,\n \"image_with_roles\": [\n {}\n ],\n \"reference_images\": [\n \"<string>\"\n ],\n \"video_list\": [\n {}\n ],\n \"audio_with_roles\": [\n {}\n ],\n \"metadata\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://toapis.com/v1/videos/generations")
.header("Authorization", "<authorization>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"duration\": 123,\n \"ratio\": \"<string>\",\n \"resolution\": \"<string>\",\n \"audio\": true,\n \"watermark\": true,\n \"seed\": 123,\n \"image_with_roles\": [\n {}\n ],\n \"reference_images\": [\n \"<string>\"\n ],\n \"video_list\": [\n {}\n ],\n \"audio_with_roles\": [\n {}\n ],\n \"metadata\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://toapis.com/v1/videos/generations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"duration\": 123,\n \"ratio\": \"<string>\",\n \"resolution\": \"<string>\",\n \"audio\": true,\n \"watermark\": true,\n \"seed\": 123,\n \"image_with_roles\": [\n {}\n ],\n \"reference_images\": [\n \"<string>\"\n ],\n \"video_list\": [\n {}\n ],\n \"audio_with_roles\": [\n {}\n ],\n \"metadata\": {}\n}"
response = http.request(request)
puts response.read_body{
"id": "tsk_vid_xxx",
"object": "generation.task",
"model": "wan3.0-video",
"status": "in_progress",
"progress": 10,
"created_at": 1781577600
}
Note for users in mainland China: Please use
https://toapis.cn as the API endpoint (Base URL). Replace https://toapis.com with https://toapis.cn in the examples in this document.wan3.0-video. A single model supports the following generation modes:
- Text-to-video
- First-frame or first/last-frame control
- Joint generation with reference images, reference videos, and reference audio
- File or public web page references
First/last-frame mode and reference-asset mode are mutually exclusive.If the request contains
first_frame or last_frame, you cannot also pass reference images, reference videos, reference audio, files, or web links. Reference images, reference videos, and reference audio can be combined with each other.Authentication
string
required
Use Bearer Token authentication:
Authorization: Bearer YOUR_API_KEY
Request Parameters
string
default:"wan3.0-video"
required
Model name, fixed as
wan3.0-video.string
Description of the video content, subject motion, camera work, and sound. At least one of
prompt or media assets must be provided.When using multimodal references, you can write “image 1”, “video 1”, “audio 1” in the prompt, matching the array order.integer
default:"5"
Output duration, supports
2 to 30 seconds. Pass -1 for smart duration to let the model decide the output length automatically.string
default:"adaptive"
Output aspect ratio, supports:
adaptive, adapts to reference assets16:99:161:14:33:4
aspect_ratio can also be used. Do not pass both fields.string
default:"1080p"
Output resolution, supports
480p, 720p, and 1080p.boolean
default:true
Whether to generate audio. Enabled by default.
boolean
default:false
Whether to add a watermark. Disabled by default.
integer
Optional random seed. The same parameters and seed help reproduce similar results.
object[]
First/last-frame control array. Each item contains:
url: publicly accessible image URLrole:first_frameorlast_frame
last_frame requires first_frame to be provided as well.string[]
Array of reference image URLs, up to
10 images. Cannot be mixed with first/last frames in image_with_roles.object[]
Array of reference videos, up to
5 clips with a total duration not exceeding 15 seconds. Each item uses the following structure:{
"video_url": "https://example.com/reference.mp4"
}
object[]
Array of reference audio, up to
5 clips with a total duration not exceeding 15 seconds. Each item contains:url: publicly accessible audio URLrole: fixed asreference_audio
object
File or web page references are passed via
metadata.media.Show Show metadata.media structure
Show Show metadata.media structure
media is an array of objects, each containing type and url:- File:
{ "type": "file", "url": "https://example.com/brief.pdf" } - Web page:
{ "type": "link", "url": "https://example.com/article" }
Local images or videos must be uploaded first to obtain a public URL. Do not pass local file paths or base64 data directly in the generation request.
Asset Combination Rules
| Request content | Supported | Notes |
|---|---|---|
| Prompt only | Yes | Text-to-video |
| First frame only | Yes | First-frame control |
| First and last frame | Yes | Last frame cannot be used alone |
| Reference images and reference videos | Yes | Can be combined |
| Reference images, videos, and audio | Yes | Can be combined |
| First frame and reference video | No | First/last-frame mode and reference-asset mode are mutually exclusive |
| First/last frames and reference images | No | First/last-frame mode and reference-asset mode are mutually exclusive |
| File and web link | No | Mutually exclusive |
Wan 3.0 cannot mix first/last frames with reference assets/files/web pages in the same request.
Request Examples
Text-to-Video
curl --request POST \
--url https://toapis.com/v1/videos/generations \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"model": "wan3.0-video",
"prompt": "An orange cat running through the streets of Tokyo after rain, cinematic camera work",
"duration": 5,
"ratio": "16:9",
"resolution": "1080p",
"audio": true,
"watermark": false
}'
First/Last-Frame Video
curl --request POST \
--url https://toapis.com/v1/videos/generations \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"model": "wan3.0-video",
"prompt": "The camera pushes in naturally as the person transitions from standing to smiling and waving",
"duration": 8,
"ratio": "adaptive",
"resolution": "1080p",
"image_with_roles": [
{
"url": "https://example.com/first-frame.png",
"role": "first_frame"
},
{
"url": "https://example.com/last-frame.png",
"role": "last_frame"
}
]
}'
Reference-Video Generation
Do not passfirst_frame or last_frame in this request.
curl --request POST \
--url https://toapis.com/v1/videos/generations \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"model": "wan3.0-video",
"prompt": "Use the camera work and movements from video 1 to generate a new street dance video",
"duration": 10,
"ratio": "adaptive",
"resolution": "720p",
"audio": true,
"video_list": [
{
"video_url": "https://example.com/reference-video.mp4"
}
]
}'
Combined Image, Video, and Audio Reference
curl --request POST \
--url https://toapis.com/v1/videos/generations \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"model": "wan3.0-video",
"prompt": "Generate a video using the character from image 1, the motion from video 1, and the rhythm of audio 1",
"duration": 10,
"ratio": "16:9",
"resolution": "720p",
"audio": true,
"reference_images": [
"https://example.com/character.png"
],
"video_list": [
{
"video_url": "https://example.com/motion.mp4"
}
],
"audio_with_roles": [
{
"url": "https://example.com/music.mp3",
"role": "reference_audio"
}
]
}'
File Reference
curl --request POST \
--url https://toapis.com/v1/videos/generations \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"model": "wan3.0-video",
"prompt": "Generate a concise product introduction video based on the file content",
"duration": 10,
"ratio": "16:9",
"resolution": "1080p",
"metadata": {
"media": [
{
"type": "file",
"url": "https://example.com/product-brief.pdf"
}
]
}
}'
Response
string
Video task ID, used to query task status.
string
Object type, usually
generation.task.string
Model name used for this request.
string
Task status:
queued, in_progress, completed, or failed.integer
Task progress, ranging from
0 to 100.integer
Task creation timestamp.
{
"id": "tsk_vid_xxx",
"object": "generation.task",
"model": "wan3.0-video",
"status": "in_progress",
"progress": 10,
"created_at": 1781577600
}