参考图片
支持 JPEG、PNG、WebP。建议每张不超过 20 MiB;只有图片支持 Data URL。与其他参考素材组合时使用数组。
通过一个异步接口完成文生视频、图生视频和多素材参考生成。 支持原生音频和 Standard、720p、1080p 三档输出。Standard 与 720p 最长 15 秒, 1080p 最长只能生成 12 秒。
POST /v1/videos
GET /v1/videos/{task_id}
GET /v1/videos/{task_id}/content
发送 JSON 请求即可创建生成任务。响应中的 id 是后续查询和下载使用的任务标识。
curl -X POST "https://new.fluapi.com/v1/videos" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Idempotency-Key: YOUR_UNIQUE_BUSINESS_REQUEST_ID" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.0",
"prompt": "电影感的清晨海面,柔和金色阳光穿过薄雾,一艘白色帆船缓慢驶过,镜头平稳横移,真实自然,环境中有轻微海浪声",
"seconds": 4,
"size": "864x496",
"audio": false
}'
上面的 864x496、4 秒、关闭音频请求组合适合首次接入和低成本联调。 创建请求必须携带 Idempotency-Key。
所有请求均携带 API Key;创建视频任务时还必须携带幂等键。不要把真实密钥写进网页、公开仓库或客户端安装包。
Flu API 使用标准 Bearer 鉴权格式。服务端环境建议通过环境变量注入密钥。
Authorization: Bearer YOUR_API_KEY
Idempotency-Key: YOUR_UNIQUE_BUSINESS_REQUEST_ID
Content-Type: application/json
生产环境不要从浏览器直接调用并暴露 API Key。应由你自己的后端服务代为请求 Flu API。
网络超时重试同一个创建请求时必须沿用原 Idempotency-Key:同键同参数返回原任务,
同键不同参数返回 409。查询状态和下载内容不需要幂等键。
创建、查询和下载必须使用同一个 New API 账户/API Key。
推荐优先使用 seconds 与精确 size。兼容字段用于迁移旧客户端。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
model必填 |
string | — | 固定传 seedance-2.0。 |
prompt必填 |
string | — | 描述主体、环境、动作、镜头、风格、对白和音效。 |
seconds推荐 |
integer | numeric string | 8 | 生成时长。Standard、720p 允许 4 至 15;1080p 只允许 4 至 12。数字和数字字符串均可。 |
size推荐 |
string | 864x496 | 精确输出尺寸,例如 1280x720、1080x1920。 |
audio可选 |
boolean | true | 是否生成原生音频。可在提示词中描述对白、环境声、音效或配乐。 |
input_reference可选 |
string | string[] | — | 字符串表示单张起始帧;数组表示最多 4 张语义参考图。与视频或音频组合时建议使用数组,即使只有 1 张图。 |
video_reference可选 |
string | string[] | — | 最多 3 段参考视频,使用 HTTPS URL 或已上传素材 UUID。 |
audio_reference可选 |
string | string[] | — | 最多 1 段参考音频,使用 HTTPS URL 或已上传素材 UUID。不能单独使用,必须同时提供图片或视频参考。 |
duration兼容 |
integer | numeric string | 8 | seconds 的兼容别名。不要同时传两个时长字段;1080p 使用该字段时同样不得超过 12。 |
resolution兼容 |
string | standard | 接受 standard、720p、1080p。已传 size 时无需再传此字段。 |
aspect_ratio兼容 |
string | 16:9 | 与 resolution 配合使用。可用组合见尺寸表。 |
image_url / image兼容 |
string | — | 单张起始帧别名。新项目统一使用 input_reference。 |
时长字段只传一个:"seconds": 4 与
"seconds": "4" 都有效,不要再同时传 duration。
传入 size 后,由尺寸确定分辨率与宽高比。
1080p 请求的时长上限为 12 秒。
同一个接口支持纯文本、单张起始帧和多素材参考。通过请求字段组合切换模式。
仅传提示词与输出参数。提示词建议按"主体 + 动作 + 环境 + 镜头 + 风格 + 声音"组织。
{
"model": "seedance-2.0",
"prompt": "雨夜霓虹街道,一辆黑色跑车从积水中驶过,低机位跟拍,轮胎溅起水花,电影级光影,远处有雷声",
"seconds": 8,
"size": "1280x720",
"audio": true
}
将 input_reference 传为字符串,图片作为视频起始帧。提示词重点描述运动和镜头变化。
{
"model": "seedance-2.0",
"prompt": "镜头缓慢推进,人物衣摆随风摆动,远处竹叶飘落,保持原图人物、服装和构图一致",
"input_reference": "https://example.com/start-frame.jpg",
"seconds": 5,
"size": "1280x720",
"audio": true
}
图片与视频可以组合使用。与视频或音频组合时,图片建议始终使用数组格式。媒体 URL 必须能被服务器直接访问。
{
"model": "seedance-2.0",
"prompt": "保持产品外观、材质与标识一致,采用参考视频的运镜节奏和主体运动方式,生成自然连贯的产品短片",
"input_reference": [
"https://example.com/product.jpg"
],
"video_reference": "https://example.com/motion.mp4",
"seconds": 4,
"size": "864x496",
"audio": false
}
已验证组合:图片 + 视频可正常生成;图片 + 音频也已正常生成。
audio_reference 不能单独提交,必须搭配
input_reference 或 video_reference。
图片可使用 HTTPS URL 或 Data URL;视频与音频必须使用 HTTP(S) URL 或已上传素材 UUID。
支持 JPEG、PNG、WebP。建议每张不超过 20 MiB;只有图片支持 Data URL。与其他参考素材组合时使用数组。
支持 MP4、MOV。每段 3–10 秒,全部参考视频总时长最多 15 秒;使用 HTTP(S) URL 或素材 UUID。
支持 MP3、WAV、M4A、AAC。只允许 1 段,不能使用 Data URL,也不能在没有图片或视频参考时单独提交。
input_reference 的 JSON 类型决定模式。
字符串是单张起始帧,数组是语义图片参考。与视频或音频组合时建议使用数组,即使只有 1 张图片。不要同时再传
image_url 或 image。
费用按最终请求的分辨率档位和生成秒数计算。提交前应在业务侧向用户明确展示预计费用。
快速预览与低成本内容
常规内容发布与社交媒体
高清成片与专业交付 · 最长 12 秒
| 宽高比 | Standard / 480p | 720p | 1080p |
|---|---|---|---|
| 16:9 | 864x496 | 1280x720 | 1920x1080 |
| 9:16 | 496x864 | 720x1280 | 1080x1920 |
| 1:1 | 640x640 | 960x960 | 1080x1080 |
| 4:3 | 752x560 | 1112x834 | 1440x1080 |
| 3:4 | 560x752 | 834x1112 | 834x1112 * |
| 21:9 | 992x432 | 1470x630 | 2520x1080 |
| 9:21 | 432x992 | — | 1080x2520 |
* 1080p 3:4:当前兼容尺寸为 834x1112。
接口不支持 4K,请严格使用表中尺寸。所有 1080p 尺寸最长只能生成 12 秒。
Seedance 2.0 是异步生成接口。客户端超时不代表任务失败,应保留任务 ID 并继续查询最终状态。
携带稳定的幂等键提交参数,读取响应中的 id。
POST /v1/videos
首次等待 8 秒,之后每 8–10 秒轮询一次。
GET /v1/videos/{task_id}
任务完成后请求内容端点,并允许 HTTP 重定向。
GET /v1/videos/{task_id}/content
queued
已排队,等待生成
in_progress
生成中,可读取 progress
completed
生成完成,可以下载
failed
生成失败,检查 error
1080p 长任务建议设置至少 25 分钟的总等待时间。拿到任务 ID 后不要因等待较长而盲目重新提交,
否则可能重复计费。创建请求如因网络超时需要重试,必须沿用原来的 Idempotency-Key。
以下示例均包含创建、轮询与下载。代码使用环境变量 FLUAPI_API_KEY 注入密钥,并使用稳定的 FLUAPI_REQUEST_ID 作为业务幂等键。
BASE_URL="https://new.fluapi.com/v1"
: "${FLUAPI_API_KEY:?set FLUAPI_API_KEY}"
: "${FLUAPI_REQUEST_ID:?set a stable business request id}"
TASK_ID=$(curl -sS -X POST "$BASE_URL/videos" \
-H "Authorization: Bearer $FLUAPI_API_KEY" \
-H "Idempotency-Key: $FLUAPI_REQUEST_ID" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.0",
"prompt": "清晨海面上的白色帆船,镜头平稳横移,电影感光影,轻微海浪声",
"seconds": 4,
"size": "864x496",
"audio": false
}' | jq -r '.id')
test -n "$TASK_ID" || { printf 'missing task id\n'; exit 1; }
DEADLINE=$(( $(date +%s) + 1500 ))
while true; do
RESULT=$(curl -sS "$BASE_URL/videos/$TASK_ID" \
-H "Authorization: Bearer $FLUAPI_API_KEY")
STATUS=$(printf '%s' "$RESULT" | jq -r '.status')
printf 'status=%s\n' "$STATUS"
[ "$STATUS" = "completed" ] && break
[ "$STATUS" = "failed" ] && printf '%s\n' "$RESULT" && exit 1
[ "$(date +%s)" -ge "$DEADLINE" ] && exit 2
sleep 8
done
curl -L "$BASE_URL/videos/$TASK_ID/content" \
-H "Authorization: Bearer $FLUAPI_API_KEY" \
--output seedance-result.mp4
import os
import time
import requests
BASE_URL = "https://new.fluapi.com/v1"
API_KEY = os.environ["FLUAPI_API_KEY"]
REQUEST_ID = os.environ["FLUAPI_REQUEST_ID"] # 同一业务请求及其重试必须复用
AUTH = {"Authorization": f"Bearer {API_KEY}"}
payload = {
"model": "seedance-2.0",
"prompt": "清晨海面上的白色帆船,镜头平稳横移,电影感光影,轻微海浪声",
"seconds": 4,
"size": "864x496",
"audio": False,
}
created = requests.post(
f"{BASE_URL}/videos",
headers={
**AUTH,
"Idempotency-Key": REQUEST_ID,
"Content-Type": "application/json",
},
json=payload,
timeout=60,
)
created.raise_for_status()
task_id = created.json()["id"]
deadline = time.monotonic() + 25 * 60
while True:
response = requests.get(
f"{BASE_URL}/videos/{task_id}",
headers=AUTH,
timeout=30,
)
response.raise_for_status()
task = response.json()
print(task["status"], task.get("progress"))
if task["status"] == "completed":
break
if task["status"] == "failed":
error = task.get("error") or {}
raise RuntimeError(error.get("message") or error or task)
if time.monotonic() >= deadline:
raise TimeoutError(f"poll timeout; retain task_id={task_id}")
time.sleep(8)
with requests.get(
f"{BASE_URL}/videos/{task_id}/content",
headers=AUTH,
timeout=120,
stream=True,
allow_redirects=True,
) as video:
video.raise_for_status()
with open("seedance-result.mp4", "wb") as output:
for chunk in video.iter_content(chunk_size=1024 * 1024):
if chunk:
output.write(chunk)
import { writeFile } from "node:fs/promises";
const baseUrl = "https://new.fluapi.com/v1";
const apiKey = process.env.FLUAPI_API_KEY;
const requestId = process.env.FLUAPI_REQUEST_ID; // 同一业务请求及其重试必须复用
if (!apiKey || !requestId) {
throw new Error("Set FLUAPI_API_KEY and FLUAPI_REQUEST_ID");
}
const auth = { Authorization: `Bearer ${apiKey}` };
const createdResponse = await fetch(`${baseUrl}/videos`, {
method: "POST",
headers: {
...auth,
"Idempotency-Key": requestId,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "seedance-2.0",
prompt: "清晨海面上的白色帆船,镜头平稳横移,电影感光影,轻微海浪声",
seconds: 4,
size: "864x496",
audio: false,
}),
});
if (!createdResponse.ok) {
throw new Error(await createdResponse.text());
}
const { id: taskId } = await createdResponse.json();
const deadline = Date.now() + 25 * 60 * 1000;
let task;
do {
await new Promise((resolve) => setTimeout(resolve, 8000));
const response = await fetch(`${baseUrl}/videos/${taskId}`, {
headers: auth,
});
if (!response.ok) throw new Error(await response.text());
task = await response.json();
console.log(task.status, task.progress);
if (task.status === "failed") {
throw new Error(task.error?.message || JSON.stringify(task.error || task));
}
if (Date.now() >= deadline) {
throw new Error(`Poll timeout; retain task_id=${taskId}`);
}
} while (task.status !== "completed");
const videoResponse = await fetch(`${baseUrl}/videos/${taskId}/content`, {
headers: auth,
redirect: "follow",
});
if (!videoResponse.ok) throw new Error(await videoResponse.text());
await writeFile(
"seedance-result.mp4",
Buffer.from(await videoResponse.arrayBuffer()),
);
创建响应至少应读取任务 ID。查询响应中以 status 作为最终状态判断依据。
{
"id": "task_xxxxxxxxxxxxxxxxxxxxx",
"object": "video",
"model": "seedance-2.0",
"status": "queued"
}
{
"id": "task_xxxxxxxxxxxxxxxxxxxxx",
"object": "video",
"model": "seedance-2.0",
"status": "in_progress",
"progress": 50,
"seconds": "5",
"size": "864x496"
}
下载请求必须允许重定向。cURL 使用 -L,Python Requests 使用 allow_redirects=True。
记录 HTTP 状态码、响应体、任务 ID 与原始参数。失败任务不要无限轮询,也不要无条件重新提交。
| 状态 | 含义 | 处理方式 |
|---|---|---|
| 400 | 请求参数错误 | 检查是否缺少 Idempotency-Key、时长/尺寸是否有效、是否单独提交了音频,以及素材数量和 URL 是否符合限制。 |
| 401 | 鉴权失败 | 检查 API Key 是否缺失、失效,以及是否使用 Bearer 格式。 |
| 404 | 任务不存在 | 检查任务 ID 是否正确,并确认任务属于当前 Flu API 账户。 |
| 409 | 幂等冲突或视频未就绪 | 同一幂等键不得对应不同请求体;下载接口返回 409 时继续查询任务状态,不要重复创建。 |
| 429 | 限流或队列限制 | 降低提交和轮询频率,读取响应体,并使用带随机抖动的指数退避。 |
| 503 | 账号或上游暂不可用 | 保留请求体和幂等键,有限次数重试;不要为每次重试生成新键。 |
| 5xx | 服务端或生成服务异常 | 保留完整响应体,仅对可重试错误执行有限次数重试,并沿用原幂等键。 |
| failed | 生成任务失败 | 保留任务 ID 并读取 error.message;不要换新幂等键盲目重投。 |
建议最多重试 3 次,退避间隔可使用 1 秒、2 秒、4 秒并加入随机抖动。 每个业务创建请求使用一个稳定幂等键;只有明确发起新的生成任务时才创建新键。
在生产流量接入前,确认密钥、计费、任务持久化和异常恢复策略已经落地。