doubao-seedance-i2v

豆包 Seedance · 图生视频

接口模型名称doubao-seedance-i2v(请求体 model 必须与此完全一致)

类型图生视频(首帧)
调用方式异步(先创建任务,再查询结果)

先看这几条

  • 计费:按 Token 用量分档,单价见控制台
  • 耗时:视频生成通常较慢(常见数分钟,复杂任务可能更久),请耐心等待
  • 调用:异步——创建成功后用 tid 轮询 /v1/tasks/query 查看进度,不要反复提交同一任务
  • 结果链接resp_content 下载地址约 24 小时内有效,请及时保存到本地
  • 输入素材:图片/视频 URL 须 公网可访问
  • 通用说明视频模型 API

最小可跑通请求

复制下面 JSON,替换密钥与素材 URL 后即可创建任务:

{
  "model": "doubao-seedance-i2v",
  "content": {
    "prompt": "一只橘猫在窗台上缓缓走动,午后阳光洒落,镜头缓慢推进,写实电影感",
    "media": [
      { "type": 2, "url": "https://example.com/first.png", "role": "first_frame" }
    ]
  },
  "parameters": {
    "duration": 5,
    "aspect_ratio": "16:9",
    "resolution": "480P",
    "watermark": false
  }
}

调用地址

步骤方法地址
创建任务POSThttps://mass.gogpu.cn/v1/videos/completions
查询任务POSThttps://mass.gogpu.cn/v1/tasks/query

鉴权:X-API-Key: sk-你的密钥Authorization: Bearer sk-你的密钥


参数说明

顶层字段

字段必传类型说明
modelstring接口模型名称(见页首)
contentobjectprompt / media
parametersobject生成控制参数,见下表
conversation_idnumber可选会话 ID

content

字段必传类型说明
promptstring正向提示词
mediaarray首帧图

content.media[]

字段必传类型可选值说明
typeint2图片
urlstring公网 URL首帧
rolestringfirst_frame首帧

parameters

字段必传类型可选值 / 范围推荐示例说明
durationint以控制台该模型允许范围为准5输出时长(秒)
aspect_ratiostring"16:9" / "9:16" / "1:1" / "4:3""16:9"画面比例
resolutionstring"480P" / "720P" / "1080P""480P"大写 P 的字符串;勿传数字
watermarkbooltrue / falsefalse是否加水印
seedint整数随机种子

type 必须是图片 2,不要误用视频 type。


任务查询

创建成功只表示任务已受理,不代表视频已生成完成。请用返回的 tid(平台任务号) 轮询查询进度;创建响应里的 task_id 一般可忽略。

视频类任务耗时通常较长:常见需等待数分钟,分辨率更高、带参考素材或视频编辑时可能更久。请保持轮询,不要因「一时查不到结果」就重复创建。

{ "model": "<同上 model>", "tid": 164 }
字段必传说明
model与创建时相同
tid创建响应里的 data.tid

建议每 10~15 秒查询一次;客户端总等待建议 ≥ 15~30 分钟(编辑类可更长)。成功后请尽快下载 resp_content(约 24 小时有效)。


成功响应示例

创建成功(示意)

{
  "code": 0,
  "data": {
    "tid": 164,
    "output": { "task_id": "cgt-xxxxxxxx", "task_status": "PENDING" }
  },
  "msg": "操作成功"
}

记下 data.tid,用于查询。

查询成功(示意)

{
  "code": 0,
  "data": {
    "tid": 164,
    "task_status": "SUCCEEDED",
    "complete_status": 2,
    "resp_content": "https://example.com/result.mp4",
    "quantity": 5,
    "billing_metric": "480P",
    "total_token": 50638,
    "total_amount": 2.33,
    "fail_reason": ""
  },
  "msg": "操作成功"
}
字段说明
task_statusSUCCEEDED 表示成功
resp_content视频下载地址(约 24 小时内有效,请及时保存)
quantity计费用量;按秒计费时多为秒数
billing_metric清晰度档,如 480P / 720P
total_tokenToken 用量(按 Token 计费时关注)
total_amount本次金额(元,按量时)
fail_reason失败原因(成功时可为空)

代码示例

点击右上角标签切换 curl / Python / Node.js / Go(含创建 + 轮询):

curl -sS https://mass.gogpu.cn/v1/videos/completions \
  -H "Content-Type: application/json" \
  -H "X-API-Key: sk-你的密钥" \
  -d '{
    "model": "doubao-seedance-i2v",
    "content": {
      "prompt": "一只橘猫在窗台上缓缓走动,午后阳光洒落,镜头缓慢推进,写实电影感",
      "media": [{"type": 2, "url": "https://example.com/first.png", "role": "first_frame"}]
    },
    "parameters": {"duration": 5, "aspect_ratio": "16:9", "resolution": "480P", "watermark": false}
  }'
import json, time, urllib.request

BASE, KEY, MODEL = "https://mass.gogpu.cn", "sk-你的密钥", "doubao-seedance-i2v"

def api(path, body):
    req = urllib.request.Request(
        f"{BASE}{path}",
        data=json.dumps(body).encode(),
        method="POST",
        headers={"Content-Type": "application/json", "X-API-Key": KEY},
    )
    with urllib.request.urlopen(req, timeout=180) as r:
        return json.loads(r.read().decode())

