wan-2-7-video
Wan 2.7 Video — one endpoint for text-to-video, image-to-video, reference-to-video, and video editing. The umbrella model auto-routes by request shape, renders 720P or 1080P, and bills per second.
Wan 2.7 Video is a single umbrella model (wan2.7-video) that auto-routes by
request shape into text-to-video, image-to-video,
reference-to-video, and video editing. One async endpoint, 720P or
1080P output, billed per second. See current pricing on the
model page.
Quick example
curl https://reapi.ai/api/v1/videos/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "wan2.7-video",
"prompt": "a paper boat drifting down a rain-soaked street at dusk, neon reflections, slow dolly-in, cinematic",
"resolution": "1080P",
"duration": 5
}'import requests
resp = requests.post(
"https://reapi.ai/api/v1/videos/generations",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"model": "wan2.7-video",
"prompt": "a paper boat drifting down a rain-soaked street at dusk",
"resolution": "1080P",
"duration": 5,
},
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: "wan2.7-video",
prompt: "a paper boat drifting down a rain-soaked street at dusk",
resolution: "1080P",
duration: 5,
}),
});
console.log(await r.json());package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
func main() {
body, _ := json.Marshal(map[string]any{
"model": "wan2.7-video",
"prompt": "a paper boat drifting down a rain-soaked street at dusk",
"resolution": "1080P",
"duration": 5,
})
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))
}Submit response
{
"id": "task_018f5a3a1b6e7d9f8c2b4d6e8f0a2c4e",
"model": "wan2.7-video",
"status": "processing",
"created_at": 1735000000
}Poll GET /api/v1/tasks/{id} (see the Tasks reference) until
status === "completed". The completed payload's output.video_urls holds the
generated MP4 URLs.
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.
Modes
There is no mode field. The umbrella model wan2.7-video infers the mode from
which inputs you send:
| Mode | Trigger | Notes |
|---|---|---|
| Text-to-video | prompt only | A prompt alone renders a clip. |
| Image-to-video | image_urls / image_with_roles / video_urls (and audio_url) | Animate a still, set first/last frame, continue a clip, or drive motion with audio. |
| Reference-to-video | reference_image_urls and/or reference_video_urls | Keeps your subjects while following a referenced performance; reference_voice_urls add per-subject audio. |
| Video editing | video_url (the source clip) | Re-renders the source against the prompt; audio_setting controls the soundtrack. |
The fields valid in each mode are mutually exclusive — sending, e.g., a
reference field together with a video_url edit source is rejected as invalid.
Parameters
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
model | string | yes | — | Must be "wan2.7-video". |
prompt | string | cond. | — | Up to 5000 chars. Required for text-to-video and reference-to-video. |
negative_prompt | string | no | — | Up to 500 chars. What to avoid. |
image_urls | string[] | no | — | Public image URLs. 1 animates a still; 2 set first/last frame. Max 4. |
image_with_roles | object[] | no | — | [{ url, role }] where role is first_frame or last_frame. Max 2. |
video_urls | string[] | no | — | Continuation source. Public video URL. Max 1. |
audio_url | string | no | — | Public audio URL. Drives motion with an image input. |
reference_image_urls | string[] | no | — | Reference subjects. Public image URLs. Up to 5. |
reference_video_urls | string[] | no | — | Reference motion/action. Public video URLs. Up to 5. |
reference_voice_urls | string[] | no | — | Per-subject voices. Public audio URLs. Count must equal reference_image_urls. |
video_url | string | no | — | Edit source. Public video URL. Routes to video editing. |
audio_setting | enum | no | — | Video editing only. auto or origin. |
size | enum | no | 16:9 | Aspect ratio: 16:9, 9:16, 1:1, 4:3, 3:4. |
resolution | enum | no | 1080P | 720P or 1080P. Scales the per-second rate. |
duration | integer | no | 5 | Seconds. Base modes 2–15; reference/edit modes cap lower (see below). |
prompt_extend | boolean | no | true | Expand a short prompt into a richer description before rendering. |
watermark | boolean | no | false | Add a watermark to the output. |
seed | integer | no | — | >= 0. Fixes the random seed for reproducible output. |
No data: URIs. reApi rejects base64 inputs platform-wide. Upload media to
public storage (your own CDN, S3, R2…) and pass the URL.
Duration limits by mode
| Mode | Allowed duration |
|---|---|
| Text-to-video / image-to-video | 2 – 15 seconds |
| Reference-to-video (images only) | 2 – 15 seconds |
| Reference-to-video (with videos) | 2 – 10 seconds |
| Video editing | 0 (full source length) or 2 – 10 |
Response envelope
Submit and poll share the same shape — only status and output fill in over
time.
{
"id": "task_018f5a3a1b6e7d9f8c2b4d6e8f0a2c4e",
"model": "wan2.7-video",
"status": "completed",
"created_at": 1735000000,
"output": {
"video_urls": ["https://cdn.reapi.ai/media/tasks/018f5a3a1b6e7d9f8c2b4d6e8f0a2c4e/0.mp4"]
},
"error": null
}| Field | Type | Notes |
|---|---|---|
id | string | Task identifier — keep it for polling and audit |
model | string | Echo of the submitted model |
status | string | processing / completed / failed |
created_at | integer | Submission unix timestamp |
output | object | null | null until completion. output.video_urls holds MP4s |
error | object | null | Populated on failed — { code, message } |
Pricing
Per-second × resolution. The mode does not change the rate — only the
resolution does. 1080P costs more per second than 720P.
For the input-billed modes (reference-to-video and video editing) reApi probes
the uploaded clip server-side and folds input + output into the billable
second count, rather than trusting a client value. Base text/image modes bill
the requested output duration.
Bill formula (1 credit = $0.001):
billable_seconds = ceil(server_probed_or_output_seconds)
bill_usd = per_second_usd(resolution) × billable_seconds
credits = ceil(per_second_usd × billable_seconds × 1000)See current per-second rates for 720P and 1080P on the
model page. Failed jobs refund
automatically. A probe failure on an input-billed mode returns
400 PRICING_UNAVAILABLE (code 30002) with no charge.
The playground's draft estimate may show a default before an uploaded clip is probed — the authoritative number is computed at submit, after the server measures the file.
Validation errors
All cases below return HTTP 400. Pattern-match on code, not message —
message strings carry request-specific context and are not a stable contract.
| Trigger | Code | Message (illustrative) |
|---|---|---|
prompt missing for text-to-video / reference-to-video | 20002 | wan-2-7-video: prompt is required |
| Field invalid for the inferred mode | 20003 | wan-2-7-video: video_urls is not valid in video editing |
duration outside the mode's allowed range | 20003 | wan-2-7-video: duration must be 2-15 seconds |
reference_voice_urls count != reference_image_urls | 20003 | wan-2-7-video: reference_voice_urls length must equal reference_image_urls length |
A media field carrying a data: URI | 20003 | wan-2-7-video: must be a public http(s) URL |
| Source clip probe fails (network / format) | 30002 | Could not determine source video duration for billing: … |
| Provider rejected the request as invalid | 80007 | Provider rejected the request as invalid |
The full envelope is { "error": { "code", "message", "request_id" } } — see
Errors catalog for the wire format and request_id
correlation tips.
Recipes
Text-to-video
{
"model": "wan2.7-video",
"prompt": "a paper boat drifting down a rain-soaked street at dusk",
"resolution": "1080P",
"duration": 5
}Image-to-video (animate a still)
{
"model": "wan2.7-video",
"prompt": "the subject turns to camera and smiles softly",
"image_urls": ["https://your-cdn.com/portrait.png"],
"resolution": "1080P",
"duration": 5
}Reference-to-video
{
"model": "wan2.7-video",
"prompt": "apply the reference choreography to the new character",
"reference_image_urls": ["https://your-cdn.com/subject.png"],
"reference_video_urls": ["https://your-cdn.com/dance-6s.mp4"],
"resolution": "1080P",
"duration": 6
}Video editing
{
"model": "wan2.7-video",
"prompt": "restyle the clip with warm cinematic color grading",
"video_url": "https://your-cdn.com/source-8s.mp4",
"audio_setting": "origin",
"duration": 0
}Tips
- Let the inputs pick the mode. There is no
modeflag — send a prompt for text-to-video, addimage_urlsfor image-to-video,reference_*for reference-to-video, orvideo_urlto edit. Don't mix fields across modes. - Match
durationto the mode. Base modes allow 2–15s; reference-with-video and editing cap at 10s, and editing accepts0for the full source length. - Resolution drives cost.
720Pis the cheaper run; switch to1080Pfor the final take. The mode does not change the per-second rate. - Keep
reference_voice_urlsaligned. Their count must equal the number ofreference_image_urls, one voice per subject. - Prompt the motion, not just the scene. Describing the action ("turns and waves, smooth and continuous") sharpens text-to-video and image-to-video results.