Doubao · 生成

提交异步视频任务;任务查询路径和响应格式因模型而异。

POST/v1/video/generations

异步任务

查看候选模型 ID
模型 ID厂商类型说明上下文窗口最大输出 Token媒体规格价格状态
Doubao-Seedance-2.0
Doubao视频文生视频、图生视频、多参考素材生成、编辑和延长——
查看规格

型号:Doubao-Seedance-2.0

生成方式:文生视频、图生视频、参考生视频、视频编辑、视频延长;分辨率:480P–1080P;时长:4–15 秒;参考素材上限:9 张图片、3 段视频、3 段音频;音频生成:支持

查看价格

型号:Doubao-Seedance-2.0

$0.0567

币种:USD;计价单位:秒起;页面折扣:8.5折;资料日期:2026-09-28

登录页面参考价

登录模型广场展示价,含页面折扣;以当前账户价格和账单为准。

—
Doubao-Seedance-2.0-cloud
Doubao视频文生视频、图生视频、续写、多素材参考和音画同步——
查看规格

型号:Doubao-Seedance-2.0-cloud

生成方式:文生视频、图生视频、参考生视频、视频延长;分辨率:最高 1080P;时长:4–30 秒;参考素材上限:9 张图片、3 段视频、3 段音频;音频生成:支持

查看价格

型号:Doubao-Seedance-2.0-cloud

$1.8550

币种:USD;计价单位:1M 输出 Tokens 起;页面折扣:8折;资料日期:2026-09-28

登录页面参考价

登录模型广场展示价,含页面折扣;以当前账户价格和账单为准。

—
Doubao-Seedance-2.0-fast
Doubao视频文生视频、图生视频和音画同步——
查看规格

型号:Doubao-Seedance-2.0-fast

生成方式:文生视频、图生视频、参考生视频;分辨率:480P–1080P;时长:4–15 秒;音频生成:支持

查看价格

型号:Doubao-Seedance-2.0-fast

$0.0261

币种:USD;计价单位:秒起;页面折扣:5折;资料日期:2026-09-28

登录页面参考价

登录模型广场展示价,含页面折扣;以当前账户价格和账单为准。

—
Doubao-Seedance-2.5
Doubao视频多素材参考、视频编辑和延长——
查看规格

型号:Doubao-Seedance-2.5

生成方式:文生视频、参考生视频、视频编辑、视频延长;时长:最长 30 秒;参考素材上限:50 个素材:30 图、10 视频、10 音频

查看价格

型号:Doubao-Seedance-2.5

$0.0900

币种:USD;计价单位:秒起;页面折扣:9折;资料日期:2026-09-28

登录页面参考价

登录模型广场展示价,含页面折扣;以当前账户价格和账单为准。

—
Seedance-2.0-mini
Doubao视频文生视频、图生视频、首尾帧和多素材参考——
查看规格

型号:Seedance-2.0-mini

生成方式:文生视频、图生视频、参考生视频;时长:4–15 秒;分辨率:最高 720P / 24fps;音频生成:支持

查看价格

型号:Seedance-2.0-mini

$0.0127

币种:USD;计价单位:秒起;页面折扣:3.8折;资料日期:2026-09-28

登录页面参考价

登录模型广场展示价,含页面折扣;以当前账户价格和账单为准。

—

按公开标签归类,并补充模型广场资料;— 表示暂无明确资料。左右滑动查看完整表格。

进阶用法与完整流程 · 参数与透传

素材库管理与引用 →

生成效果示例

Headers请求头

左右滑动查看完整参数表

请求头
参数名类型必填说明默认值 / 示例
Authorizationstring必填

平台 API Key,使用 Bearer 认证。

示例
Bearer YOUR_API_KEY
Content-Typestring必填

请求体编码格式。

示例
application/json

Request Body请求体

application/json

左右滑动查看完整参数表

请求体
参数名类型必填说明默认值 / 示例
modelstring必填

平台完整模型 ID,区分大小写和后缀;六个平台接入例子使用 Doubao-Seedance-2.0-fast。

示例
Doubao-Seedance-2.0-fast
contentarray可选

对 Doubao-Seedance-2.0-fast 必填

平台 2.0 示例的输入内容数组;使用 content 写法时必须提供。已有 2.5 prompt/metadata 写法单独保留,勿机械合并。

—
content[] 的子字段 6
content[] 子字段
参数名类型必填说明默认值 / 示例
typestring必填

单个内容项的模态,决定下方应填写的子字段。

可选值textimage_urlvideo_urlaudio_url
—
textstring可选

type=text 时提供提示词;媒体场景按同类素材序号指代。

