# Seedance 视频生成 API

> **视频生成接口与火山方舟官方完全兼容** —— 从火山迁移只需改一处：Base URL。
> 请求参数、响应结构、错误码、状态枚举全部一致，业务代码无需改动。
>
> **素材接口（私域素材 / 真人认证）字段与官方一致，但调用方式为平台统一形式**：
> 官方走管控面 `?Action=CreateAsset` + AK/SK 签名，本平台统一为 REST 路径 + API Key。
> 请求体字段名（`Name` / `URL` / `AssetType` 等 PascalCase）和响应结构与官方相同，
> 迁移时只需改 URL 与鉴权头，业务字段无需改动。详见[私域素材](#私域素材)。

获取 API Key：<https://www.wjark.com/center/api-key>

---

## 60 秒上手

```bash
# 1. 提交任务
curl -X POST 'https://maas-openapi.wanjiedata.com/api/ark/v3/contents/generations/tasks' \
  -H 'Authorization: Bearer $ARK_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "doubao-seedance-2-0-260128",
    "content": [{"type": "text", "text": "一只橘猫在阳光下伸懒腰"}]
  }'
# → {"id": "cgt-20260413152618-rx2sv"}

# 2. 轮询结果（通常 1~3 分钟）
curl 'https://maas-openapi.wanjiedata.com/api/ark/v3/contents/generations/tasks/cgt-20260413152618-rx2sv' \
  -H 'Authorization: Bearer $ARK_API_KEY'
# → status: queued → running → succeeded，成功后取 content.video_url
```

> **从火山迁移**：把 `https://ark.cn-beijing.volces.com/api/v3`
> 换成 `https://maas-openapi.wanjiedata.com/api/ark/v3`，其余不动。

---

## 目录

| 我想… | 去哪 |
|---|---|
| 用文字生成视频 | [文生视频](#文生视频) |
| 用图片 / 视频 / 音频做参考 | [多模态参考](#多模态参考) |
| 让模型联网查最新信息 | [联网搜索](#联网搜索) |
| 查任务状态、拿视频地址 | [查询任务](#查询任务) |
| 批量查任务 | [任务列表](#任务列表) |
| 任务完成时被动通知我 | [回调通知](#回调通知) |
| 上传素材反复使用 | [私域素材](#私域素材) |
| 生成真人形象视频 | [真人认证](#真人认证) |
| 请求报错了 | [错误处理](#错误处理) |
| 查参数取值范围 | [参数速查](#参数速查) |

---

## 认证

所有接口统一使用 API Key：

```
Authorization: Bearer $ARK_API_KEY
```

> 也兼容不带 `Bearer ` 前缀的写法，但推荐用官方形式。

---

## 文生视频

**POST** `/api/ark/v3/contents/generations/tasks`

```bash
curl -X POST 'https://maas-openapi.wanjiedata.com/api/ark/v3/contents/generations/tasks' \
  -H 'Authorization: Bearer $ARK_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "doubao-seedance-2-0-260128",
    "content": [{"type": "text", "text": "$提示词"}],
    "resolution": "1080p",
    "ratio": "16:9",
    "duration": 5,
    "generate_audio": true,
    "watermark": false
  }'
```

```json
{"id": "cgt-20260413152618-rx2sv"}
```

**只有 `model` 和 `content` 必填**，其余都有默认值（见[参数速查](#参数速查)）。

---

## 多模态参考

在 `content[]` 里追加参考项即可。**首帧 / 首尾帧 / 多模态参考是三种互斥场景，不能混用。**

### 图片参考

```bash
curl -X POST 'https://maas-openapi.wanjiedata.com/api/ark/v3/contents/generations/tasks' \
  -H 'Authorization: Bearer $ARK_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "doubao-seedance-2-0-260128",
    "content": [
      {"type": "text", "text": "$提示词"},
      {"type": "image_url", "role": "reference_image",
       "image_url": {"url": "https://your-domain.com/ref.jpg"}}
    ]
  }'
```

| role | 用途 | 说明 |
|---|---|---|
| `first_frame` | 首帧 | 图生视频场景，可省略不填 |
| `last_frame` | 尾帧 | 首尾帧场景**必填** |
| `reference_image` | 参考图 | 仅 2.0 系列，可传 1~9 张 |

### 视频参考

```json
{"type": "video_url", "role": "reference_video",
 "video_url": {"url": "https://your-domain.com/ref.mp4"}}
```

### 音频参考

```json
{"type": "audio_url", "role": "reference_audio",
 "audio_url": {"url": "https://your-domain.com/ref.mp3"}}
```

> ⚠️ **地址字段名必须与 `type` 一致**：`type` 为 `video_url` 时地址就得放在 `video_url` 字段里，
> 放进 `image_url` 会被拒。音频不能单独使用，须至少搭配 1 个参考视频或参考图片
>（文本不算搭配：「文本 + 音频」同样会被拒）。

**素材规格**

| 类型 | 格式 | 限制 |
|---|---|---|
| 图片 | jpeg / png / webp / bmp / tiff / gif（2.0 另支持 heic、heif） | 宽高比 0.4~2.5，边长 300~6000px，单张 <30MB |
| 视频 | mp4 / mov（H.264 或 H.265 + AAC 或 MP3） | 分辨率 480p~4k，单个 2~15 秒，最多 3 个且总时长 ≤15 秒，单个 ≤200MB，帧率 24~60 |
| 音频 | wav / mp3 | 单个 2~15 秒，最多 3 段且总时长 ≤15 秒，单个 ≤15MB |

视频另需满足：宽高比 0.4~2.5，边长 300~6000px，总像素（宽×高）在 409600 ~ 8295044 之间。

图片、音频支持 Base64（`data:image/jpeg;base64,...` / `data:audio/wav;base64,...`），
**视频不支持 Base64**。整个请求体不超过 64MB，大文件请用公网 URL 或[私域素材](#私域素材)。

> 💡 提示词语言：所有模型支持中英文，2.0 系列额外支持日语、印尼语、西班牙语、葡萄牙语。
> 建议中文 ≤500 字、英文 ≤1000 词，过长易导致模型忽略细节。

---

## 联网搜索

2.0 系列支持让模型自主联网检索，提升时效性内容（商品、天气、新闻等）的准确度。
**仅文生视频场景支持。**

```json
{
  "model": "doubao-seedance-2-0-260128",
  "content": [{"type": "text", "text": "介绍今天的天气情况"}],
  "tools": [{"type": "web_search"}]
}
```

开启后模型会自行判断是否需要检索，会增加一定时延。实际检索次数从查询任务返回的
`usage.tool_usage.web_search` 获取，为 `0` 表示本次未检索。

---

## 查询任务

**GET** `/api/ark/v3/contents/generations/tasks/{id}`

```bash
curl 'https://maas-openapi.wanjiedata.com/api/ark/v3/contents/generations/tasks/cgt-xxx' \
  -H 'Authorization: Bearer $ARK_API_KEY'
```

```json
{
  "id": "cgt-20260413152618-rx2sv",
  "model": "doubao-seedance-2-0-260128",
  "status": "succeeded",
  "error": null,
  "created_at": 1776065537,
  "updated_at": 1776065642,
  "content": {"video_url": "https://..."},
  "resolution": "1080p",
  "ratio": "16:9",
  "duration": 5,
  "generate_audio": true,
  "usage": {"completion_tokens": 4567, "total_tokens": 4567}
}
```

### 状态流转

```
queued ──► running ──► succeeded    取 content.video_url
                   └─► failed       看 error.code / error.message
   └──────────────────► cancelled   主动删除排队中的任务
   └──────────────────► expired     超过 execution_expires_after
```

**状态只有这 6 个值。** `created_at` / `updated_at` 是 Unix 秒（整数）。

### 两个时效必须注意

| 项 | 有效期 | 影响 |
|---|---|---|
| 视频地址 | **24 小时** | 过期后重新查询获取新地址 |
| 任务记录 | **7 天** | 超过后查不到，请及时保存结果 |

> 💡 `status` 刚变 `succeeded` 时，`video_url` 可能短暂不返回 —— 平台正在转存以提供稳定地址。
> 属正常现象，**继续轮询几秒即可**，不是错误。

> 💡 2.0 系列存在**最低 token 用量**：实际用量低于该阈值时，`usage.completion_tokens`
> 返回并按最低用量计费。短视频的实际扣费可能高于按时长的线性估算。

---

## 任务列表

**GET** `/api/ark/v3/contents/generations/tasks`

```bash
curl -G 'https://maas-openapi.wanjiedata.com/api/ark/v3/contents/generations/tasks' \
  -H 'Authorization: Bearer $ARK_API_KEY' \
  --data-urlencode 'page_num=1' \
  --data-urlencode 'page_size=20'
```

| 参数 | 默认 | 取值 |
|---|---|---|
| `page_num` | 1 | 1~500 |
| `page_size` | 20 | 1~500 |

```json
{"items": [ /* 每项结构同「查询任务」 */ ], "total": 42}
```

> ⚠️ 官方的 `filter.status` / `filter.task_ids` / `filter.model` 过滤参数**本平台暂不支持**，
> 传了会被忽略并返回全部任务。需要按状态筛选请在拿到 `items` 后自行过滤。

---

## 删除任务

**DELETE** `/api/ark/v3/contents/generations/tasks/{id}`

| 当前状态 | 可删 | 效果 |
|---|---|---|
| `queued` | ✅ | 取消排队，转为 `cancelled` |
| `running` | ❌ | 生成中不可中断 |
| `succeeded` / `failed` / `expired` | ✅ | 删除记录，此后查不到 |
| `cancelled` | ❌ | 24 小时后自动清理 |

---

## 回调通知

提交任务时带上 `callback_url`，状态变化时平台会 POST 通知你，**省去轮询**。

```json
{
  "model": "doubao-seedance-2-0-260128",
  "content": [{"type": "text", "text": "$提示词"}],
  "callback_url": "https://your-domain.com/webhook"
}
```

回调请求体结构与「查询任务」返回一致：

```json
{
  "id": "cgt-20260413152618-rx2sv",
  "status": "succeeded",
  "created_at": 1776065537,
  "updated_at": 1776065642
}
```

**要点**

- 请在 5 秒内返回 2xx，否则平台会重试，**最多回调 3 次**
- 回调**不含视频地址** —— 收到 `succeeded` 后调「查询任务」获取，这样拿到的地址始终有效
- 建议同时保留轮询兜底，避免网络问题漏收

---

## 私域素材

素材上传一次可反复引用，适合固定形象、参考图复用的场景。

> 素材接口沿用火山管控面风格，字段为 **PascalCase**（`Name` / `URL` / `AssetType`），
> 与视频接口的下划线风格不同 —— 这是官方设计，非笔误。

### 使用流程

```
创建素材组 ──► 上传素材 ──► 确认 Status=Active ──► 用 asset://<素材ID> 引用
```

### 1. 创建素材组

**POST** `/api/ark/v1/assets/groups`

```bash
curl -X POST 'https://maas-openapi.wanjiedata.com/api/ark/v1/assets/groups' \
  -H 'Authorization: Bearer $ARK_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"Name": "我的素材组", "Description": "常用参考图", "GroupType": "AIGC"}'
```

```json
{"ResponseMetadata": {...}, "Result": {"Id": "group-20260101000000-xxxxx"}}
```

| 字段 | 必填 | 说明 |
|---|---|---|
| `Name` | ✅ | ≤64 字符 |
| `Description` | | ≤300 字符 |
| `GroupType` | | `AIGC`（虚拟形象）。创建时仅支持此项；真人素材组由[真人认证](#真人认证)自动创建，类型为 `LivenessFace` |

### 2. 上传素材

**POST** `/api/ark/v1/assets`

```bash
curl -X POST 'https://maas-openapi.wanjiedata.com/api/ark/v1/assets' \
  -H 'Authorization: Bearer $ARK_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "GroupId": "group-20260101000000-xxxxx",
    "Name": "参考视频",
    "URL": "https://your-domain.com/demo.mp4",
    "AssetType": "Video"
  }'
```

| 字段 | 必填 | 说明 |
|---|---|---|
| `URL` | ✅ | 公网可访问地址，**不支持 Base64** |
| `AssetType` | ✅ | `Image` / `Video` / `Audio` |
| `GroupId` | ✅ | 所属素材组 |
| `Name` | | ≤64 字符，仅用于列表搜索，不影响生成效果 |

**素材规格**（与生成时直接传 URL 的规格略有不同，以此表为准）

| 类型 | 限制 |
|---|---|
| 图片 | jpeg / png / webp / bmp / tiff / gif / heic / heif，宽高比 0.4~2.5，边长 300~6000px，<30MB |
| 视频 | mp4 / mov，分辨率 480p / 720p / 1080p，2~15 秒，宽高比 0.4~2.5，总像素 409600~2086876，≤200MB，帧率 24~60 |
| 音频 | wav / mp3，2~15 秒，≤15MB |

```json
{"ResponseMetadata": {...}, "Result": {"Id": "asset-20260101000000-xxxxx"}}
```

> ⚠️ **上传是异步的。** 创建成功不代表可用，需查询确认 `Status` 为 `Active` 再引用。
> 视频素材处理较慢，请预留时间。

### 3. 查询 / 更新 / 删除

```bash
# 查询单个（确认 Status）
curl -X POST 'https://maas-openapi.wanjiedata.com/api/ark/v1/assets/get' \
  -H 'Authorization: Bearer $ARK_API_KEY' -H 'Content-Type: application/json' \
  -d '{"Id": "asset-20260101000000-xxxxx"}'

# 列表
curl -X POST 'https://maas-openapi.wanjiedata.com/api/ark/v1/assets/list' \
  -H 'Authorization: Bearer $ARK_API_KEY' -H 'Content-Type: application/json' \
  -d '{"Filter": {"GroupType": "AIGC"}, "PageNumber": 1, "PageSize": 20}'

# 改名
curl -X POST 'https://maas-openapi.wanjiedata.com/api/ark/v1/assets/update' \
  -H 'Authorization: Bearer $ARK_API_KEY' -H 'Content-Type: application/json' \
  -d '{"Id": "asset-20260101000000-xxxxx", "Name": "新名称"}'

# 删除
curl -X POST 'https://maas-openapi.wanjiedata.com/api/ark/v1/assets/delete' \
  -H 'Authorization: Bearer $ARK_API_KEY' -H 'Content-Type: application/json' \
  -d '{"Id": "asset-20260101000000-xxxxx"}'
```

素材组对应 `/api/ark/v1/assets/groups/get` `list` `update` `delete`，参数同理
（组用 `Id`，列表用 `Filter` / `PageNumber` / `PageSize`）。

> ⚠️ **删除素材组会批量删除组内所有素材资产，该操作不可逆，一经删除不可恢复，请谨慎操作。**
> 组内素材较多时，删除可能耗费一定时间。

**列表参数**

| 参数 | 必填 | 说明 |
|---|---|---|
| `Filter.GroupType` | ✅ | `AIGC` 虚拟形象 / `LivenessFace` 真人素材 —— **查真人素材必须传 `LivenessFace`** |
| `Filter.GroupIds` | | 按素材组 ID 列表过滤 |
| `Filter.Name` | | 按名称模糊搜索 |
| `PageNumber` | ✅ | 从 1 开始 |
| `PageSize` | ✅ | 上限 100 |
| `SortBy` / `SortOrder` | | 默认 `CreateTime` / `Desc` |

列表响应：

```json
{"ResponseMetadata": {...}, "Result": {"Items": [...], "TotalCount": 42}}
```

**素材状态**

| Status | 含义 |
|---|---|
| `Processing` | 处理中，**暂不可用** |
| `Active` | 可用 |
| `Failed` | 失败，看 `Error.Code` |

> ⚠️ 素材上传失败时 **HTTP 仍返回 200**，必须靠 `Status` 判断，不能只看状态码。

**`Status` 为 `Failed` 时的常见 `Error.Code`**

| Error.Code | 原因 |
|---|---|
| `DownloadFailed` | 平台无法下载你提供的 URL —— 检查公网可访问性与有效期 |
| `FormatUnsupported` / `FormatUndetectable` | 格式不支持，或文件损坏无法识别 |
| `TypeMismatch` | 声明的 `AssetType` 与实际文件类型不符 |
| `TranscodingFailed` | 转码失败 |
| `DurationTooShort` / `DurationTooLong` | 时长不在 2~15 秒内 |
| `WidthTooSmall` / `HeightTooLarge` 等 | 边长不在 300~6000px 内 |
| `AspectRatioTooSmall` / `AspectRatioTooLarge` | 宽高比不在 0.4~2.5 内 |
| `PixelCountTooSmall` / `PixelCountTooLarge` | 总像素超出范围 |
| `FpsTooLow` / `FpsTooHigh` | 帧率不在 24~60 内 |
| `FileSizeTooLarge` | 文件超出大小限制 |
| `AudioTrackRequired` / `AudioTrackForbidden` | 音轨要求不符 |
| `ContentRestricted`、`Input*SensitiveContentDetected` | 内容安全审核未通过 |
| `FaceMismatch` | 真人素材人脸与授权人脸不一致 |

### 4. 引用素材生成视频

把 URL 换成 `asset://<素材ID>`：

```json
{
  "model": "doubao-seedance-2-0-260128",
  "content": [
    {"type": "text", "text": "$提示词"},
    {"type": "video_url", "role": "reference_video",
     "video_url": {"url": "asset://asset-20260101000000-xxxxx"}}
  ]
}
```

素材的 `AssetType` 必须与 `type` 匹配（视频参考须为 `Video` 素材）。
引用他人或不存在的素材返回 **403**。

---

## 真人认证

生成真人形象视频前需完成活体认证，认证通过后系统自动创建真人素材组。

```bash
# 1. 创建认证会话，把返回的 H5Link 交给最终用户打开完成人脸认证
curl -X POST 'https://maas-openapi.wanjiedata.com/api/ark/v1/visual-validate-session' \
  -H 'Authorization: Bearer $ARK_API_KEY' -H 'Content-Type: application/json' \
  -d '{"CallbackURL": "https://your-domain.com/done"}'
# → {"Result": {"BytedToken": "...", "H5Link": "https://..."}}

# 2. 认证完成后凭 BytedToken 换取素材组 ID
curl -X POST 'https://maas-openapi.wanjiedata.com/api/ark/v1/visual-validate-result' \
  -H 'Authorization: Bearer $ARK_API_KEY' -H 'Content-Type: application/json' \
  -d '{"BytedToken": "..."}'
# → {"Result": {"GroupId": "group-xxx"}}
```

| 字段 | 必填 | 说明 |
|---|---|---|
| `CallbackURL` | ✅ | 认证完成后的跳转地址 |
| `BytedToken` | ✅ | **有效期 30 分钟，仅可用一次** |

> `H5Link` 打开后即失效。可通过后缀 `lng` 指定语言：`zh`（默认）/ `en` / `zh-Hant`。

**如何判断认证成功**：用户点「完成」后浏览器跳转到你的 `CallbackURL`，平台会在其后拼接参数：

```
https://your-domain.com/done?bytedToken=xxx&resultCode=10000&verify_type=real_time
```

| 回跳参数 | 说明 |
|---|---|
| `resultCode` | **`10000` 表示认证通过**，其余值为失败 |
| `bytedToken` | 用它调 `visual-validate-result` 换素材组 ID |
| `algorithmBaseRespCode` | 服务端子错误码，`resultCode` 为服务端错误时再看此字段 |
| `verify_type` | 固定值 `real_time` |

认证通过后自动创建的素材组类型为 **`LivenessFace`** —— 后续查询素材组列表时，
`Filter.GroupType` 需传 `LivenessFace` 才能查到（传 `AIGC` 查不到真人组）。

---

## 错误处理

所有错误统一为嵌套结构：

```json
{"error": {"code": "InvalidParameter", "message": "请求参数错误，请检查输入"}}
```

用 `error.code` 做程序化判断，`error.message` 面向人阅读。

### 常见错误

| HTTP | code | 怎么办 |
|---|---|---|
| 400 | `InvalidParameter` | 检查参数拼写与取值范围（见[参数速查](#参数速查)） |
| 401 | — | API Key 无效或已过期 |
| 403 | `AccountOverdueError` | 账户欠费，请充值后重试 |
| 403 | — | 引用了他人或不存在的素材 |
| 404 | `NotFound.*` | 任务 / 素材不存在，或已超过 7 天保留期 |
| 429 | `RateLimitExceeded.*` | 触发限流，退避后重试 |
| 5xx | `InternalServiceError` | 服务异常，建议重试；持续失败请联系我们 |

内容安全类错误码形如 `InputTextSensitiveContentDetected`、
`InputImageSensitiveContentDetected`，表示输入未通过审核，请调整内容后重试。

---

## 参数速查

### 模型

| 模型 | 特点 |
|---|---|
| `doubao-seedance-2-0-260128` | 2.0 标准版，功能最全，支持 4k |
| `doubao-seedance-2-0-fast-260128` | 2.0 快速版，速度优先，**不支持 1080p / 4k** |

### 生成参数

| 参数 | 类型 | 默认 | 取值 |
|---|---|---|---|
| `model` | string | — | **必填** |
| `content` | array | — | **必填**，见[多模态参考](#多模态参考) |
| `resolution` | string | `720p` | `480p` / `720p` / `1080p` / `4k` |
| `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 生成」水印 |
| `callback_url` | string | — | 必须是 http / https 地址 |
| `tools` | array | — | `[{"type":"web_search"}]` 开启[联网搜索](#联网搜索)，仅文生视频 |
| `return_last_frame` | bool | false | 返回尾帧图（无水印，宽高同视频） |
| `priority` | int | 0 | 0~9，越大越优先 |
| `safety_identifier` | string | — | 英文，≤64 字符，用于标识终端用户 |
| `execution_expires_after` | int | 172800 | 3600~259200 秒，超时置 `expired` |

### 版本限制

| 参数 | 说明 |
|---|---|
| `1080p` | **fast 版不支持** |
| `4k` | **仅** `doubao-seedance-2-0-260128` 支持 |
| `seed` / `camera_fixed` | 2.0 系列暂不支持 |
| `service_tier` | 2.0 系列仅支持在线推理，无需设置 |
| `frames` | 2.0 系列不支持，请用 `duration` |

---

## 常见问题

**Q：任务一直是 `queued` / `running`？**
正常生成需 1~3 分钟，4k 更久。建议每 5~10 秒轮询一次，或改用[回调通知](#回调通知)。

**Q：`succeeded` 了但没有 `video_url`？**
平台正在转存以提供稳定地址，继续轮询几秒即可。

**Q：视频地址打不开了？**
有效期 24 小时，重新调「查询任务」获取新地址。

**Q：怎么知道消耗了多少 token？**
查询任务返回的 `usage.completion_tokens` 即计费依据。

**Q：素材创建成功，但生成视频时报错？**
确认素材 `Status` 是 `Active` —— 上传是异步的，创建成功不代表可用。

**Q：能完全照搬火山方舟的代码吗？**
**视频生成接口可以**，只改 Base URL —— 参数、响应、错误码、状态枚举完全一致。
**素材接口需改调用方式**：官方是 `?Action=CreateAsset` + AK/SK 签名，本平台是 REST 路径 + API Key，
但请求体字段名与响应结构和官方相同，业务代码改动量很小。
