想先在浏览器里体验?打开 API 参考 → 创建视频生成任务,填入你的
sk- API Key 即可试一试在线发起真实请求。文生视频、图生视频、多模态参考共用同一个接口,仅靠
content 数组的组合区分模式。模型清单、定价与常见问题见 能力总览。接入前请注意以下差异点,可以避开绝大多数排障时间:
- Base URL 为
https://api.looprouter.com,完整路径是/api/v3/contents/generations/tasks,/api前缀不能省略。 resolution可用档位由 API Key 所在分组决定:VIP 组支持480p、720p、1080p、4k全档位,补贴组支持720p、1080p。传入分组外的档位会直接返回 400,不会扣费。- 本接口不支持
callback_url回调,传入会返回 400;请使用轮询查询任务状态。 - 成功状态是
succeeded(不是completed);成片content.video_url为临时链接,请在 2 小时内转存。 - Python
requests用户建议加请求头Accept-Encoding: identity,避免个别网络环境下 gzip 解码异常导致响应截断。
代码示例
curl -X POST "https://api.looprouter.com/api/v3/contents/generations/tasks" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $LOOPROUTER_API_KEY" \
-d '{
"model": "doubao-seedance-2-0-260128",
"content": [
{
"type": "text",
"text": "雨后的城市街道,霓虹灯倒映在积水中,一只橘猫从画面左侧慢慢走过"
}
],
"resolution": "720p",
"ratio": "16:9",
"duration": 5
}'
# 返回:{"id": "task_xxxx"} —— 只返回任务 ID,视频需轮询查询接口获取
import time
import requests
BASE = "https://api.looprouter.com"
HEADERS = {
"Authorization": "Bearer sk-你的APIKey",
"Accept-Encoding": "identity", # 避免个别环境 gzip 解码异常
}
# 1. 创建任务
resp = requests.post(
f"{BASE}/api/v3/contents/generations/tasks",
headers=HEADERS,
json={
"model": "doubao-seedance-2-0-260128",
"content": [
{"type": "text", "text": "雨后的城市街道,霓虹灯倒映在积水中,一只橘猫从画面左侧慢慢走过"}
],
"resolution": "720p",
"ratio": "16:9",
"duration": 5,
# "generate_audio": True, # 默认开启同步音频
# "seed": 42, # 固定随机种子,结果更可复现
},
)
resp.raise_for_status()
task_id = resp.json()["id"]
print("任务已创建:", task_id)
# 2. 轮询任务状态(建议 15~30 秒一次)
while True:
task = requests.get(
f"{BASE}/api/v3/contents/generations/tasks/{task_id}",
headers=HEADERS,
).json()
status = task["status"]
print("当前状态:", status)
if status in ("succeeded", "failed", "cancelled", "expired"):
break
time.sleep(20)
# 3. 下载成片(下载时不要携带 Authorization 头)
if status == "succeeded":
video_url = task["content"]["video_url"]
with requests.get(video_url, stream=True) as r:
r.raise_for_status()
with open("output.mp4", "wb") as f:
for chunk in r.iter_content(chunk_size=1 << 20):
f.write(chunk)
print("已保存 output.mp4")
else:
print("任务未成功:", task.get("error"))
# 模式二:首尾帧图生视频 —— 用两张图约束视频的第一帧和最后一帧
first_last_frame_body = {
"model": "doubao-seedance-2-0-260128",
"content": [
{"type": "text", "text": "镜头缓缓推进,人物转身微笑"},
{"type": "image_url", "image_url": {"url": "https://example.com/first.jpg"}, "role": "first_frame"},
{"type": "image_url", "image_url": {"url": "https://example.com/last.jpg"}, "role": "last_frame"},
],
"resolution": "1080p",
"duration": 5,
}
# 模式三:多模态参考 —— 参考图 / 参考视频 / 参考音频自由组合
multimodal_body = {
"model": "doubao-seedance-2-0-260128",
"content": [
{"type": "text", "text": "图片1中的角色在草地上奔跑,参考视频1的运镜节奏"},
{"type": "image_url", "image_url": {"url": "asset://asset-20260709190143-ntwhb"}, "role": "reference_image"},
# {"type": "video_url", "video_url": {"url": "https://example.com/ref.mp4"}, "role": "reference_video"},
# {"type": "audio_url", "audio_url": {"url": "https://example.com/voice.mp3"}, "role": "reference_audio"},
],
"resolution": "720p",
"ratio": "adaptive",
"duration": -1, # -1 表示由模型自行决定时长,按实际产出计费
}
const BASE = "https://api.looprouter.com";
const KEY = process.env.LOOPROUTER_API_KEY;
async function main() {
// 创建任务
const createRes = await fetch(`${BASE}/api/v3/contents/generations/tasks`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${KEY}`,
},
body: JSON.stringify({
model: "doubao-seedance-2-0-260128",
content: [
{ type: "text", text: "雨后的城市街道,霓虹灯倒映在积水中,一只橘猫从画面左侧慢慢走过" },
],
resolution: "720p",
ratio: "16:9",
duration: 5,
}),
});
const { id } = await createRes.json();
console.log("任务已创建:", id);
// 轮询
for (;;) {
await new Promise((r) => setTimeout(r, 20000));
const task = await (
await fetch(`${BASE}/api/v3/contents/generations/tasks/${id}`, {
headers: { Authorization: `Bearer ${KEY}` },
})
).json();
console.log("当前状态:", task.status);
if (["succeeded", "failed", "cancelled", "expired"].includes(task.status)) {
if (task.status === "succeeded") console.log("视频地址:", task.content.video_url);
else console.error("任务未成功:", task.error);
break;
}
}
}
main();
curl "https://api.looprouter.com/api/v3/contents/generations/tasks/task_xxxx" \
-H "Authorization: Bearer $LOOPROUTER_API_KEY"
请求参数速查
POST /api/v3/contents/generations/tasks,请求头 Authorization: Bearer sk-...。
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
model | string | 是 | — | 如 doubao-seedance-2-0-260128,可用模型以控制台「模型广场」为准 |
content | array | 是 | — | 生成素材数组,见下方内容项说明 |
resolution | string | 否 | 上游默认 | 480p / 720p / 1080p / 4k,可用档位依分组(VIP 组全档位,补贴组 720p / 1080p),分组外档位返回 400 且不扣费 |
ratio | string | 否 | adaptive | 16:9、4:3、1:1、3:4、9:16、21:9、adaptive |
duration | int | 否 | 5 | 输出时长(秒),范围 4–15;传 -1 由模型决定并按实际产出计费 |
generate_audio | bool | 否 | true | 是否生成与画面同步的音频(人声/音效/配乐) |
watermark | bool | 否 | false | 是否叠加 AI 生成水印 |
seed | int | 否 | -1 | 随机种子;相同种子产出相近(非完全一致)的结果 |
return_last_frame | bool | 否 | false | 成功后额外返回末帧图片,便于多段续接 |
execution_expires_after | int | 否 | 172800 | 任务执行超时(秒),超时未完成转为 expired |
callback_url 在本平台不受支持,传入会返回 400。Seedance 1.x 的 frames、camera_fixed 等参数对 2.0 模型无效,请勿依赖。content 数组
每个元素为一个内容项,type 决定其结构:
| type | 结构 | role 取值 | 说明 |
|---|---|---|---|
text | {"type":"text","text":"..."} | — | 提示词。建议中文 ≤500 字、英文 ≤1000 词;台词放在双引号内可提升配音效果 |
image_url | {"type":"image_url","image_url":{"url":"..."},"role":"..."} | first_frame / last_frame / reference_image | 支持公网 URL、Base64 data URI、asset://素材ID |
video_url | {"type":"video_url","video_url":{"url":"..."},"role":"reference_video"} | reference_video | 参考视频,最多 3 个;携带视频输入享受计费折扣 |
audio_url | {"type":"audio_url","audio_url":{"url":"..."},"role":"reference_audio"} | reference_audio | 参考音频 wav/mp3,单段 2–15 秒,最多 3 段,不能单独出现 |
asset:// 引用。
生成模式
| 模式 | content 组合 |
|---|---|
| 文生视频 | 1 个 text |
| 首帧图生视频 | 可选 text + 1 个 image_url(role 可省略) |
| 首尾帧图生视频 | 可选 text + 2 个 image_url(role 必须分别为 first_frame、last_frame) |
| 多模态参考 | text + 0–9 张参考图 + 0–3 个参考视频 + 0–3 段参考音频(至少 1 图或 1 视频) |
查询任务
GET /api/v3/contents/generations/tasks/{task_id}
任务状态机:queued → running → succeeded / failed / cancelled / expired。任务记录长期保留,可随时回查。
成功响应示例:
{
"id": "task_xxxx",
"model": "doubao-seedance-2-0-260128",
"status": "succeeded",
"content": {
"video_url": "https://api.looprouter.com/.../output.mp4?...",
"last_frame_url": ""
},
"usage": {
"completion_tokens": 246840,
"total_tokens": 246840
},
"seed": 42,
"resolution": "720p",
"ratio": "16:9",
"duration": 5,
"framespersecond": 24,
"generate_audio": true,
"created_at": 1752940800,
"updated_at": 1752941020
}
成片地址在
content.video_url 字段,为临时签名链接(约 2 小时有效),请及时转存;下载时请求中不要携带 Authorization 头。usage.total_tokens 为上游按「时长 × 分辨率像素 × 帧率」口径折算的视频 token 数,是结算依据。使用 duration: -1 或 ratio: adaptive 时,以响应中回填的实际值为准。任务列表与取消
本平台在原厂接口之外额外提供两个管理接口: 列出任务 —GET /api/v3/contents/generations/tasks
| 查询参数 | 说明 |
|---|---|
page_num | 页码,默认 1 |
page_size | 每页数量,默认 20,最大 500 |
filter.status | 按状态过滤:queued / running / succeeded / failed / cancelled |
filter.model | 按模型过滤 |
filter.task_ids | 按任务 ID 列表过滤 |
{"items": [...], "total": n},元素结构与查询单个任务一致。
取消/删除任务 — DELETE /api/v3/contents/generations/tasks/{task_id}
排队中的任务可以取消;running 状态的任务不可取消(返回 400 invalid_task_status)。成功返回 {}。
错误响应
所有错误采用与火山引擎一致的结构:{
"error": {
"code": "invalid_request",
"message": "具体错误描述 (request id: ...)",
"param": "",
"type": "BadRequest"
}
}
| HTTP 状态码 | type | 常见原因 |
|---|---|---|
| 400 | BadRequest | 缺少 model/content;resolution 不在当前分组可用档位内;传了 callback_url;取消运行中任务 |
| 401 | Unauthorized | API Key 缺失或无效 |
| 403 | Forbidden | 令牌无权访问该模型;内容审核未通过(如真实人脸直传) |
| 404 | NotFound | 任务 ID 不存在或不属于当前账号 |
| 429 | RateLimitExceeded | 当前分组上游负载已饱和,请稍后再试 |
| 5xx | InternalServerError | 服务端异常,建议指数退避后重试 |
429 与 5xx 建议采用指数退避重试(如 2s → 4s → 8s)。参数校验失败(400)与内容审核拒绝(403)均不扣费;已预扣的失败任务会自动退款。
相关文档
能力总览与定价
模型清单、技术规格、计费规则
素材引用实战
从上传素材到角色一致性生成的完整链路
在线调试
在文档内直接试一试