—
image_urlobject可选

当 type=image_url 时提供;url 需要可公开下载。

—
content[].image_url 的子字段 1
content[].image_url 子字段
参数名类型必填说明默认值 / 示例
urlstring必填

对应模态的素材 URL;示例使用需替换的 example.com 占位地址。

—
video_urlobject可选

当 type=video_url 时提供;url 需要可公开下载。

—
content[].video_url 的子字段 1
content[].video_url 子字段
参数名类型必填说明默认值 / 示例
urlstring必填

对应模态的素材 URL;示例使用需替换的 example.com 占位地址。

—
audio_urlobject可选

当 type=audio_url 时提供;url 需要可公开下载。

—
content[].audio_url 的子字段 1
content[].audio_url 子字段
参数名类型必填说明默认值 / 示例
urlstring必填

对应模态的素材 URL;示例使用需替换的 example.com 占位地址。

—
rolestring可选

用途角色:首尾帧和参考图按用途必填,视频和音频例子显式传齐。首尾帧与参考场景互斥。

可选值first_framelast_framereference_imagereference_videoreference_audio
—
durationinteger可选

生成时长(秒)。平台接入例子为 4/5/8;官方 2.0 普通输出为 4–15 或 -1,2.5 为 4–30 或 -1,编辑另有条件。

示例
4
resolutionstring可选

平台接入例子使用小写 480p/720p。官方 fast/mini 为 480p/720p,2.0 和 2.5 其他规格按型号核对。

示例
480p
ratiostring可选

平台接入例子使用 16:9。官方 2.5 的首帧、首尾帧、编辑、延长只允许 adaptive;平台映射按通道确认。

可选值16:94:31:13:49:1621:9adaptive
—
generate_audioboolean可选

平台接入文档中含视频或音频参考的例子在顶层传 true;官方默认 true,false 为无声输出。

示例
true
promptstring可选

平台已有 2.5 兼容写法的视频提示词;2.0 content 示例把文本放在 type=text 项中。

—
imagestring可选

平台通用图生字段,具体型号映射另行确认;本组平台样例使用 content[].image_url.url。

—
secondsstring可选

平台已有 2.5 兼容写法的秒数字符串,和 duration、metadata.duration 保持一致。

示例
4
metadataobject可选

平台已有 2.5 兼容写法的扁平扩展参数;content 平台接入示例不使用此包装。

—
metadata 的子字段 4
metadata 子字段
参数名类型必填说明默认值 / 示例
resolutionstring可选

已有 2.5 模板的分辨率,例如 480p。

—
ratiostring可选

已有 2.5 模板的宽高比,例如普通文生的 16:9。

—
durationinteger可选

已有 2.5 模板时长,和顶层 duration/seconds 保持一致。

—
generate_audioboolean可选

已有 2.5 模板的同步音频开关。

—

使用说明

  • 平台 2.0 示例使用顶层 content、duration、resolution,ratio/generate_audio 按场景填写;已有 2.5 prompt/metadata 模板单独保留。
  • 首帧、首尾帧和全模态参考互斥;2.0 系列参考音频不能单独输入。
  • 示例媒体 URL 为占位地址,替换公开素材后使用;请求按接入资料整理,模型与通道依账户配置。
  • 创建受理不等于生成完成;保存任务 ID,GET /v1/video/generations/{task_id} 查询同一任务,完成后及时转存结果。
  • 请求超时先核对任务记录,避免重复创建;轮询设置间隔和总时限。官方原生参数与平台兼容字段的映射按型号确认。

六种输入组合

输入组合使用方式
文:纯文本提示词用提示词描述画面和镜头运动。
图 + 文:两张参考图参考图约束角色和画面;reference_image 与首帧用途不同。
图 + 视频 + 文图片控制画面,视频作为动作或镜头参考。
图 + 音频 + 文音频增强节奏与氛围,2.0 系列至少同时输入参考图或视频。
图 + 视频 + 音频 + 文同时参考画面、动作和声音,先检查每种素材的数量、时长与格式。
首帧 + 末帧 + 文分别指定 first_frame 和 last_frame,生成起止画面之间的过渡。

六个平台接入示例均使用完整模型 ID Doubao-Seedance-2.0-fast。示例保留原传参方式,其他型号的素材能力与通道支持需分别核对。

媒体地址 https://example.com/… 是占位符,请替换为公开可下载且符合所选型号规格的素材。示例按接入资料整理,模型与通道依账户配置。

content 与素材用途

