Wan 3.0 Prime Video API
Wan 3.0 Prime exposes text-to-video, first/last-frame animation, multimodal reference generation, document understanding, and public web-page input through wan-3.0-video-prime.
Pricing
| Resolution | Credits per billable second | 5-second text-only request |
|---|---|---|
480p | 18 | 90 credits |
720p | 36 | 180 credits |
1080p | 72 | 360 credits |
For a fixed duration, billable seconds equal the requested output duration without reference video. With video_urls, billing is:
(detected input video seconds + requested output seconds) × resolution rate
Images, audio, files, and web pages do not add input-video seconds. For example, 4.5 seconds of reference video plus 5 seconds of 720p output costs (4.5 + 5) × 36 = 342 credits.
Automatic duration (duration=-1)
Wan 3.0 Prime supports automatic output duration. The platform pre-charges 30 total billable seconds × the selected model and resolution rate. This already includes reference-video input; its duration is not added again.
| Resolution | Automatic-duration pre-charge |
|---|---|
480p | 540 credits |
720p | 1,080 credits |
1080p | 2,160 credits |
Create a task
POST https://api.aivideoapi.ai/v1/videos/generations
Request body
| Field | Type | Required | Description |
|---|---|---|---|
model | string | Yes | wan-3.0-video-prime |
input | object | Yes | Prompt, media, and output controls |
callback_url | string | No | Public callback URL for terminal task notifications |
input.prompt and the media fields are optional individually, but at least one prompt or media value is required.
Input fields
| Field | Type | Default | Description |
|---|---|---|---|
prompt | string | — | Up to 20,000 characters |
first_frame_url | string | — | Public HTTP(S) first-frame image URL |
last_frame_url | string | — | Public HTTP(S) last-frame URL; requires first_frame_url |
image_urls | string[] | [] | Up to 10 reference images |
video_urls | string[] | [] | Up to 5 MP4/MOV references; each 1–15s, 15s total |
audio_urls | string[] | [] | Up to 5 MP3/WAV references; each 1–15s, 15s total |
file_url | string | — | One public document URL |
link_url | string | — | One public, login-free web page URL |
resolution | string | 1080p | 480p, 720p, or 1080p |
aspect_ratio | string | adaptive | adaptive, 16:9, 4:3, 1:1, 3:4, or 9:16 |
duration | integer | 5 | -1 for automatic duration, or an integer from 2 to 30; numeric strings are not accepted |
audio | boolean | true | Include an audio track |
seed | integer | — | 0–2147483647 |
watermark | boolean | false | Add a watermark |
Only public HTTP(S) URLs are accepted. Base64 data, OSS URIs, credentials in URLs, localhost, and private network addresses are outside the public contract.
Mode and duration rules
- First/last-frame mode cannot be combined with
image_urls,video_urls,audio_urls,file_url, orlink_url. last_frame_urlcannot be sent withoutfirst_frame_url.file_urlandlink_urlare mutually exclusive.- Reference media remain in their array order. In prompts, images, videos, and audio are numbered independently.
- Input video duration plus output duration cannot exceed 30 seconds.
- Automatic
duration=-1pre-charges the 30-second total billable limit, then settles after success using actual duration.
Create response
HTTP 200 returns the platform task ID immediately. Use data.taskId with the task-query endpoint.
{
"code": 200,
"msg": "success",
"data": {
"taskId": "cbf6b69d-4f03-4817-8ed7-94c0292184a8"
}
}
Examples
Automatic duration
{
"model": "wan-3.0-video-prime",
"input": {
"prompt": "A cinematic journey through a city from sunrise to sunset",
"resolution": "720p",
"duration": -1
}
}
Text-to-video
curl -X POST https://api.aivideoapi.ai/v1/videos/generations \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"model": "wan-3.0-video-prime",
"callback_url": "https://your-server.com/webhook",
"input": {
"prompt": "A cat runs across a moonlit rooftop above a neon city, cinematic camera motion",
"resolution": "1080p",
"aspect_ratio": "16:9",
"duration": 5,
"audio": true
}
}'
First and last frames
{
"model": "wan-3.0-video-prime",
"input": {
"prompt": "The expression changes from a smile to laughter as warm light fills the room",
"first_frame_url": "https://example.com/first.jpg",
"last_frame_url": "https://example.com/last.jpg",
"duration": 6
}
}
Mixed references
{
"model": "wan-3.0-video-prime",
"input": {
"prompt": "Video 1 supplies the camera move, Image 1 supplies the character, and Audio 1 guides the music",
"image_urls": ["https://example.com/character.png"],
"video_urls": ["https://example.com/camera.mp4"],
"audio_urls": ["https://example.com/music.mp3"],
"resolution": "720p",
"duration": 5
}
}
Use file_url for a supported public document or link_url for a public page. Do not send both in one request.
Query task status
curl https://api.aivideoapi.ai/v1/tasks/{taskId} \
-H "Authorization: Bearer sk-your-api-key"
Task statuses are pending, processing, completed, and failed. Confirmed failures refund the pre-charge once. Successful automatic-duration tasks refund only an unused pre-charge difference during settlement; they never receive a failure refund. An expired upstream UNKNOWN record becomes a non-refundable failed task for manual reconciliation. Wan 3.0 Prime tasks do not support cancellation.
Pending response
{
"id": "cbf6b69d-4f03-4817-8ed7-94c0292184a8",
"status": "pending",
"model": "wan-3.0-video-prime",
"credits_consumed": 0,
"created_at": 1786330800,
"estimated_seconds": 300
}
Processing response
{
"id": "cbf6b69d-4f03-4817-8ed7-94c0292184a8",
"status": "processing",
"model": "wan-3.0-video-prime",
"credits_consumed": 0,
"created_at": 1786330800,
"progress": null
}
Completed response
{
"id": "cbf6b69d-4f03-4817-8ed7-94c0292184a8",
"status": "completed",
"model": "wan-3.0-video-prime",
"credits_consumed": 360,
"created_at": 1786330800,
"completed_at": 1786330928,
"output": {
"urls": [
"https://dashscope-result.oss-cn-beijing.aliyuncs.com/example.mp4"
],
"metadata": {
"usage": {
"duration": 5,
"input_video_duration": 0,
"output_video_duration": 5,
"video_count": 1,
"fps": 24,
"SR": 1080,
"ratio": "16:9"
}
}
},
"usage": {
"total_seconds": 5,
"input_seconds": 0,
"output_seconds": 5,
"video_count": 1,
"fps": 24,
"resolution": 1080,
"ratio": "16:9"
}
}
credits_consumed is 0 while the task is in progress and after a confirmed failure has been refunded. On success it contains the final charge after settlement, or the retained pre-charge if actual duration could not be verified. usage is returned on successful Wan 3.0 Prime tasks when the corresponding values are available. Callbacks use the same final charge as task queries.
Completed task with automatic duration
For a Wan 3.0 Prime 720p task submitted with duration=-1, a 4.5-second reference video and 5 seconds of actual output produce this response excerpt:
{
"status": "completed",
"model": "wan-3.0-video-prime",
"credits_consumed": 342,
"usage": {
"total_seconds": 9.5,
"input_seconds": 4.5,
"output_seconds": 5
}
}
With an account multiplier of 1, the task originally pre-charged 1,080 credits. The final charge is (4.5 + 5) × 36 = 342 credits, so 738 credits are automatically returned to the balance once. The refund amount is explained here for reconciliation; it is not a new field in the public response. Task queries and callbacks both report the same final credits_consumed of 342.
Failed response
{
"id": "cbf6b69d-4f03-4817-8ed7-94c0292184a8",
"status": "failed",
"model": "wan-3.0-video-prime",
"credits_consumed": 0,
"created_at": 1786330800,
"error": {
"code": "upstream_error",
"message": "Video generation failed"
}
}
For an expired upstream UNKNOWN record, the response is also failed, but credits_consumed retains the pre-charge because that state is not automatically refundable.
Successful upstream result URLs expire after approximately 24 hours. If your account has Bailian R2 mirroring enabled, the platform stores the result; otherwise download the provider URL promptly.
Callbacks
Set callback_url at the top level of the create-task request, alongside model and input. Use a publicly reachable HTTP(S) endpoint; HTTPS is recommended.
{
"model": "wan-3.0-video-prime",
"callback_url": "https://your-server.com/webhooks/wan",
"input": {
"prompt": "A cat runs across a moonlit rooftop above a neon city",
"resolution": "720p",
"duration": 5
}
}
The platform sends a JSON POST when the task reaches completed or failed. It does not send progress notifications for pending or processing.
Request headers
| Header | Value |
|---|---|
Content-Type | application/json |
X-Event | task.completed or task.failed |
X-Task-Id | The task ID, matching id in the body |
X-Timestamp | Delivery time as a Unix timestamp in seconds |
These headers identify the event but are not a signature or proof of the sender's identity. Before changing business state based on a notification, verify the task with an authenticated GET /v1/tasks/{taskId} request using your API Key.
Completed callback
For the 720p, 5-second text-to-video request above at the listed rate:
{
"id": "cbf6b69d-4f03-4817-8ed7-94c0292184a8",
"status": "completed",
"model": "wan-3.0-video-prime",
"credits_consumed": 180,
"created_at": 1786330800,
"completed_at": 1786330928,
"output": {
"urls": ["https://example.com/video.mp4"]
},
"usage": {
"total_seconds": 5,
"input_seconds": 0,
"output_seconds": 5
}
}
The body is the task object itself, without an event or data wrapper. See the task-query results above for the output and usage fields; usage and its values are optional when unavailable. For duration=-1, credits_consumed is the final amount and matches the task-query response.
Failed callback
A confirmed failure after the pre-charge has been refunded sends:
{
"id": "cbf6b69d-4f03-4817-8ed7-94c0292184a8",
"status": "failed",
"model": "wan-3.0-video-prime",
"credits_consumed": 0,
"created_at": 1786330800,
"error": {
"code": "upstream_error",
"message": "Video generation failed"
}
}
Failed callbacks omit output and completed_at. As described in the task-query results, a failure retained for manual reconciliation can still report the retained pre-charge in credits_consumed.
Acknowledgment and retries
After durably accepting the notification, return any HTTP 2xx status within 10 seconds, for example:
HTTP/1.1 204 No Content
The response body is ignored. Queue long-running work and process it asynchronously. Duplicate deliveries are possible, so make your handler idempotent using the combination of id and status.
For the request's callback_url, the delivery policy is:
| Attempt | Scheduled delivery |
|---|---|
| Initial | When the task reaches a terminal state |
| First retry | 3 minutes after the initial delivery fails |
| Second retry | 10 minutes after the first retry fails |
There are three attempts including the initial delivery. Network errors, timeouts, and non-2xx responses trigger retries. Retries run on a schedule, so actual delivery can be later than the listed delay.
Exhausting callback delivery attempts does not change the generation result. If a callback does not arrive, query GET /v1/tasks/{taskId} with your API Key to retrieve the task status and result.
See the callback guide for the common callback contract.
Error Codes
When a request fails, the API returns a JSON error response:
{
"error": {
"code": "insufficient_credits",
"message": "Your credit balance is too low. Please top up.",
"type": "billing_error"
}
}
Error Reference
| HTTP Status | Code | Type | Description |
|---|---|---|---|
| 400 | invalid_request | invalid_request_error | Missing or invalid parameters |
| 401 | invalid_api_key | authentication_error | API key is invalid, disabled, or deleted |
| 402 | insufficient_credits | billing_error | Credit balance too low, please top up |
| 403 | ip_not_allowed | permission_error | Request IP not in the key's allowlist |
| 404 | model_not_found | invalid_request_error | Model does not exist or is inactive |
| 404 | task_not_found | invalid_request_error | Task ID does not exist |
| 429 | rate_limit_exceeded | rate_limit_error | Too many requests, please slow down |
| 429 | spend_limit_exceeded | billing_error | Key spend limit reached (hourly/daily/total) |
| 500 | internal_error | api_error | Unexpected server error |
| 503 | upstream_error | upstream_error | Upstream AI provider returned an error |
Common Scenarios
invalid_request (400)
Returned when required fields are missing or invalid.
{
"error": {
"code": "invalid_request",
"message": "'model' is required.",
"type": "invalid_request_error"
}
}
insufficient_credits (402)
Your balance is too low. Check your balance with GET /v1/credits and top up in Dashboard > Billing.
invalid_api_key (401)
Possible causes:
- The key does not start with
sk- - The key has been disabled or deleted
- The user account has been banned
upstream_error (503)
The upstream AI provider returned an error. This may happen when:
- The input contains sensitive or prohibited content
- The provider is temporarily unavailable
- The request parameters are not supported by the provider
Credits are automatically refunded when a task fails due to upstream errors.