Wan 2.7 Video Generation
Use EasyRouter's unified API to call Alibaba Cloud's Wan 2.7 video generation model family — text-to-video, image-to-video, reference-to-video, and video editing.
Wan 2.7 is the latest-generation video creation model family from Alibaba Cloud Bailian, delivering cinematic 1080P quality, up to 15-second videos, multi-shot storytelling, and native audio synchronization. EasyRouter wraps the upstream DashScope async task API as a unified /v1/video/generations endpoint, covering four capabilities: text-to-video, image-to-video, reference-to-video, and video editing.
Wan 2.7 uses an async task-based API: submit a request, receive a task_id, poll for status, then download the video from data.result_url.
1. Supported Models
| Model | Capability | Required Media Input | Description |
|---|---|---|---|
wan2.7-t2v | Text-to-Video | — | Generate video from text prompt; supports multi-shot storytelling and audio sync |
wan2.7-i2v | Image-to-Video | 1 first-frame image | Generate video starting from a first-frame image |
wan2.7-r2v | Reference-to-Video | 1–9 reference images | Multi-image reference generation maintaining subject consistency; use [Image N] in prompt |
wan2.7-videoedit | Video Editing | 1 video + 0–3 reference images | Edit video via text instructions: style transfer, element replacement, local modification |
All 4 models share the same endpoint /v1/video/generations, distinguished only by the model field. Response structures are identical across all models.
2. Common Endpoints
2.1 Submit Task
POST /v1/video/generationsRequest Headers
| Header | Required | Description |
|---|---|---|
Authorization | ✓ | Bearer sk-YourApiKey |
Content-Type | ✓ | application/json |
Request Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
model | string | ✓ | Wan 2.7 model name (see table above) |
prompt | string | ✓ | Text prompt, max 5000 characters, Chinese and English supported |
resolution | string | — | Resolution tier: 720P / 1080P (default 720P). Recommended — aligns with the upstream DashScope API field name |
size | string | — | Alias for resolution, kept for backward compatibility. If both are provided, resolution takes precedence. New integrations should use resolution instead |
duration | int | — | Video duration in seconds. t2v/i2v: 2~15, default 5; r2v with reference video: 2~10. Ignored by videoedit — duration follows input video (max 15s) |
input_reference | string | i2v only | i2v only: publicly accessible first-frame image URL |
images | array | videoedit only | videoedit only: media URL array — first element is the source video (MP4/MOV), remaining elements are reference images (optional, max 3) |
metadata | object | — | Wan 2.7-specific parameters container, see Section 3 |
The images field is currently in a transition period: before the feature release, pass media via metadata.input.media with explicit type fields; after release, the system automatically infers media type from URL file extension and images can be used directly. Follow the actual API behavior in production.
Response
{
"id": "task_AbCdEf1234567890XyZw",
"task_id": "task_AbCdEf1234567890XyZw",
"object": "video",
"model": "wan2.7-t2v",
"status": "queued",
"progress": 0,
"created_at": 1778300000
}id / task_id is the EasyRouter public ID (with task_ prefix), used for subsequent queries. It is not the upstream DashScope task_id — always use the value returned here.
2.2 Query Task Status
GET /v1/video/generations/{task_id}The response uses EasyRouter's unified {code, message, data} wrapper format. data contains full task details, billing info, channel info, and the raw upstream response.
Response (Queued / NOT_START)
{
"code": "success",
"message": "",
"data": {
"id": 42,
"task_id": "task_AbCdEf1234567890XyZw",
"platform": "17",
"user_id": 3,
"group": "default",
"channel_id": 18,
"quota": 250000,
"action": "textGenerate",
"status": "NOT_START",
"fail_reason": "",
"submit_time": 1778300000,
"start_time": 0,
"finish_time": 0,
"created_at": 1778300000,
"updated_at": 1778300000,
"progress": "0%",
"properties": {
"input": "",
"upstream_model_name": "wan2.7-t2v",
"origin_model_name": "wan2.7-t2v"
},
"data": {
"output": {
"task_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"task_status": "PENDING"
},
"request_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
}
}Response (In Progress / IN_PROGRESS)
{
"code": "success",
"message": "",
"data": {
"id": 42,
"task_id": "task_AbCdEf1234567890XyZw",
"status": "IN_PROGRESS",
"progress": "40%",
"submit_time": 1778300000,
"start_time": 1778300010,
"finish_time": 0,
"properties": {
"upstream_model_name": "wan2.7-t2v",
"origin_model_name": "wan2.7-t2v"
},
"data": {
"output": { "task_status": "RUNNING" }
}
}
}Response (Completed / SUCCESS)
{
"code": "success",
"message": "",
"data": {
"id": 42,
"task_id": "task_AbCdEf1234567890XyZw",
"platform": "17",
"user_id": 3,
"group": "default",
"channel_id": 18,
"quota": 250000,
"action": "textGenerate",
"status": "SUCCESS",
"fail_reason": "",
"result_url": "https://dashscope-result-bj.oss-cn-beijing.aliyuncs.com/.../output.mp4?Expires=...&Signature=...",
"submit_time": 1778300000,
"start_time": 1778300010,
"finish_time": 1778300095,
"created_at": 1778300000,
"updated_at": 1778300095,
"progress": "100%",
"properties": {
"input": "",
"upstream_model_name": "wan2.7-t2v",
"origin_model_name": "wan2.7-t2v"
},
"data": {
"output": {
"task_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"task_status": "SUCCEEDED",
"video_url": "https://dashscope-result-bj.oss-cn-beijing.aliyuncs.com/.../output.mp4"
},
"usage": {
"video_duration": 5,
"video_ratio": "16:9",
"video_count": 1
},
"request_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
}
}Response (Failed / FAILURE)
{
"code": "success",
"message": "",
"data": {
"id": 42,
"task_id": "task_AbCdEf1234567890XyZw",
"status": "FAILURE",
"fail_reason": "DataInspectionFailed: input data may contain inappropriate content",
"progress": "100%",
"data": {
"output": { "task_status": "FAILED" }
}
}
}Key Fields
| Field | Type | Description |
|---|---|---|
code | string | Response code, "success" on success |
message | string | Response message |
data.id | int | Internal task auto-increment ID |
data.task_id | string | EasyRouter public task ID (prefixed with task_) |
data.status | string | Task status: NOT_START / QUEUED / IN_PROGRESS / SUCCESS / FAILURE |
data.result_url | string | Video result URL (non-empty only on SUCCESS; upstream OSS temporary signed link) |
data.fail_reason | string | Failure reason (non-empty only on FAILURE) |
data.quota | int | Raw quota deducted for this task |
data.progress | string | Progress string, e.g. "40%" / "100%" |
data.submit_time / start_time / finish_time | int64 | Unix timestamps (seconds) for submit / start / finish |
data.created_at / updated_at | int64 | Record creation / last update time |
data.properties.upstream_model_name | string | Actual model name sent to upstream DashScope |
data.properties.origin_model_name | string | Model name from the client request |
data.data | object | Raw upstream DashScope response (contains output.video_url, usage, request_id) |
Status Enum
| Status | DashScope Status | Description |
|---|---|---|
NOT_START | PENDING | Created, not yet started |
QUEUED | PENDING | Entered upstream queue |
IN_PROGRESS | RUNNING | Generating |
SUCCESS | SUCCEEDED | Completed; result_url contains the video URL |
FAILURE | FAILED / CANCELED / UNKNOWN | Generation failed; fail_reason contains details |
The video URL (data.result_url) is an upstream OSS signed link, valid for 24 hours. Download or transfer it to your own storage immediately after retrieval.
3. Wan 2.7-Specific Parameters (metadata)
These fields are passed via the metadata object in the request body and forwarded transparently to upstream DashScope.
3.1 Common Control Parameters
| Field | Type | Applicable Models | Description | Default |
|---|---|---|---|---|
ratio | string | t2v / r2v | Aspect ratio: 16:9 / 9:16 / 1:1 / 4:3 / 3:4 | 16:9 |
seed | int | All | Random seed, range 0 ~ 2147483647; auto-generated if not specified | — |
negative_prompt | string | All | Negative prompt describing content to exclude; max 500 characters | — |
i2v does not support ratio: the output aspect ratio automatically follows the input first-frame image.
3.2 Multimedia Input (metadata.input.media)
For r2v and videoedit, pass media assets via the metadata.input.media array:
{
"metadata": {
"input": {
"media": [
{ "type": "reference_image", "url": "https://.../img1.jpg" },
{ "type": "reference_image", "url": "https://.../img2.jpg" },
{ "type": "video", "url": "https://.../video.mp4" }
]
}
}
}type | Purpose | Count Limit |
|---|---|---|
reference_image | Reference image | r2v: 1–9; videoedit: 0–3 |
video | Source video to edit (videoedit only) | Exactly 1 required |
first_frame | First-frame image (i2v only; can also be passed via top-level input_reference) | Exactly 1 |
r2v prompt convention: reference images in metadata.input.media by [Image 1], [Image 2], etc., in array order. Example: "The woman in [Image 1] wearing a red cheongsam gracefully unfolds the fan from [Image 2]."
3.3 Media Asset Constraints
| Type | Formats | Resolution | File Size | Other |
|---|---|---|---|---|
| Image (i2v first frame) | JPEG / JPG / PNG / WEBP | 240–8000 px per side | ≤ 10 MB | Aspect ratio 1:8 ~ 8:1 |
| Image (r2v reference) | JPEG / JPG / PNG / WEBP | Short side ≥ 300 px | ≤ 10 MB | Prefer sharp, uncompressed images |
| Image (videoedit reference) | JPEG / JPG / PNG / BMP / WEBP | 240–8000 px per side | ≤ 20 MB | Aspect ratio 1:8 ~ 8:1 |
| Video (videoedit source) | MP4 / MOV (H.264 recommended) | 240–4096 px per side | ≤ 100 MB | Duration 2–10s, aspect ratio 1:8 ~ 8:1 |
4. Full Request Examples
# Step 1: Submit task
curl -X POST https://easyrouter.io/v1/video/generations \
-H "Authorization: Bearer sk-YourApiKey" \
-H "Content-Type: application/json" \
-d '{
"model": "wan2.7-t2v",
"prompt": "A small cat running under moonlight, fur gently flowing in the wind, cinematic slow motion",
"resolution": "720P",
"duration": 5,
"metadata": {
"ratio": "16:9",
"seed": 42
}
}'
# Response:
# {
# "id": "task_AbCdEf1234567890XyZw",
# "task_id": "task_AbCdEf1234567890XyZw",
# "status": "queued", ...
# }
# Step 2: Poll (recommended interval: 10~15 seconds)
curl https://easyrouter.io/v1/video/generations/task_AbCdEf1234567890XyZw \
-H "Authorization: Bearer sk-YourApiKey"
# Step 3: When data.status == "SUCCESS", download from data.result_url
curl -o output.mp4 "https://dashscope-result-bj.oss-cn-beijing.aliyuncs.com/.../output.mp4?Expires=..."# i2v: pass first-frame image via input_reference
curl -X POST https://easyrouter.io/v1/video/generations \
-H "Authorization: Bearer sk-YourApiKey" \
-H "Content-Type: application/json" \
-d '{
"model": "wan2.7-i2v",
"prompt": "Realistic style, a small black cat curiously looks up at the sky, camera slowly zooms in",
"resolution": "720P",
"duration": 5,
"input_reference": "https://wanx.alicdn.com/material/20250318/first_frame.png"
}'The output aspect ratio for i2v automatically follows the input_reference image. metadata.ratio is not supported for i2v.
# r2v: pass reference images via metadata.input.media
# Reference them in the prompt with [Image 1], [Image 2], etc.
curl -X POST https://easyrouter.io/v1/video/generations \
-H "Authorization: Bearer sk-YourApiKey" \
-H "Content-Type: application/json" \
-d '{
"model": "wan2.7-r2v",
"prompt": "3D cartoon adventure movie style, chibi character with refined textures, [Image 1] character running joyfully",
"resolution": "720P",
"duration": 5,
"metadata": {
"ratio": "16:9",
"input": {
"media": [
{
"type": "reference_image",
"url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20260403/wgjaxy/banana_storyboard_00000020.png"
}
]
}
}
}'# videoedit: source video + reference image via images array
# images[0] = source video (MP4/MOV), images[1+] = reference images
curl -X POST https://easyrouter.io/v1/video/generations \
-H "Authorization: Bearer sk-YourApiKey" \
-H "Content-Type: application/json" \
-d '{
"model": "wan2.7-videoedit",
"prompt": "Replace the outfit of the girl in the video with the clothing shown in the reference image",
"resolution": "720P",
"images": [
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20260403/nlspwm/T2VA_22.mp4",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20260402/fwjpqf/wan2.7-videoedit-change-clothes.png"
]
}'No duration needed for videoedit — output duration follows the source video (max 15s). The system infers media type from file extension: MP4/MOV → source video, PNG/JPG/WEBP → reference image.
5. OpenAI-Compatible Endpoints (Optional)
In addition to /v1/video/generations, Wan 2.7 also supports OpenAI-style /v1/videos endpoints. Both are fully equivalent — choose based on your client integration preference.
5.1 Submit (OpenAI-Compatible)
POST /v1/videosRequest body fields are identical to /v1/video/generations.
5.2 Query (OpenAI-Compatible)
GET /v1/videos/{task_id}Returns OpenAI standard flat format:
{
"id": "task_AbCdEf1234567890XyZw",
"object": "video",
"model": "wan2.7-t2v",
"status": "completed",
"progress": 100,
"created_at": 1778300000,
"completed_at": 1778300095,
"metadata": {
"url": "https://dashscope-result-bj.oss-cn-beijing.aliyuncs.com/.../output.mp4?Expires=...&Signature=..."
}
}| OpenAI Status | Unified Format Status |
|---|---|
queued | NOT_START / QUEUED |
in_progress | IN_PROGRESS |
completed | SUCCESS |
failed | FAILURE |
6. Billing
Wan 2.7 is billed by video seconds × resolution multiplier:
| Resolution | Unit Price | Example (5s) |
|---|---|---|
720P | $0.10 / second | 5 × $0.10 = $0.50 |
1080P | $0.15 / second | 5 × $0.15 = $0.75 |
Quota calculation formula:
quota = modelPrice × QuotaPerUnit × groupRatio × seconds × resolutionRatio
QuotaPerUnit = 500,000
modelPrice = 0.10 (all wan2.7 models)
groupRatio = 1.0 (production default group)
resolutionRatio = 720P → 1.0, 1080P → 1.5
Examples:
720P × 5s = 0.10 × 500,000 × 1 × 5 × 1.0 = 250,000 quota
1080P × 10s = 0.10 × 500,000 × 1 × 10 × 1.5 = 750,000 quotaOn task FAILURE, EasyRouter automatically refunds quota to your account (logged as type=6). No manual action required.
7. Polling Guide
| Item | Recommendation |
|---|---|
| Poll interval | Every 10–15 seconds; do not poll more often than every 5 seconds |
| Terminal state | data.status == "SUCCESS" or data.status == "FAILURE" |
| Total timeout | t2v / i2v / r2v: 5 minutes; videoedit: 8–10 minutes |
| Typical duration | t2v / i2v / r2v: 30–100s; videoedit: 3–5 minutes |
| Video URL validity | 24 hours; download or transfer immediately |
Simple Polling Script (Bash)
#!/bin/bash
TID="task_AbCdEf1234567890XyZw"
KEY="sk-YourApiKey"
while true; do
RESP=$(curl -sS "https://easyrouter.io/v1/video/generations/$TID" \
-H "Authorization: Bearer $KEY")
echo "$RESP"
STATUS=$(echo "$RESP" | python3 -c \
"import sys,json;print(json.load(sys.stdin)['data'].get('status',''))")
case "$STATUS" in
SUCCESS|FAILURE) break ;;
esac
sleep 15
done8. Error Handling
8.1 HTTP 400 — Invalid Parameters (rejected before billing)
| Scenario | Response |
|---|---|
Missing prompt | {"code":"invalid_request","message":"prompt is required","data":null} |
| Unknown model name | {"code":"invalid_request","message":"unknown model: ..."} |
Empty images array | {"code":"invalid_request","message":"images is required for videoedit"} |
8.2 HTTP 401 / 403 — Auth Error
401 Unauthorized: API Key invalid or expired403 Forbidden: API Key has no access to this model
8.3 HTTP 402 — Insufficient Balance
Returns insufficient user quota. Recharge at the EasyRouter console.
8.4 Task FAILURE Status
| Common Reason | Recommendation |
|---|---|
DataInspectionFailed | Upstream content moderation triggered. Adjust prompt or media. Note: some official Alibaba example assets may also trigger this — it is upstream behavior, not an EasyRouter restriction. |
i2v missing input_reference | First-frame image is required for image-to-video |
| r2v with zero reference images | Provide at least 1 reference_image |
| videoedit missing source video | images[0] must be an MP4/MOV video link |
| Inaccessible media URL | Ensure URLs are publicly accessible and not expired |
| Media asset out of spec | See Section 3.3 for constraints |