Wan 2.7 Video Generation
Call Wan 2.7 text-to-video, image-to-video, reference-to-video, and video editing models through the unified video task API.
- Submission route:
POST /v1/videos - Task query:
GET /v1/videos/{task_id} - Content download:
GET /v1/videos/{task_id}/content
Video generation is asynchronous. Submit a task first, then poll with the returned task_id. After the task succeeds, download the generated video promptly. Wan 2.7 upstream result URLs are usually valid for 24 hours.
Supported Models
| Model | Use case | Main input |
|---|---|---|
wan2.7-t2v | Text to video | prompt |
wan2.7-i2v | Image to video, first/last frame, video continuation | prompt, media, or image/images |
wan2.7-r2v | Reference to video, multi-subject reference, reference voices | prompt, media |
wan2.7-videoedit | Video editing | prompt, video item in media |
Common Request Fields
| Field | Type | Description |
|---|---|---|
model | string | Required. Use wan2.7-r2v for reference-to-video generation. |
prompt | string | Required for wan2.7-r2v, up to 5000 characters. Refer to assets by order, such as Image 1 and Video 1; image and video references are numbered separately. |
media | array | Required for wan2.7-r2v. Must contain at least one reference_image or reference_video. |
negative_prompt | string | Negative prompt, up to 500 characters. |
resolution | string | Resolution tier. 720P or 1080P; default is 1080P. Cost changes with resolution. |
ratio | string | Output aspect ratio. Supports 16:9, 9:16, 1:1, 4:3, 3:4; default is 16:9. For wan2.7-r2v, this is ignored when first_frame is provided. |
duration | number | Duration in seconds; default is 5. For wan2.7-r2v, range is 2 to 10 when reference video is included, and 2 to 15 without reference video. |
seconds | string | String form of duration; prefer duration for new integrations. |
metadata | object | Extra parameters. Common wan2.7-r2v keys: prompt_extend, watermark, seed. |
wan2.7-r2v media
Each media item must include at least type and url. Array order defines the prompt references: the first reference_image is Image 1, and the first reference_video is Video 1. Images and videos are counted independently.
| type | Availability | Description |
|---|---|---|
reference_image | One of the required reference types | Reference image for a person, animal, object, or scene. Supports public URLs, OSS temporary URLs, and Base64 Data URLs. |
reference_video | One of the required reference types | Reference video. Use content that contains the subject; it can also provide a voice reference when it has audio. Supports public URLs and OSS temporary URLs. |
first_frame | Optional | First-frame image, maximum 1. When provided, ratio is ignored and the output follows the first-frame aspect ratio. |
reference_image plus reference_video supports up to 5 items total. If a reference asset represents a subject, the official recommendation is to keep one role per asset. reference_image and reference_video may include reference_voice to set that subject's voice.
Media Limits
| Asset | Formats | Limits |
|---|---|---|
reference_image / first_frame | JPEG, JPG, PNG, BMP, WEBP | Width and height [240, 8000], aspect ratio 1:8 to 8:1, file size up to 20MB. PNG transparency is not supported. |
reference_video | MP4, MOV | Duration 1 to 30 seconds, width and height [240, 4096], aspect ratio 1:8 to 8:1, file size up to 100MB. |
reference_voice | WAV, MP3 | Duration 1 to 10 seconds, file size up to 15MB. It only controls voice timbre, not spoken content. |
Reference to Video
Multi-subject example with reference images, a reference video, and reference voices:
curl --request POST \
--url https://api.magickapi.com/v1/videos \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"model": "wan2.7-r2v",
"prompt": "Video 1 is holding Image 3 while playing a gentle country song on the chair from Image 4, and says: The sunshine is lovely today. Image 1 walks past Video 1 holding Image 2, puts Image 2 on the nearby table, and says: That sounds great, can you sing it again?",
"media": [
{
"type": "reference_image",
"url": "https://example.com/girl.jpg",
"reference_voice": "https://example.com/girl-voice.mp3"
},
{
"type": "reference_video",
"url": "https://example.com/boy-role.mp4",
"reference_voice": "https://example.com/boy-voice.mp3"
},
{
"type": "reference_image",
"url": "https://example.com/prop.png"
},
{
"type": "reference_image",
"url": "https://example.com/chair.png"
}
],
"resolution": "720P",
"ratio": "16:9",
"duration": 10,
"metadata": {
"prompt_extend": false,
"watermark": false,
"seed": 7
}
}'For a single storyboard image, still use reference_image:
{
"model": "wan2.7-r2v",
"prompt": "Reference image, 3D cartoon adventure film style, keep the characters and forest scene consistent. Story beats: wide shot of the forest, the boy opens vines, the robot scans ahead, and they finally find a treasure chest.",
"media": [
{
"type": "reference_image",
"url": "https://example.com/storyboard.png"
}
],
"resolution": "720P",
"duration": 10,
"metadata": {
"prompt_extend": false,
"watermark": false
}
}To constrain the first frame, add first_frame:
{
"model": "wan2.7-r2v",
"prompt": "Video 1 enters from the doorway of the room in Image 1 and talks with the character in Image 2.",
"media": [
{
"type": "first_frame",
"url": "https://example.com/first-frame.png"
},
{
"type": "reference_video",
"url": "https://example.com/role.mp4"
},
{
"type": "reference_image",
"url": "https://example.com/second-role.png"
}
],
"resolution": "720P",
"duration": 8
}Other Wan 2.7 Modes
Text to video:
curl --request POST \
--url https://api.magickapi.com/v1/videos \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"model": "wan2.7-t2v",
"prompt": "A paper airplane slowly glides over a desk in sunlight, steady camera, clean composition.",
"resolution": "720P",
"ratio": "16:9",
"duration": 5
}'Image to video:
{
"model": "wan2.7-i2v",
"prompt": "Make the cat in the image look up at the camera, with a slight camera push-in.",
"image": "https://example.com/first-frame.png",
"resolution": "720P",
"duration": 5
}Video editing:
{
"model": "wan2.7-videoedit",
"prompt": "Keep the subject motion, replace the background with a cyberpunk street at night.",
"media": [
{
"type": "video",
"url": "https://example.com/source.mp4"
},
{
"type": "reference_image",
"url": "https://example.com/style-reference.png"
}
],
"resolution": "720P",
"duration": 5,
"metadata": {
"audio_setting": "origin",
"watermark": false
}
}Response, Query, and Download
Successful submission returns a task object:
{
"id": "task_01KXYZ1234567890ABCDE",
"task_id": "task_01KXYZ1234567890ABCDE",
"object": "video",
"model": "wan2.7-r2v",
"status": "queued",
"progress": 0,
"created_at": 1712345678
}Query task status:
curl https://api.magickapi.com/v1/videos/task_01KXYZ1234567890ABCDE \
-H 'Authorization: Bearer YOUR_API_KEY'Status can be queued, in_progress, completed, or failed. When the task succeeds, metadata.url contains the upstream temporary video URL. Prefer the content download route to save the file:
curl -L https://api.magickapi.com/v1/videos/task_01KXYZ1234567890ABCDE/content \
-H 'Authorization: Bearer YOUR_API_KEY' \
--output wan2-7-r2v-output.mp4Polling Example
import { writeFile } from "node:fs/promises";
const baseUrl = "https://api.magickapi.com";
const apiKey = "YOUR_API_KEY";
const submitResp = await fetch(`${baseUrl}/v1/videos`, {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "wan2.7-r2v",
prompt: "Image 1 sits by the cafe window playing guitar. Video 1 walks into the frame and talks with Image 1.",
media: [
{
type: "reference_image",
url: "https://example.com/character.png",
reference_voice: "https://example.com/voice.mp3",
},
{
type: "reference_video",
url: "https://example.com/action.mp4",
},
],
resolution: "720P",
ratio: "16:9",
duration: 10,
metadata: {
prompt_extend: false,
watermark: false,
},
}),
});
if (!submitResp.ok) {
throw new Error(await submitResp.text());
}
const task = await submitResp.json();
const taskId = task.id || task.task_id;
while (true) {
const queryResp = await fetch(`${baseUrl}/v1/videos/${taskId}`, {
headers: { Authorization: `Bearer ${apiKey}` },
});
const status = await queryResp.json();
if (status.status === "completed") {
const downloadResp = await fetch(`${baseUrl}/v1/videos/${taskId}/content`, {
headers: { Authorization: `Bearer ${apiKey}` },
});
const buffer = Buffer.from(await downloadResp.arrayBuffer());
await writeFile("wan2-7-r2v-output.mp4", buffer);
break;
}
if (status.status === "failed") {
throw new Error(status.error?.message || "video generation failed");
}
await new Promise((resolve) => setTimeout(resolve, 15000));
}Last updated on
Veo Video Generation
Call Veo models through the unified video task interface; describes available models, request fields, and query methods in the current project.
Doubao Seedance 2.0 Video Generation
Call Doubao video models through the unified video task interface; explains available models, request fields, and query methods in the current project.