Wan 3.0
Wan 3.0 API — up to 30 seconds from text, frames or reference media, with 480P through 4K output. API-key access only; ordinary keys use the NSFW channel.
Alibaba's all-in-one reference video model. Wan 3.0 generates up to 30 seconds in a single pass from text, images, video, audio, documents, or a public web page, at 480P through 4K — with an audio track by default. See current pricing on the model page.
API access and content filtering
This model is available only through an API key. Playground generation is disabled for all users, including administrators. Session-cookie requests are rejected before a task is created or credits are charged.
Ordinary API keys: content filtering is always disabled (NSFW channel).
content_filter and the legacy nsfw_checker field are ignored, including
true, false, other values, and omission.
Administrator-owned API keys: content_filter: true enables filtering
(non-NSFW channel); false disables it (NSFW channel). This exception depends
on the verified key owner, not a request parameter or an administrator's
website session. At 2K and 4K, filtering must be disabled.
For 2K or 4K, use the same model id. These resolutions do not support
file_url, link_url or watermark: true.
Quick example
curl https://reapi.ai/api/v1/videos/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "wan3.0-video",
"prompt": "A lighthouse keeper climbing a spiral staircase at dawn",
"resolution": "720P",
"size": "16:9",
"duration": 10
}'import requests
resp = requests.post(
"https://reapi.ai/api/v1/videos/generations",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"model": "wan3.0-video",
"prompt": "A lighthouse keeper climbing a spiral staircase at dawn",
"resolution": "720P",
"size": "16:9",
"duration": 10,
},
timeout=30,
)
print(resp.json())const r = await fetch("https://reapi.ai/api/v1/videos/generations", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "wan3.0-video",
prompt: "A lighthouse keeper climbing a spiral staircase at dawn",
resolution: "720P",
size: "16:9",
duration: 10,
}),
});
console.log(await r.json());package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
func main() {
body, _ := json.Marshal(map[string]any{
"model": "wan3.0-video",
"prompt": "A lighthouse keeper climbing a spiral staircase at dawn",
"resolution": "720P",
"size": "16:9",
"duration": 10,
})
req, _ := http.NewRequest("POST",
"https://reapi.ai/api/v1/videos/generations", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
fmt.Println(string(out))
}Authentication
Every call needs a Bearer token. Generate keys at reapi.ai/settings/apikeys.
Authorization: Bearer YOUR_API_KEYEndpoint
POST /api/v1/videos/generations
GET /api/v1/tasks/{id}Submission is async. The POST returns immediately with a task_id; the task
endpoint returns the same envelope until completion. Polling does not consume
credits. Generation typically takes 1–5 minutes, longer for long clips.
Modes
There is no mode field — the model id is always wan3.0-video and the mode
follows from which media fields you send:
| Mode | Trigger |
|---|---|
| Text-to-video | prompt alone |
| First-frame video | one image in the frame family |
| First + last frame | two images in image_urls, or image_with_roles with first_frame / last_frame |
| Multi-modal reference | reference images / video_urls / audio_urls / audio_url |
| Document to video | file_url (prompt optional) |
| Web page to video | link_url (prompt optional) |
Media families
Every media input belongs to one of two families, and the two cannot be mixed in one request:
| Family | Members | Meaning |
|---|---|---|
| Frame | first_frame, last_frame | Strict first / last frame of the clip |
| Reference | reference_image, reference video, reference audio, document, web page | The model interprets the content freely |
A bare image_urls array is assigned as follows:
- If
generation_typeis set, it decides (frameorreference). - Otherwise, if the request already carries reference media (
video_urls,audio_urls,audio_url,file_url,link_url), the images are reference images. - Otherwise they are frame images: the first becomes
first_frame, the secondlast_frame.
Use image_with_roles when you want explicit control.
Request body
| Field | Type | Default | Notes |
|---|---|---|---|
model | string | — | wan3.0-video. Required. |
prompt | string | — | Scene, motion, camera, story beats. Required unless a media input is present; max 20,000 characters. In reference mode you can address assets as 图1 / 视频1 / 音频1 — indices run within each media type. |
image_urls | string[] | — | Public image URLs. Frame family (max 2) or reference images (max 10) per the rules above. |
image_with_roles | object[] | — | { "url": string, "role": "first_frame" | "last_frame" | "reference_image" }. Max 1 first_frame and 1 last_frame. |
video_urls | string[] | — | Reference clips, max 5; 1–15 s each, 15 s total. |
audio_urls | string[] | — | Reference audio, max 5; 1–15 s each, 15 s total. |
audio_url | string | — | Single reference audio — the single-value form of audio_urls. |
file_url | string | — | One reference document: docx, doc, xlsx, xls, pptx, ppt, pdf, txt, key, pages, numbers, md. Max 100 MB, 50 pages. Mutually exclusive with link_url. |
link_url | string | — | One public, login-free web page. Mutually exclusive with file_url. |
generation_type | string | — | frame or reference — how bare image_urls are classified. |
size | string | adaptive | adaptive / 16:9 / 4:3 / 1:1 / 3:4 / 9:16. |
resolution | string | 1080P | 480P / 720P / 1080P / 2K / 4K. Case-insensitive. 2K and 4K do not support file_url, link_url or watermark: true. |
duration | integer | 5 | Output seconds, 2–30, or -1 to let the model choose the length. |
audio | boolean | true | Whether the output carries an audio track. Does not change the price. |
watermark | boolean | false | Watermark the output. |
seed | integer | — | Reproducibility seed, 0–2147483647. |
content_filter | boolean for admin keys; ignored otherwise | false for ordinary keys; true for admin keys | Ordinary keys always use NSFW. Admin keys: true enables filtering; false disables it. See Content filter below. |
No data: URIs. reAPI rejects base64 inputs platform-wide — every URL
field must be a public HTTP(S) URL. Upload to your own object storage (S3, R2,
OSS, …) and pass the URL.
Media limits
| Type | Limits |
|---|---|
| First / last frame | Max 1 each |
| Reference images | Max 10 |
| Reference video | Max 5 clips, 1–15 s each, 15 s total; mp4/mov; edge 240–4096 px, ratio ≤ 8:1, ≤ 100 MB |
| Reference audio | Max 5 clips, 1–15 s each, 15 s total; wav/mp3; ≤ 15 MB |
| Images | JPEG/JPG/PNG (no alpha) / BMP / WEBP; edge 240–8000 px, ratio ≤ 8:1, ≤ 20 MB |
| Documents | ≤ 100 MB, ≤ 50 pages |
| Web pages | Public, login-free URLs |
With reference video present, the total input video duration plus the output
duration must stay within 30 seconds — including when duration is -1.
Content filter
Ordinary API keys always use the NSFW channel. Both content_filter and
nsfw_checker are ignored, so sending true does not enable filtering.
Administrator-owned API keys can set content_filter to a boolean:
| Value | Administrator API behavior |
|---|---|
true | Filtering enabled; available at 480P, 720P and 1080P. |
false | Filtering disabled; available at all supported resolutions. |
| Omitted | Defaults to true, preserving this model's existing behavior. |
For administrator keys, the legacy boolean nsfw_checker remains accepted;
content_filter takes precedence when both are present. Invalid non-boolean
values are rejected. 2K and 4K with filtering enabled are rejected before
credits are charged. The effective setting is preserved on every fallback,
and the filter choice does not change the public price.
Administrator key permissions are cached for up to 5 minutes. Role changes may take that long to affect requests.
Playground generation is disabled. Use Authorization: Bearer YOUR_API_KEY;
a website session cookie cannot submit this model, even for administrators.
Response envelope
Submit and poll share the same shape — only status and output fill in over
time.
{
"id": "task_018f5a3a1b6e7d9f8c2b4d6e8f0a2c4e",
"model": "wan3.0-video",
"status": "completed",
"created_at": 1735000000,
"output": {
"video_urls": ["https://cdn.reapi.ai/media/tasks/.../0.mp4"]
},
"error": null
}Poll GET /api/v1/tasks/{id} (see the Tasks reference)
until status === "completed". output.video_urls holds the generated MP4
URL.
Pricing
Billed per billable second, scaled by resolution. The mode does not change
the rate, and audio: true costs the same as audio: false.
billable_seconds = reference_video_seconds + duration
credits = ceil(per_second_usd × billable_seconds × 1000)where 1 credit = $0.001. Current per-second rates for each resolution tier
are on the model page — that table is
dynamic and always reflects the live rate. Failed jobs are refunded
automatically.
Three things drive the bill more than anything else:
- Resolution. Omitting
resolutiongenerates and bills at1080P. Pass480Por720Pexplicitly when cost matters. - Reference video. Every clip in
video_urlsis processed as well as generated, so its own length is billable on top ofduration. reAPI measures the clips server-side at submit time, and their combined length withdurationis capped at 30 seconds. A 6-second reference clip withduration: 8bills 14 seconds. Reference images, audio, documents and web pages carry no billable length — only video does. A clip reAPI cannot read is rejected rather than billed as zero. duration: -1. The model chooses the length, so the final second count is not knowable at submit time. reAPI charges the 30-second ceiling for these requests. Pass an explicitdurationwhenever you can.
Errors
Invalid combinations are rejected before any generation is billed.
| Code | When |
|---|---|
400 invalid request | Frame and reference media mixed; both file_url and link_url; duration outside 2–30 and not -1; unsupported resolution; more than 10 reference images; neither prompt nor media |
401 unauthorized | Missing or invalid API key |
402 insufficient credits | Balance below the estimated charge |
429 rate limited | Too many requests |
Full catalog: Errors.
Tips
- Keep the frame family and the reference family apart. If you want a specific still to open the clip and a character carried across shots, the frame role wins — send the character as the first frame, not as a reference image.
generation_typeis worth setting explicitly wheneverimage_urlsis present alongside any other media. The inference rules are well-defined, but a stated role is easier to reason about six months later.- In reference mode, name the assets in the prompt (
图1,视频1,音频1). Indices count within each media type, not across all of them. sizeonly frames the output; with a first-frame image the source aspect ratio dominates the result.- Long clips take proportionally longer. A 30-second 1080P request can sit well past the 5-minute mark — set your poll timeout accordingly.