content 是内容项数组:文本用 type=text 与 text;媒体使用对应的 URL 对象和 role。

  • 首帧、首尾帧和全模态参考是互斥场景;不在同一请求中混合 first_frame/last_frame 与 reference_image/reference_video/reference_audio。
  • 首帧明确写 first_frame;首尾帧两项分别写 first_frame、last_frame;参考图必须写 reference_image,不能把参考图当成结构化首帧。
  • 提示词按同类素材在数组中的出现顺序写“图片1”“视频1”“音频1”;不同模态各自编号,素材 ID 和名称不代替这些序号。
  • 2.0 系列参考音频不能单独输入,至少同时提供一张参考图或一段参考视频;2.5 原生协议允许单独参考音频,其平台通道支持另行确认。

官方原生图片和音频支持公网 URL、对应模态的 Base64 Data URL 与 asset://ASSET_ID;视频只列公网 URL 和 Asset URI,不提供视频 Base64 示例。Asset URI 放在对应模态对象的 url 字段;其平台生成映射待确认。素材库管理与引用 →

官方媒体规格参考

以下是当前火山官方原生规格,不构成平台配额或所有通道的支持承诺;平台账户限制以对应型号和通道为准。

项目Seedance 2.0 系列Seedance 2.5
参考图片0–9 张0–30 张
参考视频0–3 段;每段 2–15 秒,总时长 ≤15 秒0–10 段;普通参考每段 2–30 秒,编辑每段 4–30 秒,总时长 ≤30 秒
参考音频0–3 段;每段 2–15 秒,总时长 ≤15 秒0–10 段;每段 2–30 秒,总时长 ≤30 秒
输出时长整数 4–15 秒或 -1 智能选择整数 4–30 秒或 -1;编辑只允许 -1
输出分辨率2.0:480p/720p/1080p/4k;fast/mini:480p/720p480p/720p/1080p
首帧/首尾帧/编辑/延长比例支持型号允许的比例或 adaptive仅 adaptive
总素材数量按各模态上限分别核对最多 50:30 图 + 10 视频 + 10 音频
输入格式官方限制
图片jpeg/png/webp/bmp/tiff/gif;2.0 及以上另支持 heic/heif宽高比 [0.4,2.5];边长 [300,6000] px;单张 <30 MB
视频mp4/mov;MP4 为 H.264/H.265 视频、AAC/MP3 音频,MOV 另支持 PCM宽高比 [0.4,2.5];边长 [300,6000] px;总像素 [407696,8295044];24–60 FPS;单个 ≤200 MB
音频wav/mp3单个 ≤15 MB;数量和时长按上表区分型号

原生请求体不超过 64 MB。生成输入规格与素材库入库规格分别核对;素材已入库不代表满足每个视频模型的输入限制。

任务查询与响应字段

GET /v1/video/generations/{task_id} 使用同一平台 Bearer 认证。创建只提交一次,保存 ID,再按适当间隔查询;HTTP 200 或 code=success 仅代表请求成功。

平台接入字段说明
id任务唯一标识;保存创建响应的任务 ID
object平台接入说明为 video
created创建时的 Unix 时间戳
model生成使用的模型名称
status平台接入示例:processing / completed / failed
url完成后可用的视频下载地址
duration返回的视频时长;精确时长需检查媒体文件
resolution返回的视频分辨率

不同通道还可能返回外层 data.status=SUCCESS、data.result_url 或嵌套 status=succeeded、content.video_url。按实际响应读取终态与地址;失败读 fail_reason/error,不要只靠某一种字段位置。

协议范围处理中与终态结果字段
平台接入示例processing → completed / failedurl
火山官方原生queued → running → succeeded / failed;超时 expired;排队取消 cancelledcontent.video_url;失败读 error.code/message

官方原生任务记录保留 7 天,视频 URL 有效期 24 小时,2.5 产物 URL 最多下载 100 次。这些是官方参考条件,平台结果地址有效期以实际响应或平台通知为准;完成后及时转存。

官方原生扩展参考

下表属于火山方舟原生协议,平台映射待确认,以 — 标示。不把原生列表、取消、回调或 Draft 操作拼成未经确认的平台请求。

