Wan 3.0
Generate a video with sound from a prompt, first and last frames, or reference images, videos and audio, billed by the output length.
Wan 3.0 (product wan) generates a video from a prompt, a first frame (optionally with a last frame), or reference images, videos and audio. The output has sound by default. It comes in two variants.
mode | What it does |
|---|---|
text_to_video | Text to video: generated from a prompt alone. |
image_to_video | Image to video: from a first frame, optionally with a last frame. |
reference_to_video | Reference to video: a new video from reference images, videos and audio. |
Variants
Every task picks one with variant: standard or prime. Both take the same parameters and resolutions (480p, 720p, 1080p); prime costs more, see Pricing.
Create a task
https://api.nanoapi.ai/v1/tasksUse the shared create endpoint with model: "wan-3.0". It usually responds in under 1 second and the cost is frozen within a few seconds; the video usually takes 1–5 minutes. Get the result once the task has finished.
Headers
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer <API key>, see Authentication. |
Content-Type | Yes | application/json |
Idempotency-Key | No | A unique string for every new task, ideally a UUID (1–255 characters). See Preventing duplicate tasks. |
Body
| Parameter | Type | Required | Description |
|---|---|---|---|
model | string | Yes | wan-3.0. |
variant | string | Yes | standard or prime, see Variants. Sets the price. |
mode | string | Yes | text_to_video, image_to_video or reference_to_video. |
prompt | string | Yes | What the video shows, at most 8000 characters. Best written in English. Refer to the files as <<<image_1>>>, <<<video_1>>>, <<<audio_1>>>, see Referring to files. |
image_urls | string[] | Yes in image_to_video; optional in reference_to_video; not accepted by text_to_video | image_to_video: 1–2 images, the first frame and optionally the last frame. reference_to_video: up to 10 reference images. |
video_urls | string[] | reference_to_video only, optional | Up to 5 reference videos: each 1–15 seconds, together at most 15 seconds, and together plus duration at most 30 seconds. See Media. |
audio_urls | string[] | reference_to_video only, optional | Up to 5 reference audio files (mp3 or wav): each, and all of them together, at most 15 seconds. |
resolution | string | Yes | 480p, 720p or 1080p. Sets the price. |
aspect_ratio | string | Yes in text_to_video and reference_to_video; not accepted by image_to_video | text_to_video: 16:9, 9:16, 1:1, 4:3 or 3:4. reference_to_video: the same or auto, which follows the reference images and videos (with reference audio only, it gives 16:9). image_to_video follows the first frame. |
duration | integer | Yes | Output length in seconds, 2–30. It's what you pay for, see Pricing. With reference videos, at most 30 − the number of videos. |
generate_audio | boolean | No | Whether the output has sound, default true. Same price either way. |
enable_thinking | boolean | No | true has the model reason about the prompt before generating: closer to your description, but slower. Default false. |
webhook_url | string | No | Notified when the task succeeds or fails: https, up to 2048 characters, not a private, loopback or reserved address. See Webhooks. |
- Parameter checks: a parameter that breaks the mode's rules (for example
image_urlsoraspect_ratio: autowithtext_to_video,aspect_ratiowithimage_to_video, orreference_to_videowith no files) returns400 invalid_requestwithparamset to that parameter, and no task is created. So does any other parameter. See Errors. - Prompt: write it in English for the best results.
Response: 200 OK. data is the newly created task, with only these fields; each one is described in Create a task: Response. Keep data.id to get the result. The task can still fail after it's created (for example a file can't be downloaded), so go by what retrieving the task or the webhook tells you.
{
"code": 200,
"message": "success",
"data": {
"object": "task",
"id": "tk_01jbq5w8m2c4x7b0n3q6t9e1r5",
"model": "wan-3.0",
"status": "queued",
"error": null,
"created_at": "2026-11-11T08:30:00Z"
}
}Text to video
Generates the video from prompt alone.
standard, 720p, 16:9, 5 seconds:
curl https://api.nanoapi.ai/v1/tasks \
-H "Authorization: Bearer $NANOAPI_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 2a7e4c90-5b1d-4f36-8a2c-9d6e0b3f7a18" \
-d '{
"model": "wan-3.0",
"variant": "standard",
"mode": "text_to_video",
"prompt": "A golden retriever running along a beach at sunset, cinematic tracking shot",
"resolution": "720p",
"aspect_ratio": "16:9",
"duration": 5
}'Image to video
Starts the video from the first image in image_urls and, if you send a second one, ends on it; prompt says what happens in between. The aspect ratio follows the first frame, so aspect_ratio isn't accepted. Use two frames of the same orientation (both landscape or both portrait): with one landscape and one portrait, generation may fail.
prime, a first and a last frame, 1080p, 5 seconds:
curl https://api.nanoapi.ai/v1/tasks \
-H "Authorization: Bearer $NANOAPI_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 8c5b3e17-0d9a-4e62-b7f4-1a6c2e8d5b39" \
-d '{
"model": "wan-3.0",
"variant": "prime",
"mode": "image_to_video",
"image_urls": [
"https://example.com/first_frame.jpg",
"https://example.com/last_frame.jpg"
],
"prompt": "The woman turns around and walks toward the window, the camera follows her",
"resolution": "1080p",
"duration": 5
}'Reference to video
Puts the people or objects in your reference images into a new video, follows the moves or camera work in reference videos, or uses reference audio as the sound. Send at least one of image_urls, video_urls and audio_urls; reference audio alone is fine.
Reference images (image_urls) | Reference videos (video_urls) | Reference audio (audio_urls) | |
|---|---|---|---|
| Count | Up to 10 | Up to 5 | Up to 5 |
| Length | – | Each 1–15 seconds; together at most 15 seconds (with a duration over 15, at most 30 − duration) | Each, and all together, at most 15 seconds |
With reference videos, duration can be at most 30 − the number of videos. The other requirements are under Media.
A reference image, a reference video and background music, 480p, 5 seconds, aspect ratio auto (follows the image and video):
curl https://api.nanoapi.ai/v1/tasks \
-H "Authorization: Bearer $NANOAPI_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 5e0f8a26-3c7b-4d91-a4e8-6b2d9c1f0a73" \
-d '{
"model": "wan-3.0",
"variant": "standard",
"mode": "reference_to_video",
"image_urls": ["https://example.com/cat.jpg"],
"video_urls": ["https://example.com/camera_move.mp4"],
"audio_urls": ["https://example.com/music.mp3"],
"prompt": "The cat from <<<image_1>>> sits on the car hood, the camera moves like in <<<video_1>>>, with <<<audio_1>>> as the background sound",
"resolution": "480p",
"aspect_ratio": "auto",
"duration": 5
}'Get the result
A video usually takes 1–5 minutes: longer at higher resolutions and longer durations, and with enable_thinking. Once the task has finished (succeeded or failed), get the result either way:
- Webhook (recommended in production): if you passed
webhook_url, the full task is pushed to it once when the task finishes. See Webhooks. - Polling: call
GET /v1/tasks/{task_id}withdata.idat most once every 15 seconds untilstatusissucceededorfailed. Check several tasks at once withidsin List tasks.
| Field | Wan 3.0 |
|---|---|
outputs[0].url | The generated video, an mp4 (H.264, 30 fps; for example 1920×1080 at 1080p 16:9), with sound when generate_audio is true (the default). Kept for 15 days after the task finishes. |
outputs[0].preview_url | A silent, compressed copy for previews, at most 600 pixels wide; null if it couldn't be made (use url). See Outputs. |
billing.billed_seconds | The duration. |
input | The parameters you sent; the files, generate_audio and enable_thinking only if you sent them. |
On failure the frozen amount is returned in full and the reason is in data.error.type, see Errors. Every field is described in The task object.
Media
All media is passed as public http(s) URLs. There's no upload endpoint: host the files yourself. URLs are at most 4096 characters, must download directly and can't point to localhost or private, loopback or reserved addresses.
| Parameter | What it is | Modes |
|---|---|---|
image_urls | Images: a first and last frame (up to 2), or reference images (up to 10). | image_to_video, reference_to_video |
video_urls | Reference videos, up to 5. | reference_to_video |
audio_urls | Reference audio (mp3 or wav), up to 5. | reference_to_video |
The files must meet these requirements:
| Requirement | Otherwise the task fails with |
|---|---|
| Each reference video 1–15 seconds | video_too_short / video_too_long |
The reference videos together at most 15 seconds; with a duration over 15, at most 30 − duration seconds | video_too_long |
| Each reference video's aspect ratio within 2.5:1 | invalid_media |
| Each reference audio file, and all of them together, at most 15 seconds | invalid_media |
A file that can't be downloaded or read (corrupt, unsupported format) fails the task with invalid_media.
Wan 3.0 reads every file only after the task is submitted for generation, a few seconds after creation, once the cost has been frozen: none of the above is checked when the task is created. If a file can't be used, the frozen amount is returned in full. Keep every link reachable until the task finishes, including links that expire.
Referring to files in the prompt
In prompt | Refers to |
|---|---|
<<<image_1>>>, <<<image_2>>>, … | The images in image_urls, in order. |
<<<video_1>>>, <<<video_2>>>, … | The videos in video_urls, in order. |
<<<audio_1>>>, <<<audio_2>>>, … | The audio files in audio_urls, in order. |
Each kind is numbered on its own, starting from 1.
Pricing
cost = duration × price per second of the variant and resolutionLoading the current prices…
Billed seconds are the duration you ask for (2–30). Only variant and resolution change the price per second: the mode, reference images, videos and audio, sound in the output (generate_audio) and enable_thinking don't.
Example: the text-to-video request above (standard, 720p, 5 seconds) freezes 5 × the 720p price per second of standard and is charged the same when it succeeds; if it fails, all of it is returned. How freezing and charging work in general: Billing.
Loading the current prices…
The price is known from the request alone, so you can show it before submitting: read the current prices from GET /v1/products, one prices row per variant and resolution (the row's variant). Prices change, so don't hard-code them; billing.frozen on the retrieved task is what counts.
Errors
Errors and failure reasons specific to Wan 3.0. Every error of the create endpoint: Create a task → Errors; every failure reason: Failure reasons.
Create request errors: the request fails with an HTTP error and no task is created. param names the parameter.
| Status | error.type | When | What to do |
|---|---|---|---|
400 | invalid_request | A required parameter is missing (Field required), or variant, mode, resolution or duration isn't an allowed value (for example Input should be 'standard' or 'prime' for wan-3.0). | Send every required parameter with an allowed value, see Create a task. |
400 | invalid_request | aspect_ratio is missing in text_to_video or reference_to_video (aspect_ratio is required for mode text_to_video), sent with image_to_video (aspect_ratio is not allowed for mode image_to_video; the output follows the first frame), or isn't one the mode takes (auto with text_to_video: Input should be '16:9', '9:16', '1:1', '4:3' or '3:4' for mode text_to_video). | Fix aspect_ratio as the mode needs, see Create a task. |
400 | invalid_request | Files that break the mode's rules: files with text_to_video (image_urls is not allowed for mode text_to_video); image_to_video without image_urls, with more than 2 images, or with video_urls or audio_urls; reference_to_video with none of the three (param is image_urls, image_urls, video_urls or audio_urls is required for mode reference_to_video), or more than 10 images, 5 videos or 5 audio files. | Fix the parameter param names and send the request again. |
400 | invalid_request | duration is above 30 − the number of reference videos, with param "duration" (for example duration must be at most 29 with 1 reference video: the videos (at least 1 second each) plus duration must be at most 30 seconds). | Lower duration, or send fewer reference videos. |
400 | invalid_request | A parameter this model doesn't take (Extra inputs are not permitted). | Remove it. |
Other errors of the create endpoint (401, 402, 429 and so on): Create a task → Errors.
Task failures: the create request succeeded (200) and the task later turned failed. There's no HTTP status: the reason is the task's error.type, from retrieving the task or the webhook.
error.type | When | What to do |
|---|---|---|
insufficient_balance | Your available balance can't cover duration × the price per second. Within a few seconds of creating the task, nothing frozen. | Top up, then create the task again. |
spend_limit_exceeded | This task's cost would go over one of the key's spend limits. Within a few seconds of creating the task, nothing frozen. | Raise the limit in Console → API keys, or wait for it to reset, then create the task again. |
invalid_media | An image, video or audio file can't be downloaded or read (corrupt or an unsupported format), a reference video's aspect ratio is beyond 2.5:1, or a reference audio file is longer than 15 seconds (The audio duration must be at most 15 seconds.) or they add up to more (The total duration of the audio files must be at most 15 seconds.). Found when the files are downloaded, a few seconds after the task is submitted. | Replace the file error.message points to, or trim the audio, and create the task again. |
content_policy | The prompt or a file breaks the content policy: adult content, or a protected likeness or copyrighted material (for example a photo of a public figure). This includes files turned down by the model provider's moderation. Found when the task is submitted or while it's generated. | Resubmitting it as is fails again: change the prompt or the file. |
video_too_short | A reference video is shorter than 1 second. Found when the videos are downloaded, a few seconds after the task is submitted; started_at may be null. | Use reference videos of 1–15 seconds and create the task again. |
video_too_long | A reference video is longer than 15 seconds, or they add up to more (with a duration over 15: to more than 30 − duration seconds). Found when the videos are downloaded, a few seconds after the task is submitted; started_at may be null. | Trim the videos (or send fewer) and create the task again. |
generation_failed | Generation failed or timed out. | Create the task again later, or change the prompt or files. |
queue_timeout / internal_error | Not started within 30 minutes / an error on our side. | Create the task again later. |
error.message states the requirement, not your file's length; the messages are listed under Messages. Every failed task has its frozen amount returned in full and billing.charged "0.00": invalid_media, video_too_short and video_too_long happen after the cost is frozen, so billing.frozen keeps the frozen amount and refunded equals it.