curl --request POST \
--url https://api.apimart.ai/v1/videos/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"model": "wan3.0-video",
"prompt": "一只小猫在月光下的屋顶上奔跑,城市的霓虹灯在远处闪烁,电影级画质,流畅运镜。",
"resolution": "720P",
"size": "16:9",
"duration": 5
}'
import requests
url = "https://api.apimart.ai/v1/videos/generations"
payload = {
"model": "wan3.0-video",
"prompt": "一只小猫在月光下的屋顶上奔跑,城市的霓虹灯在远处闪烁,电影级画质,流畅运镜。",
"resolution": "720P",
"size": "16:9",
"duration": 5,
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json",
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
const url = "https://api.apimart.ai/v1/videos/generations";
const payload = {
model: "wan3.0-video",
prompt: "一只小猫在月光下的屋顶上奔跑,城市的霓虹灯在远处闪烁,电影级画质,流畅运镜。",
resolution: "720P",
size: "16:9",
duration: 5,
};
const headers = {
Authorization: "Bearer <token>",
"Content-Type": "application/json",
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(payload),
})
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.error("Error:", error));
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
url := "https://api.apimart.ai/v1/videos/generations"
payload := map[string]interface{}{
"model": "wan3.0-video",
"prompt": "一只小猫在月光下的屋顶上奔跑",
"resolution": "720P",
"size": "16:9",
"duration": 5,
}
jsonData, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
{
"code": 200,
"data": [
{
"status": "submitted",
"task_id": "task_01J9HA7JPQ9A0Z6JZ3V8M9W6PZ"
}
]
}
{
"error": {
"code": 400,
"message": "请求参数无效",
"type": "invalid_request_error"
}
}
{
"error": {
"code": 401,
"message": "身份验证失败,请检查您的API密钥",
"type": "authentication_error"
}
}
{
"error": {
"code": 402,
"message": "账户余额不足,请充值后再试",
"type": "payment_required"
}
}
{
"error": {
"code": 429,
"message": "请求过于频繁,请稍后再试",
"type": "rate_limit_error"
}
}
Wan3.0
Wan3.0 视频生成
- 阿里云万相 3.0 全能参考视频模型(统一入口)
- 文生视频 / 首帧 / 首尾帧 / 参考生视频 / 参考文件生视频
- 分辨率 480P / 720P / 1080P,时长 2–30 秒,或
-1由模型决定 - 支持图、视频、音频、文档、网页等多模态参考
POST
/
v1
/
videos
/
generations
curl --request POST \
--url https://api.apimart.ai/v1/videos/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"model": "wan3.0-video",
"prompt": "一只小猫在月光下的屋顶上奔跑,城市的霓虹灯在远处闪烁,电影级画质,流畅运镜。",
"resolution": "720P",
"size": "16:9",
"duration": 5
}'
import requests
url = "https://api.apimart.ai/v1/videos/generations"
payload = {
"model": "wan3.0-video",
"prompt": "一只小猫在月光下的屋顶上奔跑,城市的霓虹灯在远处闪烁,电影级画质,流畅运镜。",
"resolution": "720P",
"size": "16:9",
"duration": 5,
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json",
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
const url = "https://api.apimart.ai/v1/videos/generations";
const payload = {
model: "wan3.0-video",
prompt: "一只小猫在月光下的屋顶上奔跑,城市的霓虹灯在远处闪烁,电影级画质,流畅运镜。",
resolution: "720P",
size: "16:9",
duration: 5,
};
const headers = {
Authorization: "Bearer <token>",
"Content-Type": "application/json",
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(payload),
})
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.error("Error:", error));
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
url := "https://api.apimart.ai/v1/videos/generations"
payload := map[string]interface{}{
"model": "wan3.0-video",
"prompt": "一只小猫在月光下的屋顶上奔跑",
"resolution": "720P",
"size": "16:9",
"duration": 5,
}
jsonData, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
{
"code": 200,
"data": [
{
"status": "submitted",
"task_id": "task_01J9HA7JPQ9A0Z6JZ3V8M9W6PZ"
}
]
}
{
"error": {
"code": 400,
"message": "请求参数无效",
"type": "invalid_request_error"
}
}
{
"error": {
"code": 401,
"message": "身份验证失败,请检查您的API密钥",
"type": "authentication_error"
}
}
{
"error": {
"code": 402,
"message": "账户余额不足,请充值后再试",
"type": "payment_required"
}
}
{
"error": {
"code": 429,
"message": "请求过于频繁,请稍后再试",
"type": "rate_limit_error"
}
}
curl --request POST \
--url https://api.apimart.ai/v1/videos/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"model": "wan3.0-video",
"prompt": "一只小猫在月光下的屋顶上奔跑,城市的霓虹灯在远处闪烁,电影级画质,流畅运镜。",
"resolution": "720P",
"size": "16:9",
"duration": 5
}'
import requests
url = "https://api.apimart.ai/v1/videos/generations"
payload = {
"model": "wan3.0-video",
"prompt": "一只小猫在月光下的屋顶上奔跑,城市的霓虹灯在远处闪烁,电影级画质,流畅运镜。",
"resolution": "720P",
"size": "16:9",
"duration": 5,
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json",
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
const url = "https://api.apimart.ai/v1/videos/generations";
const payload = {
model: "wan3.0-video",
prompt: "一只小猫在月光下的屋顶上奔跑,城市的霓虹灯在远处闪烁,电影级画质,流畅运镜。",
resolution: "720P",
size: "16:9",
duration: 5,
};
const headers = {
Authorization: "Bearer <token>",
"Content-Type": "application/json",
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(payload),
})
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.error("Error:", error));
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
url := "https://api.apimart.ai/v1/videos/generations"
payload := map[string]interface{}{
"model": "wan3.0-video",
"prompt": "一只小猫在月光下的屋顶上奔跑",
"resolution": "720P",
"size": "16:9",
"duration": 5,
}
jsonData, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
{
"code": 200,
"data": [
{
"status": "submitted",
"task_id": "task_01J9HA7JPQ9A0Z6JZ3V8M9W6PZ"
}
]
}
{
"error": {
"code": 400,
"message": "请求参数无效",
"type": "invalid_request_error"
}
}
{
"error": {
"code": 401,
"message": "身份验证失败,请检查您的API密钥",
"type": "authentication_error"
}
}
{
"error": {
"code": 402,
"message": "账户余额不足,请充值后再试",
"type": "payment_required"
}
}
{
"error": {
"code": 429,
"message": "请求过于频繁,请稍后再试",
"type": "rate_limit_error"
}
}
认证
string
必填
生成模式
模型名固定wan3.0-video,按传参自动承接多种能力:
| 模式 | 典型传参 |
|---|---|
| 文生视频 | 仅 prompt |
| 首帧生视频 | image_urls 1 张(首尾帧族) |
| 首尾帧生视频 | image_urls 2 张,或 image_with_roles 指定 first_frame / last_frame |
| 参考生视频 | 参考图 / 视频 / 音频;prompt 可用「图1」「视频1」「音频1」指代 |
| 参考文件 / 网页生视频 | file_url 或 link_url(可无 prompt) |
请求参数
基础
string
必填
固定值:
wan3.0-videoboolean
默认值:"false"
是否在提交视频任务前执行内容审核。
true:使用omni-moderation-latest审核提示词和输入图片false或不传:不发起审核请求,不增加审核成本与延迟(默认)
string
文本描述。与素材字段至少填其一。
- 最长 20000 字符,超出部分会被自动截断(不报错)
- 参考模式下可用「图1」「视频1」「音频1」指代素材;编号按同类型素材在数组中的顺序(图与视频各自从 1 计数)
string
默认值:"1080P"
输出分辨率(大小写不敏感)
480P720P1080P(默认,价格最高)
不传
resolution 时按 1080P 计费。对成本敏感时请显式传 480P 或 720P。string
默认值:"adaptive"
宽高比。也可用
aspect_ratio。adaptive(默认,自适应)16:9/4:3/1:1/3:4/9:16
integer
默认值:"5"
生成时长(秒):
2–30:指定输出时长,默认5-1:由模型自行决定时长
有参考视频输入时,要求「输入视频总时长 + 输出时长 ≤ 30 秒」,超出将被拒绝。传
duration: -1 时,输出时长由模型决定,仍须满足该约束。boolean
默认值:"true"
输出视频是否含音轨,默认
true。开关声音价格相同。integer
随机种子,范围
[0, 2147483647]boolean
默认值:"false"
是否加水印,默认
falsestring
决定裸
image_urls 归到哪一族:frame— 首尾帧族reference— 参考族
素材输入
string[]
图片 URL 数组。角色归属见「两族素材互斥」。支持公网 URL 与 Base64(
data:image/png;base64,...)。object[]
带角色的图片数组,可显式指定角色。每项:
url:图片地址role:first_frame/last_frame/reference_image(及常见别名)
string[]
参考视频,最多 5 段;单段 1–15 秒,总时长 ≤ 15 秒
string[]
参考音频,最多 5 段;单段 1–15 秒,总时长 ≤ 15 秒
string
单条参考音频(与
audio_urls 等价的单值写法)string
参考文档 URL,最多 1 个。不可与
link_url 同时传。支持:docx / doc / xlsx / xls / pptx / ppt / pdf / txt / key / pages / numbers / md 等,≤100MB,≤50 页。string
公开网页 URL,最多 1 个。仅支持免登录网页。不可与
file_url 同时传。两族素材互斥
素材分两族,不能混用(提交前校验,返回 400,不建任务、不扣费):| 族 | 成员 | 语义 |
|---|---|---|
| 首尾帧族 | first_frame、last_frame | 严格指定视频第一帧 / 最后一帧 |
| 参考族 | reference_image、reference_video、reference_audio、file、link | 由模型理解素材内容 |
裸 image_urls 如何归属
- 传了
generation_type→ 以它为准(frame/reference) - 未传,但请求含参考族输入(
video_urls/audio_urls/audio_url/file_url/link_url)→ 归reference_image - 都没有 → 归首尾帧族:第 1 张
first_frame,第 2 张last_frame(与wan2.7一致)
image_with_roles。
素材上限与格式
| 类型 | 上限 / 限制 |
|---|---|
| 首帧 / 尾帧 | 各最多 1 张 |
| 参考图 | 最多 10 张 |
| 参考视频 | 最多 5 段,单段 1–15s,总 ≤15s;mp4/mov;单边 240–4096 px,长宽比 ≤8:1,≤100MB |
| 参考音频 | 最多 5 段,单段 1–15s,总 ≤15s;wav/mp3;≤15MB |
| 图像 | JPEG/JPG/PNG(无透明)/BMP/WEBP;单边 240–8000 px,长宽比 ≤8:1,≤20MB |
| 文档 | ≤100MB,≤50 页 |
| 网页 | 公开、免登录 URL |
请求示例
文生视频
{
"model": "wan3.0-video",
"prompt": "一只小猫在月光下的屋顶上奔跑,城市的霓虹灯在远处闪烁,电影级画质,流畅运镜。",
"resolution": "720P",
"size": "16:9",
"duration": 5
}
首帧生视频
{
"model": "wan3.0-video",
"prompt": "画面中的人物开始说唱,镜头缓缓推进",
"image_urls": ["https://example.com/first.png"],
"resolution": "720P",
"duration": 5
}
首尾帧生视频
{
"model": "wan3.0-video",
"prompt": "从微笑逐渐变为大笑,背景光线从冷色调渐变为暖色调",
"image_urls": [
"https://example.com/first.png",
"https://example.com/last.jpg"
],
"duration": 5
}
image_with_roles:
{
"model": "wan3.0-video",
"prompt": "从微笑逐渐变为大笑",
"image_with_roles": [
{"url": "https://example.com/first.png", "role": "first_frame"},
{"url": "https://example.com/last.jpg", "role": "last_frame"}
],
"duration": 5
}
参考生视频(多素材)
{
"model": "wan3.0-video",
"prompt": "视频1抱着图1,在图3的椅子上弹奏一支舒缓的乡村民谣,并说道:\"今天的阳光真好。\"",
"generation_type": "reference",
"image_urls": [
"https://example.com/object1.jpg",
"https://example.com/object2.png",
"https://example.com/chair.png"
],
"video_urls": ["https://example.com/role.mp4"],
"resolution": "480P",
"duration": 5
}
有video_urls时,裸image_urls会自动归参考图;显式generation_type: "reference"更清晰。
参考文件生视频
可不传prompt,由文档内容驱动生成:
{
"model": "wan3.0-video",
"file_url": "https://example.com/glass.pptx",
"resolution": "480P",
"duration": 10
}
参考网页生视频
{
"model": "wan3.0-video",
"prompt": "把这篇文章做成一支科普短片",
"link_url": "https://example.com/article/123",
"duration": 15
}
计费
按秒 × 分辨率计费(与官方刊例一致),开关声音同价:| 分辨率 | 单价 | 5 秒 | 30 秒 |
|---|---|---|---|
| 480P | ¥0.30 / 秒 | ¥1.50 | ¥9.00 |
| 720P | ¥0.60 / 秒 | ¥3.00 | ¥18.00 |
| 1080P | ¥1.20 / 秒 | ¥6.00 | ¥36.00 |
- 默认 1080P(最贵),成本敏感请显式传
480P/720P - 计费秒数:传
2–30时按请求的duration;传-1时按模型实际产出秒数 audio: true/false不影响价格
限制与注意
| 项 | 说明 |
|---|---|
| 时长 | 2–30 秒整数,或 -1(由模型决定时长) |
| 有视频输入时 | 输入视频总时长 + 输出时长 ≤ 30 秒 |
| 生成耗时 | 通常 1–5 分钟,长视频更久 |
| 结果地址 | 任务成功后转存平台 CDN,返回地址可长期使用 |
| prompt | ≤20000 字符,超出自动截断 |
常见错误
均为同步 400,不建任务、不扣费:| 场景 | 处理 |
|---|---|
| 首尾帧族与参考族混用 | 用 generation_type 选定一族,或 image_with_roles 指定角色 |
同时传 file_url 与 link_url | 二选一 |
duration 非法 | 仅支持 2–30 或 -1 |
| 不支持的分辨率(如 4K) | 仅用 480P / 720P / 1080P |
| 参考图超过 10 张 | 减到 10 张以内 |
prompt 与素材都为空 | 至少提供其一 |
Response
integer
响应状态码,成功时为 200
查询任务结果视频为异步任务。使用 获取任务状态 或
GET /v1/videos/generations/{task_id} 轮询。建议每 5–10 秒一次;生成通常 1–5 分钟。成功后取 result.videos 中的地址。