项目官方说明平台字段/路径映射
watermarkboolean,默认 false;控制水印—
return_last_frameboolean,默认 false;true 时返回 content.last_frame_url 的 JPEG 尾帧—
execution_expires_afterinteger;默认 172800,范围 [3600,259200] 秒,从创建起计时;超时 expired—
priorityinteger 0–9;默认 0,同 Endpoint 排队排序,不能中断 running—
safety_identifier英文字符串 ≤64 字符;使用固定用户标识的哈希,不传原始用户信息—
toolsobject[],type=web_search;用量见 usage.tool_usage.web_search—
callback_url公网地址接收 POST,body 与原生查询一致;按任务 ID 和状态处理重复通知—
查询任务列表GET /contents/generations/tasks;filter.model 为 Endpoint ID;filter.status、filter.task_ids、page_num/page_size;多个 ID 重复传同名参数—
取消/删除DELETE /contents/generations/tasks/{id};queued 可取消;running 不支持;succeeded/failed/expired 可删除记录;cancelled 不支持重复删除—
draft/draft_task仅 2.5 原生:480p 样片,成功后以 draft_task.id 引用;复用字段和禁传字段另核对—
output_format仅 2.5 原生:mp4/mov,默认 mp4—

原生列表默认 page_num=1、page_size=20,二者范围 [1,500],返回 items 和 total。回调正文未给出本组验签算法或严格一次投递保证;取消通知也没有承诺,轮询可作为补充。

当前官方参数表仅列 1.0 pro/pro fast 支持 seed、camera_fixed 和 frames,不将这些字段加入 2.x 请求示例。2.0 系列和 2.5 当前不支持 flex;批量处理由应用按限流提交多个单任务并保存 ID,没有在这里定义批量创建路由。

参考资料

核对日期:2026-10-12。平台请求依据平台接入示例;官方文档用于补充型号条件和原生协议说明。

平台接入示例 ↗ · 官方创建参数 ↗ · 官方任务查询 ↗ · 官方任务列表 ↗ · 官方取消与删除 ↗ · Seedance 2.0 教程 ↗ · Seedance 2.5 教程 ↗

创建、轮询与获取结果

创建请求只提交一次,并立即保存响应中的任务 ID。以下示例先等待 3 秒,再按 5、10、30 秒的间隔查询,之后保持 30 秒间隔;轮询预算为 600 秒。这些数值是客户端示例策略,不是平台频率限制或生成时长承诺。超时后保留任务 ID,后续继续查询同一任务。HTTP 错误、失败、取消及未知状态会停止本轮轮询。

阶段可能的响应位置处理方式
排队status=queued;data.status=NOT_START;output.task_status=PENDING继续查询已有任务
处理中data.status=IN_PROGRESS;嵌套 status=running继续查询已有任务
成功data.status=SUCCESS;嵌套 status=succeeded / task_status=SUCCEEDED读取结果地址并下载
失败或取消FAILURE / failed / cancelled停止轮询,读取 fail_reason / error
结果地址result_url、content.video_url、output.video_url、task.content.url按返回的 HTTPS URL 下载

先把所选模型的完整 JSON 请求体保存为 video-request.json。模型的时长、分辨率、content 与 metadata 结构各不相同,按本页对应模型填写。查询成功的 code=success 不等于视频任务成功。

展开 Python:一次创建、有界轮询与保存视频
Python
# 安装依赖:python -m pip install requests
import json
import os
import tempfile
import time
from pathlib import Path
from urllib.parse import quote, urlsplit
import requests

BASE_URL = "https://ai.kedang.net"

def normalize_task(payload):
    """读取任务状态;HTTP 200 或 code=success 仅表示查询成功。"""
    if not isinstance(payload, dict):
        raise ValueError("任务响应必须为 JSON 对象")
    if payload.get("error"):
        return {"state": "failed", "url": "", "reason": str(payload["error"])}
    code = payload.get("code")
    if code is not None and str(code).lower() not in ("0", "200", "success", "ok"):
        raise RuntimeError(payload.get("message") or str(code))
    nodes, layer = [payload], [payload]
    for _ in range(5):
        children = []
        for node in layer:
            for key in ("data", "output", "task", "content"):
                if isinstance(node.get(key), dict):
                    children.append(node[key])
        nodes.extend(children)
        layer = children
    # 外层任务状态优先;未提供时再读取嵌套状态。
    raw = next((str(node.get("status") or node.get("task_status")).lower()
                for node in nodes if node.get("status") or node.get("task_status")), "")
    states = {
        "queued": "queued", "pending": "queued", "not_start": "queued", "submitted": "queued",
        "in_progress": "running", "running": "running", "processing": "running",
        "success": "succeeded", "succeeded": "succeeded", "completed": "succeeded",
        "failure": "failed", "failed": "failed", "fail": "failed", "error": "failed", "expired": "failed",
        "cancelled": "cancelled", "canceled": "cancelled",
    }
    url = next((node[key] for node in nodes for key in ("result_url", "video_url", "url")
                if isinstance(node.get(key), str) and node[key]), "")
    reason = next((str(node[key]) for node in nodes for key in ("fail_reason", "error", "message")
                   if node.get(key)), "")
    return {"state": states.get(raw, "unknown"), "url": url, "reason": reason}