c = api("/v1/videos/completions", {
    "model": MODEL,
    "content": {
        "prompt": "一只橘猫在窗台上缓缓走动,午后阳光洒落,镜头缓慢推进,写实电影感",
        "media": [{"type": 2, "url": "https://example.com/first.png", "role": "first_frame"}],
    },
    "parameters": {
        "duration": 5,
        "aspect_ratio": "16:9",
        "resolution": "480P",
        "watermark": False,
    },
})
assert c.get("code") == 0, c
tid = c["data"]["tid"]
print("tid=", tid)
while True:
    d = api("/v1/tasks/query", {"model": MODEL, "tid": tid})["data"]
    print(d.get("task_status"), d.get("resp_content"), d.get("total_token"), d.get("total_amount"))
    if d.get("task_status") in ("SUCCEEDED", "FAILED", "CANCELED", "UNKNOWN"):
        break
    time.sleep(10)
const BASE = "https://mass.gogpu.cn";
const KEY = "sk-你的密钥";
const MODEL = "doubao-seedance-i2v";

const api = (path, body) =>
  fetch(`${BASE}${path}`, {
    method: "POST",
    headers: { "Content-Type": "application/json", "X-API-Key": KEY },
    body: JSON.stringify(body),
  }).then((r) => r.json());

const c = await api("/v1/videos/completions", {
  model: MODEL,
  content: {
    prompt: "一只橘猫在窗台上缓缓走动,午后阳光洒落,镜头缓慢推进,写实电影感",
    media: [{ type: 2, url: "https://example.com/first.png", role: "first_frame" }],
  },
  parameters: {
    duration: 5,
    aspect_ratio: "16:9",
    resolution: "480P",
    watermark: false,
  },
});
if (c.code !== 0) throw new Error(JSON.stringify(c));
const tid = c.data.tid;
console.log("tid=", tid);
for (;;) {
  const d = (await api("/v1/tasks/query", { model: MODEL, tid })).data;
  console.log(d.task_status, d.resp_content, d.total_token, d.total_amount);
  if (["SUCCEEDED", "FAILED", "CANCELED", "UNKNOWN"].includes(d.task_status)) break;
  await new Promise((r) => setTimeout(r, 10000));
}
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"time"
)

const (
	base  = "https://mass.gogpu.cn"
	apiKey = "sk-你的密钥"
	model = "doubao-seedance-i2v"
)

func api(path string, body any) (map[string]any, error) {
	b, err := json.Marshal(body)
	if err != nil {
		return nil, err
	}
	req, err := http.NewRequest(http.MethodPost, base+path, bytes.NewReader(b))
	if err != nil {
		return nil, err
	}
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("X-API-Key", apiKey)
	client := &http.Client{Timeout: 180 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	raw, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	var out map[string]any
	if err := json.Unmarshal(raw, &out); err != nil {
		return nil, err
	}
	return out, nil
}

func main() {
	var createBody any
	if err := json.Unmarshal([]byte(`{
  "model": "doubao-seedance-i2v",
  "content": {
    "prompt": "一只橘猫在窗台上缓缓走动,午后阳光洒落,镜头缓慢推进,写实电影感",
    "media": [
      { "type": 2, "url": "https://example.com/first.png", "role": "first_frame" }
    ]
  },
  "parameters": {
    "duration": 5,
    "aspect_ratio": "16:9",
    "resolution": "480P",
    "watermark": false
  }
}`), &createBody); err != nil {
		panic(err)
	}
	c, err := api("/v1/videos/completions", createBody)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%v\n", c)
	if fmt.Sprint(c["code"]) != "0" {
		panic(fmt.Sprintf("create failed: %v", c))
	}
	data := c["data"].(map[string]any)
	tid := data["tid"]
	fmt.Println("tid=", tid)

	for {
		q, err := api("/v1/tasks/query", map[string]any{"model": model, "tid": tid})
		if err != nil {
			panic(err)
		}
		d := q["data"].(map[string]any)
		status, _ := d["task_status"].(string)
		fmt.Println(status, d["resp_content"], d["quantity"], d["billing_metric"], d["total_amount"], d["total_token"])
		switch status {
		case "SUCCEEDED", "FAILED", "CANCELED", "UNKNOWN":
			return
		}
		time.Sleep(10 * time.Second)
	}
}

计费说明

Token 用量分档计费,单价以控制台为准。成功后可在任务查询中查看 total_tokentotal_amount 等字段。


常见错误

现象处理
模型不可用或不存在核对 model 是否与控制台「接口模型名称」/ GET /v1/modelsid 完全一致
余额不足 / 套餐额度不足前往控制台充值或购买/更换套餐后重试
创建成功但一直轮询不到结束视频生成本身较慢,属正常情况:保持轮询(建议间隔 10~15 秒),客户端总等待建议 ≥ 15~30 分钟;视频编辑可能更久。勿重复创建同一任务
媒体相关失败 / 无法读取素材确认图片或视频 URL 公网可访问(勿用内网或需登录的地址)
参数错误 / role 或 type 不对严格按本页 media 要求填写;文生请传 media: []

相关链接

doubao-seedance-t2v · doubao-seedance-r2v

复制 MD