视频生成POST
文生视频、图生视频、首尾帧、参考视频与视频编辑。所有视频任务都是异步的:提交后返回 202,完成后从私有存储下载。
POST https://api.tokentosea.com/v1/videos
提交一个视频生成任务。接口总是返回 202 和结果信封,平台在后台每 5 秒查询一次厂商任务,完成后把视频转存到私有存储并按实际用量结算。用 GET /v1/videos/{id} 或 GET /v1/results/{key} 查询进度。
前提:全能密钥或模型密钥,账户可用余额足以覆盖本次预留(按秒计费的型号按 duration 预留)。Python 示例需要 pip install requests,Node.js 示例需要 Node.js 18+。
支持的型号#
截至 2026-10-21,49 个型号开放本接口,以 GET /v1/models 为准。
开放 /v1/videos 的型号(49)
| 服务商 | 型号 |
|---|---|
| 千问(通义万相、HappyHorse) | wan3.0-video、wan3.0-video-prime、wan2.7-t2v、wan2.7-t2v-2026-04-25、wan2.7-t2v-2026-06-12、wan2.7-i2v、wan2.7-i2v-2026-04-25、wan2.7-r2v、wan2.7-r2v-2026-06-12、wan2.7-videoedit、wan2.6-t2v、wan2.6-i2v、wan2.6-i2v-flash、wan2.6-r2v、wan2.6-r2v-flash、wan2.5-t2v-preview、wan2.5-i2v-preview、wan2.2-t2v-plus、wan2.2-i2v-plus、wan2.2-i2v-flash、wan2.2-kf2v-flash、wan2.2-s2v、wan2.2-animate-mix、wan2.2-animate-move、wanx2.1-t2v-plus、wanx2.1-t2v-turbo、wanx2.1-i2v-plus、wanx2.1-i2v-turbo、wanx2.1-kf2v-plus、wanx2.1-vace-plus、happyhorse-1.0-t2v、happyhorse-1.0-i2v、happyhorse-1.0-r2v、happyhorse-1.0-video-edit、happyhorse-1.1-t2v、happyhorse-1.1-i2v、happyhorse-1.1-r2v |
| 豆包(Seedance) | doubao-seedance-2-5-260628、doubao-seedance-2-0-260128、doubao-seedance-2-0-fast-260128、doubao-seedance-2-0-mini-260615、doubao-seedance-1-0-pro-fast-251015 |
| MiniMax(海螺) | MiniMax-H3、MiniMax-H3-Max、MiniMax-Hailuo-02、MiniMax-Hailuo-2.3、MiniMax-Hailuo-2.3-Fast |
| 智谱 | cogvideox-3、cogvideox-2 |
只支持 JSON 请求;"stream": true 返回 422 response_mode_not_verified。
请求体#
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
model | string | 必填 | 型号 ID |
prompt | string | 必填 | 视频描述 |
duration | integer | 可选 | 时长(秒)。按秒计费的型号以它预留费用;取值范围以型号为准,见时长与分辨率 |
resolution | string | 可选 | 分辨率档位,例如 480P、720P、1080P、768P(大小写不敏感)。不传时使用型号默认档位;多数型号的价格随档位变化 |
size | string | 可选 | 千问写作 宽*高(如 1280*720),智谱写作 宽x高 |
ratio | string | 可选 | 画面比例(千问、豆包、MiniMax H3) |
fps | integer | 可选 | 帧率(智谱) |
quality | string | 可选 | 质量档位(智谱,如 speed) |
with_audio / audio | boolean | 可选 | 是否生成音频:智谱用 with_audio,千问用 audio(wan2.6-i2v-flash、wan2.6-r2v-flash 的价格与此有关) |
watermark | boolean | 可选 | 豆包:是否添加水印 |
seed | integer | 可选 | 随机种子 |
prompt_extend | boolean | 可选 | 千问:是否自动扩写提示词 |
input | array | object | 可选 | 参考素材,见参考素材 |
parameters | object | 可选 | 千问:其他厂商原生参数,合并进上游 parameters |
provider_options | object | 可选 | 厂商原生扩展。千问支持 input(合并进上游 input)与 parameters;MiniMax 与豆包的字段直接并入上游请求体 |
参考素材#
input 写成数组时,每一项是 { "role": "…", "url": "https://…" }。role 只能是下表之一,否则返回 422 video_input_invalid;型号不支持该角色时返回 422 unsupported_video_role。
role | 含义 | 适用(示例) |
|---|---|---|
first_frame | 首帧图片 | 图生视频 *-i2v*、首尾帧 *-kf2v*、wan2.2-s2v、MiniMax 海螺 |
last_frame | 尾帧图片 | 首尾帧 *-kf2v*、MiniMax 海螺 |
reference_image | 参考图 | happyhorse-*-r2v、wan2.2-animate-*、豆包 Seedance、MiniMax H3 |
reference_video | 参考视频 | wan2.6-r2v*、wan2.7-r2v*、wan2.2-animate-*、视频编辑型号、豆包、MiniMax H3 |
reference_audio | 参考音频 | wan2.2-s2v(驱动音频)、wan2.7-i2v、豆包、MiniMax H3 |
平台按型号把这些角色转换成厂商字段(例如千问 *-i2v 的 img_url、*-kf2v 的 first_frame_url / last_frame_url、wan2.7 / wan3 / HappyHorse 的 media 列表、豆包的 content 列表)。少数型号使用厂商原生的对象形式,直接把 input 写成对象:wan2.7-videoedit 用 { "media": [{ "type": "video", "url": "…" }] },wanx2.1-vace-plus 用 { "function": "image_reference", "ref_images_url": ["…"] }。
素材限制:
- URL 必须能被厂商公网访问。
- 每次最多 20 张图片、8 段视频、合计 30 个素材,超出返回
422 too_many_input_media。 - 参考视频会被平台下载以测量时长(每个不超过 75 MiB、1 小时),下载失败返回
422 input_media_unavailable,时长无效返回422 media_duration_invalid。测得的时长用于预留费用,结算以厂商返回的用量为准。 wan2.6-r2v*、wan2.7-r2v*使用参考视频时,参考素材(图片与视频合计)最多 5 个,超出返回422 reference_count_not_priced。
时长与分辨率#
| 型号 | 规则 |
|---|---|
豆包 doubao-seedance-2-5-* | duration 为 4–30 的整数,-1 表示最长 |
豆包 doubao-seedance-1-0-* | 2–12 的整数,-1 表示最长 |
| 其他豆包 Seedance | 4–15 的整数,-1 表示最长 |
| 豆包分辨率 | 只接受 480P、720P、1080P、4K,否则返回 422 video_resolution_invalid |
| 千问、MiniMax、智谱 | 以厂商文档为准;平台验收示例见下文 |
豆包 Seedance 按视频 token 计费:平台根据时长、分辨率与参考视频时长预留上限,完成后按厂商返回的用量结算。时长不合法返回 422 video_duration_invalid。
响应#
提交后立即返回 202:
{
"id": "result_9a1d…(64 位十六进制)",
"run_id": "cm2…",
"status": "upstream_pending"
}保存 id 与你的 Idempotency-Key,二者都能用于查询。完成后的结果:
{
"id": "result_9a1d…",
"run_id": "cm2…",
"status": "succeeded",
"billing_status": "succeeded",
"output": {
"id": "厂商任务 ID",
"model": "wan2.7-t2v",
"data": [
{ "url": "https://…cos.ap-nanjing.myqcloud.com/…?sign=…", "asset_id": "asset_…", "mime_type": "video/mp4" }
],
"usage": { "…": "厂商返回的用量" }
},
"status_code": 200,
"response_type": "application/json"
}url 最多 300 秒内有效,过期后用 GET /v1/assets/{asset_id}/download-url 重新获取;文件保留 30 天。厂商任务 24 小时内未完成时,调用进入 needs_review。
示例#
文生视频并下载#
REQUEST_KEY="$(uuidgen)"
curl https://api.tokentosea.com/v1/videos \
-H "Authorization: Bearer $TOKENTOSEA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $REQUEST_KEY" \
-d '{
"model": "wan2.7-t2v",
"prompt": "A red cube slowly rotates on a white table. Steady camera.",
"duration": 5,
"resolution": "720P",
"size": "1280*720"
}'
# 每 10 秒查询一次,直到 status 为 succeeded 或 failed
curl "https://api.tokentosea.com/v1/results/$REQUEST_KEY" \
-H "Authorization: Bearer $TOKENTOSEA_API_KEY"import os
import time
import uuid
import requests
API = "https://api.tokentosea.com/v1"
HEADERS = {"Authorization": "Bearer " + os.environ["TOKENTOSEA_API_KEY"]}
request_key = str(uuid.uuid4())
submitted = requests.post(
API + "/videos",
headers={**HEADERS, "Idempotency-Key": request_key},
json={
"model": "wan2.7-t2v",
"prompt": "A red cube slowly rotates on a white table. Steady camera.",
"duration": 5,
"resolution": "720P",
"size": "1280*720",
},
timeout=120,
)
if submitted.status_code != 202:
raise RuntimeError(f"{submitted.status_code}: {submitted.text}")
result_id = submitted.json()["id"]
while True:
time.sleep(10)
result = requests.get(API + "/videos/" + result_id, headers=HEADERS, timeout=30).json()
if result["status"] == "succeeded":
break
if result["status"] == "failed":
raise RuntimeError(result.get("error"))
print("status:", result["status"])
video = result["output"]["data"][0]
with open("video.mp4", "wb") as file: # 链接 300 秒内有效
file.write(requests.get(video["url"], timeout=300).content)
print("saved video.mp4, asset_id =", video["asset_id"])import { randomUUID } from 'node:crypto';
import { writeFile } from 'node:fs/promises';
const API = 'https://api.tokentosea.com/v1';
const headers = { Authorization: `Bearer ${process.env.TOKENTOSEA_API_KEY}` };
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const submitted = await fetch(`${API}/videos`, {
method: 'POST',
headers: { ...headers, 'Content-Type': 'application/json', 'Idempotency-Key': randomUUID() },
body: JSON.stringify({
model: 'wan2.7-t2v',
prompt: 'A red cube slowly rotates on a white table. Steady camera.',
duration: 5,
resolution: '720P',
size: '1280*720',
}),
});
if (submitted.status !== 202) throw new Error(`HTTP ${submitted.status}: ${await submitted.text()}`);
const { id } = await submitted.json();
let result;
for (;;) {
await sleep(10_000);
result = await (await fetch(`${API}/videos/${id}`, { headers })).json();
if (result.status === 'succeeded') break;
if (result.status === 'failed') throw new Error(JSON.stringify(result.error));
console.log('status:', result.status);
}
const video = result.output.data[0];
const file = await fetch(video.url); // 链接 300 秒内有效
await writeFile('video.mp4', Buffer.from(await file.arrayBuffer()));
console.log('saved video.mp4, asset_id =', video.asset_id);各厂商的请求体#
以下请求体来自平台验收示例,提交与查询方式同上。
{
"model": "wan2.7-i2v",
"prompt": "A red cube slowly rotates on a white table. Steady camera.",
"duration": 5,
"resolution": "720P",
"input": [{ "role": "first_frame", "url": "https://example.com/first.png" }]
}{
"model": "wan2.2-kf2v-flash",
"prompt": "A red cube slowly rotates on a white table. Steady camera.",
"duration": 5,
"resolution": "480P",
"input": [
{ "role": "first_frame", "url": "https://example.com/first.png" },
{ "role": "last_frame", "url": "https://example.com/last.png" }
]
}{
"model": "wan2.2-s2v",
"prompt": "A red cube slowly rotates on a white table. Steady camera.",
"duration": 6,
"resolution": "480P",
"input": [
{ "role": "first_frame", "url": "https://example.com/portrait.png" },
{ "role": "reference_audio", "url": "https://example.com/voice.wav" }
]
}{
"model": "doubao-seedance-2-0-260128",
"prompt": "A red cube slowly rotates on a white table. Steady camera.",
"duration": 4,
"resolution": "480p",
"watermark": true
}{
"model": "MiniMax-Hailuo-2.3-Fast",
"prompt": "A red cube slowly rotates on a white table. Steady camera.",
"duration": 6,
"resolution": "768P",
"provider_options": { "first_frame_image": "https://example.com/first.png" }
}{
"model": "cogvideox-3",
"prompt": "A red cube slowly rotates on a white table. Steady camera.",
"duration": 5,
"quality": "speed",
"size": "1280x720",
"fps": 30,
"with_audio": false
}每个型号的完整示例与价格见模型目录。
错误#
| 状态码 | code | 原因与处理 |
|---|---|---|
422 | video_input_invalid | input 中有不支持的 role,或缺少 url |
422 | unsupported_video_role | 该型号不接受这个角色,或同一角色重复 |
422 | video_duration_invalid、video_resolution_invalid | 豆包 Seedance 的时长或分辨率不合法 |
422 | too_many_input_media、reference_count_not_priced | 参考素材过多 |
422 | input_media_unavailable、media_duration_invalid | 参考视频无法下载或时长无效 |
422 | response_mode_not_verified | 视频接口不支持流式 |
400 | main_wallet_authorization_failed | 所选分辨率、时长等条件在价格表中没有对应规则 |
4xx | provider_http_<状态码> | 厂商拒绝了任务,未扣费 |
任务提交后的失败(例如厂商审核不通过)体现在结果的 status: "failed" 与 error.code 中。