def poll_task(task_id, fetch, sleep, monotonic, total_timeout=600):
    """3 / 5 / 10 / 30 秒间隔与 600 秒预算均为客户端示例策略。"""
    if not isinstance(task_id, str) or not task_id:
        raise ValueError("任务 ID 不能为空")
    if total_timeout <= 0:
        raise ValueError("轮询预算必须大于零")
    encoded_id = quote(task_id, safe="")
    deadline = monotonic() + total_timeout
    delays, attempt = (3, 5, 10, 30), 0
    while True:
        remaining = deadline - monotonic()
        if remaining <= 0:
            raise TimeoutError("轮询超时,保留此 ID 后续查询:" + task_id)
        sleep(min(delays[min(attempt, len(delays) - 1)], remaining))
        remaining = deadline - monotonic()
        if remaining <= 0:
            raise TimeoutError("轮询超时,保留此 ID 后续查询:" + task_id)
        payload = fetch(encoded_id, min(30, remaining))
        if monotonic() >= deadline:
            raise TimeoutError("轮询超时,保留此 ID 后续查询:" + task_id)
        task = normalize_task(payload)
        if task["state"] == "succeeded":
            return payload
        if task["state"] in ("failed", "cancelled"):
            raise RuntimeError("任务 " + task_id + ":" + task["state"] + " " + task["reason"])
        if task["state"] not in ("queued", "running"):
            raise RuntimeError("未知任务状态,请按任务 ID 检查响应:" + task_id)
        attempt += 1

def download_video(url, target, headers=None):
    parsed = urlsplit(url)
    if parsed.scheme != "https" or not parsed.netloc:
        raise ValueError("下载地址必须为有效 HTTPS URL")
    target = Path(target)
    temporary = None
    try:
        with requests.get(url, headers=headers or {}, stream=True, timeout=(10, 120)) as response:
            response.raise_for_status()
            mime = response.headers.get("Content-Type", "").split(";", 1)[0].lower()
            if mime and not (mime.startswith("video/") or mime == "application/octet-stream"):
                raise ValueError("下载响应不是视频或二进制文件")
            with tempfile.NamedTemporaryFile(dir=target.parent, delete=False) as file:
                temporary = Path(file.name)
                size = 0
                for chunk in response.iter_content(chunk_size=1024 * 1024):
                    if chunk:
                        file.write(chunk)
                        size += len(chunk)
            if size == 0:
                raise ValueError("下载内容为空")
        temporary.replace(target)
    finally:
        if temporary is not None:
            temporary.unlink(missing_ok=True)
    return target

def main():
    headers = {"Authorization": "Bearer " + os.environ["KEDANG_API_KEY"]}
    # 将所选模型的完整创建请求保存到此 JSON 文件,包含它要求的规格与扩展参数。
    body = json.loads(Path("video-request.json").read_text(encoding="utf-8"))
    if not body.get("model") or body["model"] == "MODEL_ID":
        raise ValueError("请在 video-request.json 中填写账户可用的模型与完整请求参数")
    # 创建只提交一次。网络超时时先核对任务记录,避免重复创建。
    created_response = requests.post(BASE_URL + "/v1/video/generations", headers=headers,
                                     json=body, timeout=(10, 120))
    created_response.raise_for_status()
    created = created_response.json()
    if created.get("error"):
        raise RuntimeError(created["error"])
    data = created.get("data") if isinstance(created.get("data"), dict) else {}
    task_id = created.get("task_id") or created.get("id") or data.get("task_id")
    if not isinstance(task_id, str) or not task_id:
        raise RuntimeError("响应没有任务 ID;保留提交记录,不自动重新创建。")
    Path("video-task-id.txt").write_text(task_id, encoding="utf-8")
    print("任务 ID:", task_id)

    def fetch(encoded_id, timeout):
        response = requests.get(BASE_URL + "/v1/video/generations/" + encoded_id,
                                headers=headers, timeout=timeout)
        response.raise_for_status()
        return response.json()

    result = poll_task(task_id, fetch, time.sleep, time.monotonic, total_timeout=600)
    url = normalize_task(result)["url"]
    if not url:
        raise RuntimeError("任务已成功但缺少结果地址;使用保存的任务 ID 查询。")
    # 返回的媒体 URL 可能在独立域名,下载时不发送平台 Authorization。
    print(download_video(url, "video.mp4"))

if __name__ == "__main__":
    main()