Wan 3.0 - Video
curl --request POST \
--url https://whollyapi.com/api/v1/jobs/createTask \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"input": {
"prompt": "<string>",
"first_frame_url": "<string>",
"last_frame_url": "<string>",
"reference_video_urls": [
"<string>"
],
"reference_image_urls": [
"<string>"
],
"reference_audio_urls": [
"<string>"
],
"reference_file_urls": [
"<string>"
],
"reference_link_urls": [
"<string>"
],
"resolution": "<string>",
"aspect_ratio": "<string>",
"duration": 123,
"audio": true,
"seed": 123
}
}
'import requests
url = "https://whollyapi.com/api/v1/jobs/createTask"
payload = {
"model": "<string>",
"input": {
"prompt": "<string>",
"first_frame_url": "<string>",
"last_frame_url": "<string>",
"reference_video_urls": ["<string>"],
"reference_image_urls": ["<string>"],
"reference_audio_urls": ["<string>"],
"reference_file_urls": ["<string>"],
"reference_link_urls": ["<string>"],
"resolution": "<string>",
"aspect_ratio": "<string>",
"duration": 123,
"audio": True,
"seed": 123
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: '<string>',
input: {
prompt: '<string>',
first_frame_url: '<string>',
last_frame_url: '<string>',
reference_video_urls: ['<string>'],
reference_image_urls: ['<string>'],
reference_audio_urls: ['<string>'],
reference_file_urls: ['<string>'],
reference_link_urls: ['<string>'],
resolution: '<string>',
aspect_ratio: '<string>',
duration: 123,
audio: true,
seed: 123
}
})
};
fetch('https://whollyapi.com/api/v1/jobs/createTask', 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://whollyapi.com/api/v1/jobs/createTask",
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>',
'input' => [
'prompt' => '<string>',
'first_frame_url' => '<string>',
'last_frame_url' => '<string>',
'reference_video_urls' => [
'<string>'
],
'reference_image_urls' => [
'<string>'
],
'reference_audio_urls' => [
'<string>'
],
'reference_file_urls' => [
'<string>'
],
'reference_link_urls' => [
'<string>'
],
'resolution' => '<string>',
'aspect_ratio' => '<string>',
'duration' => 123,
'audio' => true,
'seed' => 123
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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://whollyapi.com/api/v1/jobs/createTask"
payload := strings.NewReader("{\n \"model\": \"<string>\",\n \"input\": {\n \"prompt\": \"<string>\",\n \"first_frame_url\": \"<string>\",\n \"last_frame_url\": \"<string>\",\n \"reference_video_urls\": [\n \"<string>\"\n ],\n \"reference_image_urls\": [\n \"<string>\"\n ],\n \"reference_audio_urls\": [\n \"<string>\"\n ],\n \"reference_file_urls\": [\n \"<string>\"\n ],\n \"reference_link_urls\": [\n \"<string>\"\n ],\n \"resolution\": \"<string>\",\n \"aspect_ratio\": \"<string>\",\n \"duration\": 123,\n \"audio\": true,\n \"seed\": 123\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://whollyapi.com/api/v1/jobs/createTask")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"<string>\",\n \"input\": {\n \"prompt\": \"<string>\",\n \"first_frame_url\": \"<string>\",\n \"last_frame_url\": \"<string>\",\n \"reference_video_urls\": [\n \"<string>\"\n ],\n \"reference_image_urls\": [\n \"<string>\"\n ],\n \"reference_audio_urls\": [\n \"<string>\"\n ],\n \"reference_file_urls\": [\n \"<string>\"\n ],\n \"reference_link_urls\": [\n \"<string>\"\n ],\n \"resolution\": \"<string>\",\n \"aspect_ratio\": \"<string>\",\n \"duration\": 123,\n \"audio\": true,\n \"seed\": 123\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://whollyapi.com/api/v1/jobs/createTask")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"<string>\",\n \"input\": {\n \"prompt\": \"<string>\",\n \"first_frame_url\": \"<string>\",\n \"last_frame_url\": \"<string>\",\n \"reference_video_urls\": [\n \"<string>\"\n ],\n \"reference_image_urls\": [\n \"<string>\"\n ],\n \"reference_audio_urls\": [\n \"<string>\"\n ],\n \"reference_file_urls\": [\n \"<string>\"\n ],\n \"reference_link_urls\": [\n \"<string>\"\n ],\n \"resolution\": \"<string>\",\n \"aspect_ratio\": \"<string>\",\n \"duration\": 123,\n \"audio\": true,\n \"seed\": 123\n }\n}"
response = http.request(request)
puts response.read_body{
"code": 123,
"msg": "<string>",
"data": {
"taskId": "<string>"
}
}Wan
Wan 3.0 - Video
Generate videos with Wan 3.0 using text, frames, reference media, files, or public webpages.
POST
/
api
/
v1
/
jobs
/
createTask
Wan 3.0 - Video
curl --request POST \
--url https://whollyapi.com/api/v1/jobs/createTask \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"input": {
"prompt": "<string>",
"first_frame_url": "<string>",
"last_frame_url": "<string>",
"reference_video_urls": [
"<string>"
],
"reference_image_urls": [
"<string>"
],
"reference_audio_urls": [
"<string>"
],
"reference_file_urls": [
"<string>"
],
"reference_link_urls": [
"<string>"
],
"resolution": "<string>",
"aspect_ratio": "<string>",
"duration": 123,
"audio": true,
"seed": 123
}
}
'import requests
url = "https://whollyapi.com/api/v1/jobs/createTask"
payload = {
"model": "<string>",
"input": {
"prompt": "<string>",
"first_frame_url": "<string>",
"last_frame_url": "<string>",
"reference_video_urls": ["<string>"],
"reference_image_urls": ["<string>"],
"reference_audio_urls": ["<string>"],
"reference_file_urls": ["<string>"],
"reference_link_urls": ["<string>"],
"resolution": "<string>",
"aspect_ratio": "<string>",
"duration": 123,
"audio": True,
"seed": 123
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: '<string>',
input: {
prompt: '<string>',
first_frame_url: '<string>',
last_frame_url: '<string>',
reference_video_urls: ['<string>'],
reference_image_urls: ['<string>'],
reference_audio_urls: ['<string>'],
reference_file_urls: ['<string>'],
reference_link_urls: ['<string>'],
resolution: '<string>',
aspect_ratio: '<string>',
duration: 123,
audio: true,
seed: 123
}
})
};
fetch('https://whollyapi.com/api/v1/jobs/createTask', 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://whollyapi.com/api/v1/jobs/createTask",
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>',
'input' => [
'prompt' => '<string>',
'first_frame_url' => '<string>',
'last_frame_url' => '<string>',
'reference_video_urls' => [
'<string>'
],
'reference_image_urls' => [
'<string>'
],
'reference_audio_urls' => [
'<string>'
],
'reference_file_urls' => [
'<string>'
],
'reference_link_urls' => [
'<string>'
],
'resolution' => '<string>',
'aspect_ratio' => '<string>',
'duration' => 123,
'audio' => true,
'seed' => 123
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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://whollyapi.com/api/v1/jobs/createTask"
payload := strings.NewReader("{\n \"model\": \"<string>\",\n \"input\": {\n \"prompt\": \"<string>\",\n \"first_frame_url\": \"<string>\",\n \"last_frame_url\": \"<string>\",\n \"reference_video_urls\": [\n \"<string>\"\n ],\n \"reference_image_urls\": [\n \"<string>\"\n ],\n \"reference_audio_urls\": [\n \"<string>\"\n ],\n \"reference_file_urls\": [\n \"<string>\"\n ],\n \"reference_link_urls\": [\n \"<string>\"\n ],\n \"resolution\": \"<string>\",\n \"aspect_ratio\": \"<string>\",\n \"duration\": 123,\n \"audio\": true,\n \"seed\": 123\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://whollyapi.com/api/v1/jobs/createTask")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"<string>\",\n \"input\": {\n \"prompt\": \"<string>\",\n \"first_frame_url\": \"<string>\",\n \"last_frame_url\": \"<string>\",\n \"reference_video_urls\": [\n \"<string>\"\n ],\n \"reference_image_urls\": [\n \"<string>\"\n ],\n \"reference_audio_urls\": [\n \"<string>\"\n ],\n \"reference_file_urls\": [\n \"<string>\"\n ],\n \"reference_link_urls\": [\n \"<string>\"\n ],\n \"resolution\": \"<string>\",\n \"aspect_ratio\": \"<string>\",\n \"duration\": 123,\n \"audio\": true,\n \"seed\": 123\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://whollyapi.com/api/v1/jobs/createTask")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"<string>\",\n \"input\": {\n \"prompt\": \"<string>\",\n \"first_frame_url\": \"<string>\",\n \"last_frame_url\": \"<string>\",\n \"reference_video_urls\": [\n \"<string>\"\n ],\n \"reference_image_urls\": [\n \"<string>\"\n ],\n \"reference_audio_urls\": [\n \"<string>\"\n ],\n \"reference_file_urls\": [\n \"<string>\"\n ],\n \"reference_link_urls\": [\n \"<string>\"\n ],\n \"resolution\": \"<string>\",\n \"aspect_ratio\": \"<string>\",\n \"duration\": 123,\n \"audio\": true,\n \"seed\": 123\n }\n}"
response = http.request(request)
puts response.read_body{
"code": 123,
"msg": "<string>",
"data": {
"taskId": "<string>"
}
}Generate videos with the Wan 3.0 standard video model.
Supported generation modes:
- Text to video
- First-frame to video
- First-and-last-frame to video
- Reference to video
- File to video
- Link to video
Create a Video Generation Task
POST /api/v1/jobs/createTask
Authentication
All API requests require a Bearer Token.Authorization: Bearer YOUR_API_KEY
Model
Use:wan/3-0-video
Text to Video
{
"model": "wan/3-0-video",
"input": {
"prompt": "Describe a video you want to generate.",
"resolution": "480P",
"aspect_ratio": "adaptive",
"duration": 5,
"audio": true
}
}
First Frame to Video
{
"model": "wan/3-0-video",
"input": {
"prompt": "Describe a video you want to generate.",
"first_frame_url": "https://example.com/first-frame.png",
"resolution": "720P",
"aspect_ratio": "adaptive",
"duration": 5,
"audio": true
}
}
First and Last Frames to Video
{
"model": "wan/3-0-video",
"input": {
"prompt": "Describe a video you want to generate.",
"first_frame_url": "https://example.com/first-frame.jpg",
"last_frame_url": "https://example.com/last-frame.jpg",
"resolution": "1080P",
"aspect_ratio": "adaptive",
"duration": 8,
"audio": true,
"seed": 12345
}
}
Reference to Video
Reference media can include images, videos, and audio. In the prompt, reference items correspond to their array order:Image1,Image2, …Video1,Video2, …Audio1,Audio2, …
{
"model": "wan/3-0-video",
"input": {
"prompt": "Video 1 holds image 3 and is playing a song on the chair in image 4. Image 1 holds image 2 and passes through Video 1, placing image 2 on the table.",
"reference_image_urls": [
"https://example.com/character.jpg",
"https://example.com/object.png",
"https://example.com/prop.png",
"https://example.com/background.png"
],
"reference_video_urls": [
"https://example.com/role.mp4"
],
"reference_audio_urls": [
"https://example.com/voice.mp3"
],
"resolution": "720P",
"aspect_ratio": "adaptive",
"duration": 5,
"audio": true
}
}
File to Video
{
"model": "wan/3-0-video",
"input": {
"prompt": "Based on this product presentation PPT, create an advertisement video for an ultra-minimalist tech-style smart glasses.",
"reference_file_urls": [
"https://example.com/product.pptx"
],
"resolution": "480P",
"aspect_ratio": "adaptive",
"duration": 10,
"audio": true
}
}
Link to Video
The referenced webpage must be publicly accessible and must not require login.{
"model": "wan/3-0-video",
"input": {
"prompt": "Based on the content of this public webpage, create a concise product introduction video.",
"reference_link_urls": [
"https://example.com/article"
],
"resolution": "720P",
"aspect_ratio": "16:9",
"duration": 8,
"audio": true
}
}
Parameters
string
required
Must be
wan/3-0-video.input Parameters
object
required
The
input object contains the parameters used to generate the video.string
Use
prompt to describe the video motion you want to generate in English or Chinese.Note: Required for text-to-video.Maximum length: 20,000 characters.string
Use the provided image URL as the first frame.
The
Each side: 240–8,000 px.
Aspect ratio : ≤ 8:1
The
first_frame_url must contain the URL of an uploaded image. The value must be an uploaded file URL, not the file content itself.Note: first_frame_url cannot be used together with reference_*_urls according to the source specification.Supported image types:image/jpegimage/pngimage/webpimage/bmp
Each side: 240–8,000 px.
Aspect ratio : ≤ 8:1
string
Use the provided image URL as the last frame.
The
Each side: 240–8,000 px.
Aspect ratio : ≤ 8:1
The
last_frame_url must contain the URL of an uploaded image. The value must be an uploaded file URL, not the file content itself.Note: Cannot be provided together with reference_*_urlsSupported image types:image/jpegimage/pngimage/webpimage/bmp
Each side: 240–8,000 px.
Aspect ratio : ≤ 8:1
string[]
Reference videos for the all-purpose reference mode.
The
Maximum each file size: 100 MB
The
reference_video_urls must contain the URLs of an uploaded videos. The value must be an uploaded file URL, not the file content itself.Note: The input video duration + duration must not exceed 30 seconds.Supported videos types:.mp4.mov
1 to 15 seconds.Maximum reference videos: 5 Maximum each file size: 100 MB
string[]
Reference images for the all-purpose reference mode.
The
Maximum file size: 20 MB
Aspect ratio : ≤ 8:1
The
reference_image_urls must contain the URLs of an uploaded images. The value must be an uploaded file URL, not the file content itself.Note: Cannot be provided together with the first-frame/last-frame parametersSupported image types:image/jpegimage/pngimage/webpimage/bmp
Maximum file size: 20 MB
Aspect ratio : ≤ 8:1
string[]
Reference audio for the all-purpose reference mode.
The
Maximum each file size: 15 MB
The
reference_audio_urls must contain the URLs of an uploaded audios. The value must be an uploaded file URL, not the file content itself.Note: The source recommends pairing audio with an image or video rather than using audio alone.Supported audios types:.wav.mp3
1 to 15 seconds.Maximum reference audios: 5 Maximum each file size: 15 MB
string[]
File-to-video generation.
The
The
reference_file_urls must contain the URLs of an uploaded file. The value must be an uploaded file URL, not the file content itself.Note: reference_file_urls cannot be combined with reference_link_urls or the first-frame/last-frame parameters.- Maximum 1 file.
- Maximum size: 100 MB.
- Supported formats: DOCX, DOC, XLSX, XLS, PPTX, PPT, PDF, TXT, KEY, PAGES, NUMBERS, MD.
- PDF, DOCX, PPT, KEY, PAGES, and similar documents: up to 50 pages.
string[]
Link-to-video generation.
The
The
reference_link_urls must be publicly accessible webpage that does not require login.Note: reference_link_urls cannot be combined with reference_file_urls or the first-frame/last-frame parameters.Maximum file: 1string
default:"1080P"
Specify the resolution of the output video.Supported output resolutions:
480P720P1080P
1080Pstring
default:"adaptive"
Applies to multi-image generation. In single-image mode, video dimensions follow the source image dimensions.Supported values:
3:4, 4:3, 1:1, 16:9, 9:16, adaptive.Default: adaptivenumber
Generated video duration in seconds.Type:
Supported range without video input:
Supported range with reference videos: input video duration + output duration ≤ 30, in one-second steps.
Default:
integer Supported range without video input:
2–30, in one-second steps. Supported range with reference videos: input video duration + output duration ≤ 30, in one-second steps.
Default:
5boolean
default:"true"
When enabled, the output video includes an audio track.Default:
truenumber
The seed can be used to reproduce results.
- Minimum:
0 - Maximum:
2147483647 - If omitted, a random seed is used.
Note: The source schema requiresmodelandinputat the top level. It describespromptas required for text-to-video, but does not mark it as required in theinputschema.
Successful Response
number
Response status code.
string
Response message. Contains the error description when the request fails.Example:
successobject
required
The task data object containing task id.
string
required
The unique identifier for this task.Example:
task_123456Query Task Status
After submitting a task, use the unified query endpoint to check the task progress and retrieve the generated results.Get Task Details
Check task status, monitor generation progress, and retrieve results.
Error Response
{
"code": 500,
"msg": "Server Error - An unexpected error occurred while processing the request",
"data": null
}
Response Codes
| Code | Meaning |
|---|---|
200 | Success — the request was successfully processed. |
401 | Unauthorized — authentication credentials are missing or invalid. |
402 | Insufficient Credits — the account does not have enough credits. |
404 | Not Found — the requested resource or interface does not exist. |
408 | Upstream service issue — no result has been returned for over 10 minutes. |
422 | Validation Error — request parameters failed validation. |
429 | Rate Limited — request frequency limit has been exceeded. |
433 | Request Limit — sub-key usage exceeded the limit. |
455 | Service Unavailable — system is undergoing maintenance. |
500 | Server Error — an unexpected error occurred while processing the request. |
501 | Generation Failed — content generation failed. |
505 | Feature Disabled — the requested feature is disabled. |
