> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apimart.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# seedance-2.5 视频生成

>  - 异步处理，返回 task_id 用于查询
- 文生视频 / 多模态参考 / 视频编辑 / 视频延长 / 首尾帧
- 单次最长 30 秒；参考素材最多 30 图 + 10 视频 + 10 音频
- 分辨率支持 480p / 720p / 1080p；支持 mp4 / mov 输出 

> [!NOTE]
>
> **相对 2.0 的主要变化**：时长上限 15s → **30s**；参考素材 9 图 + 3 视频 + 3 音频 → **30 图 + 10 视频 + 10 音频**；支持**纯音频参考**；新增 **mov** 输出。\
> **注意**：分辨率支持 **480p / 720p / 1080p**（2.0 的 4k 在 2.5 **不可用**）。

```bash cURL theme={null}
curl --request POST \
  --url https://api.apimart.ai/v1/videos/generations \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "model": "seedance-2.5",
    "prompt": "一段极具电影感的30秒蒸汽朋克微缩景观序列",
    "size": "16:9",
    "resolution": "720p",
    "duration": 30
  }'
```

```python Python theme={null}
import requests

url = "https://api.apimart.ai/v1/videos/generations"

payload = {
    "model": "seedance-2.5",
    "prompt": "一段极具电影感的30秒蒸汽朋克微缩景观序列",
    "size": "16:9",
    "resolution": "720p",
    "duration": 30,
}

headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json",
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript JavaScript theme={null}
const url = "https://api.apimart.ai/v1/videos/generations";

const payload = {
  model: "seedance-2.5",
  prompt: "一段极具电影感的30秒蒸汽朋克微缩景观序列",
  size: "16:9",
  resolution: "720p",
  duration: 30,
};

const headers = {
  Authorization: "Bearer <token>",
  "Content-Type": "application/json",
};

fetch(url, {
  method: "POST",
  headers: headers,
  body: JSON.stringify(payload),
})
  .then((response) => response.json())
  .then((data) => console.log(data))
  .catch((error) => console.error("Error:", error));
```

```go Go theme={null}
package main

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

func main() {
    url := "https://api.apimart.ai/v1/videos/generations"

    payload := map[string]interface{}{
        "model":      "seedance-2.5",
        "prompt":     "一段极具电影感的30秒蒸汽朋克微缩景观序列",
        "size":       "16:9",
        "resolution": "720p",
        "duration":   30,
    }

    jsonData, _ := json.Marshal(payload)

    req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
    req.Header.Set("Authorization", "Bearer <token>")
    req.Header.Set("Content-Type", "application/json")

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}
```

```java Java theme={null}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;

public class Main {
    public static void main(String[] args) throws Exception {
        String url = "https://api.apimart.ai/v1/videos/generations";

        String payload = """
        {
          "model": "seedance-2.5",
          "prompt": "一段极具电影感的30秒蒸汽朋克微缩景观序列",
          "size": "16:9",
          "resolution": "720p",
          "duration": 30
        }
        """;

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(url))
            .header("Authorization", "Bearer <token>")
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(payload))
            .build();

        HttpResponse<String> response = client.send(request,
            HttpResponse.BodyHandlers.ofString());

        System.out.println(response.body());
    }
}
```

```php PHP theme={null}
<?php

$url = "https://api.apimart.ai/v1/videos/generations";

$payload = [
    "model" => "seedance-2.5",
    "prompt" => "一段极具电影感的30秒蒸汽朋克微缩景观序列",
    "size" => "16:9",
    "resolution" => "720p",
    "duration" => 30
];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer <token>",
    "Content-Type: application/json"
]);

$response = curl_exec($ch);
curl_close($ch);

echo $response;
?>
```

```json 200 theme={null}
{
  "code": 200,
  "data": [
    {
      "status": "submitted",
      "task_id": "task_01KMCGF6BQGN3X28H3KSR50X5T"
    }
  ]
}
```

```json 400 theme={null}
{
  "error": {
    "code": 400,
    "message": "请求参数无效",
    "type": "invalid_request_error"
  }
}
```

```json 401 theme={null}
{
  "error": {
    "code": 401,
    "message": "身份验证失败，请检查您的API密钥",
    "type": "authentication_error"
  }
}
```

```json 402 theme={null}
{
  "error": {
    "code": 402,
    "message": "账户余额不足，请充值后再试",
    "type": "payment_required"
  }
}
```

```json 429 theme={null}
{
  "error": {
    "code": 429,
    "message": "请求过于频繁，请稍后再试",
    "type": "rate_limit_error"
  }
}
```

```json 500 theme={null}
{
  "error": {
    "code": 500,
    "message": "服务器内部错误，请稍后重试",
    "type": "server_error"
  }
}
```

## 认证

**Authorization** `string` *required*

Bearer Token 认证。访问 [API Key 管理页面](https://apimart.ai/keys) 获取密钥。

```
Authorization: Bearer YOUR_API_KEY
```

## 请求参数

**model** `string` *required*

固定值：`seedance-2.5`

**nsfw\_check** `boolean` (default: false)

是否在提交视频任务前执行内容审核。

* `true`：使用 `omni-moderation-latest` 审核提示词和输入图片
* `false` 或不传：不发起审核请求，不增加审核成本与延迟（默认）

审核范围：

* 文本：`prompt`、`negative_prompt`
* 图片：`image_urls`、`image_with_roles[].url`、`first_frame_image`、`last_frame_image`
* 图片类型的 `asset://` 私域素材：反查原始公网 URL 后审核
* base64 图片：转为公网地址后审核

`video_urls`、`audio_urls` 以及视频/音频类型的私域素材**不会送审**，因为审核模型不支持视频和音频。

适用模型：`seedance-2.0`、`seedance-2.0-fast`、`seedance-2.0-mini`、`seedance-2.0-face`、`seedance-2.0-fast-face`、`seedance-2-0`（旧名）、`seedance-2.5`。

审核调用本身不向发起视频请求的用户计费。

> [!WARNING]
>
> * 命中审核时同步返回 HTTP 400（`nsfw_content_detected`），不会创建任务、不会返回 `task_id`、不会扣除视频生成额度
> * 审核服务不可用、超时或响应异常时采用 **fail-open**：生成请求继续提交。因此该参数不能作为绝对的内容安全保证
> * 无法解析为公网图片地址的输入会跳过；其他模型传 `nsfw_check: true` 会被静默忽略

开启示例：

```json theme={null}
{
  "model": "seedance-2.5",
  "prompt": "a cat walking on the beach",
  "image_urls": ["https://cdn.example.com/ref.png"],
  "nsfw_check": true
}
```

审核命中响应：

```json theme={null}
{
  "error": {
    "message": "Your request was rejected by content moderation (`nsfw_check` is enabled). Flagged categories: sexual, violence/graphic.",
    "type": "nsfw_content_detected",
    "param": "",
    "code": "nsfw_content_detected"
  }
}
```

**draft** `boolean`

设为 `true` 时生成 480p 样片，仅 `seedance-2.5` 支持。未传时按普通生成请求处理。

* `resolution` 只能是 `480p`，不传时自动使用 `480p`
* 不能与 `draft_task_id` 同时使用
* 样片从创建起 **7 天**内有效，成功后可用于生成 1080p 正式片

完整流程见 [样片模式](#样片模式)。

**draft\_task\_id** `string`

根据已完成的样片生成 1080p 正式片。填写样片提交响应中的 APIMart 任务 ID（`data[0].task_id`），不是视频 URL。

* 仅 `seedance-2.5` 支持；必须与样片使用同一模型
* 样片必须属于当前 API Key 所属用户，已成功完成且从创建起未超过 7 天
* `resolution` 只能是 `1080p`，不传时自动使用 `1080p`
* 不能与 `draft: true` 同时使用，也不能再次传入 `prompt`、参考素材、时长等继承字段

可调整字段与完整限制见 [样片模式](#样片模式)。

**prompt** `string`

提示词。可用 `@图片1` / `@视频1` / `@音频1` 指代参考素材（下标从 1 起，对应数组顺序）。

普通生成及生成样片时必填；使用 `draft_task_id` 生成正式片时禁止传入，自动沿用样片提示词。

示例：`"全程使用@视频1的第一视角构图，@音频1作为背景音乐，首帧为@图片1"`

**resolution** `string` (default: 720p)

分辨率，**仅支持**：

* `480p`
* `720p`（默认）
* `1080p`

传入 `2k` / `4k` 等不支持的分辨率会同步 **400**。

样片模式例外：`draft: true` 时仅支持 `480p`，省略时自动使用 `480p`；传入 `draft_task_id` 时仅支持 `1080p`，省略时自动使用 `1080p`。

**size** `string` (default: adaptive)

宽高比（也接受字段名 `aspect_ratio`）。

可选值：`16:9`、`4:3`、`1:1`、`3:4`、`9:16`、`21:9`、`adaptive`（默认）

> [!WARNING]
>
> 视频编辑、视频延长、首帧/首尾帧任务对 `size` 有硬性限制，见 [任务类型与限制](#任务类型与限制)。

**duration** `integer` (default: 5)

时长（秒）：

* `4` \~ `30`
* `-1`：模型自动选择时长（提交时按 30 秒上限预扣，完成后按实际产出多退少补）

未传时按 **5 秒**生成与计费。

**generate\_audio** `boolean` (default: true)

是否生成音频（也接受字段名 `audio`）。

* `true`：有声视频（默认）
* `false`：无声视频

**watermark** `boolean` (default: false)

是否添加「AI 生成」水印。默认 `false`。

**seed** `integer`

随机种子。相同请求下不同 seed 通常得到不同结果；相同 seed 结果相近但不保证完全一致。

**output\_format** `string` (default: mp4)

输出封装格式：

* `mp4`（默认）
* `mov`：更高色彩精度，**推荐**用于编辑 / 延长场景

**omni\_reference\_task\_type** `string` (default: auto)

子任务类型引导：`auto` / `reference` / `edit` / `extend`。

显式指定 `reference` / `edit` / `extend` 后，提交时同步校验该类型的限制；不合格直接 **400**，不建任务、不扣费。详见下方 [任务类型与限制](#任务类型与限制)。

**image\_urls** `array\<string\>`

参考图 URL 数组，一律作为 `reference_image`。

支持：

* 普通 URL：`https://example.com/pic.jpg`
* 私域素材：`asset://cm9xxxxxxxx`

首帧 / 尾帧请用 `image_with_roles`。

> [!WARNING]
>
> * 最多 **30** 张
> * 与 `image_with_roles` 不要混用冲突角色语义；首尾帧请走 `image_with_roles`

**image\_with\_roles** `array\<object\>`

带角色的图片数组。

**字段说明**

**url** `string` *required*

图片 URL 或 `asset://...`

**role** `string` *required*

* `first_frame`：首帧（1 张）
* `last_frame`：尾帧（1 张，通常与首帧配合）
* `reference_image`：参考图（合计最多 30 张）

示例：

```json theme={null}
[
  {"url": "https://example.com/first.jpg", "role": "first_frame"},
  {"url": "https://example.com/last.jpg", "role": "last_frame"}
]
```

> [!NOTE]
>
> 若同时存在 `video_urls` / `audio_urls`，`first_frame` / `last_frame` 会自动转为 `reference_image`（多模态参考任务）。

**video\_urls** `array\<string\>`

参考视频数组（`reference_video`）。

**传入方式**：视频 URL、素材 ID（`asset://...`）。

规格见 [参考视频规格](#参考视频规格)。

**audio\_urls** `array\<string\>`

参考音频 URL 数组（`reference_audio`）。支持普通 URL 与 `asset://...`。

最多 **10** 段；总时长 ≤ **30s**（单段 2\~30s）。

> [!NOTE]
>
> 2.5 **支持纯音频参考**（可不配图/视频）。

**return\_last\_frame** `boolean` (default: false)

为 `true` 时，任务成功后额外返回尾帧图片，便于连续生成。

**tools** `array\<object\>`

工具列表，用于联网搜索等增强能力。

示例：

```json theme={null}
"tools": [{"type": "web_search"}]
```

**字段说明**

**type** `string` *required*

工具类型

可选值：

* `web_search` - 联网搜索，生成时参考网络信息

## 素材要求

| 素材 | 限制 |
| - | - |
| 图片 | ≤30 张；jpeg / png / webp / bmp / tiff / gif / heic / heif；宽高比 \[0.4, 2.5]；边长 \[300, 6000]px；单张 \<30MB |
| 视频 | 见下方 [参考视频规格](#参考视频规格) |
| 音频 | ≤10 段；wav / mp3；单段 \[2, 30]s 且**总时长 ≤30s**；单个 ≤15MB |

### 参考视频规格

* **传入方式**：视频 URL、素材 ID（`asset://...`）
* **视频格式**：`mp4`、`mov`，支持编码格式见下表
* **分辨率**：`480p`，`720p`，`1080p`
* **时长**：单个视频时长 \[2, 30] s；最多传入 **10** 个参考视频；所有视频**总时长不超过 30s**
* **单个视频尺寸**：
  * 宽高比（宽/高）：\[0.4, 2.5]
  * 宽高长度（px）：\[300, 6000]
  * 总像素数：\[640×640=409600, 3326×2494=8295044]，即宽和高的乘积须落在 \[409600, 8295044]
* **大小**：单个视频不超过 **200 MB**
* **帧率 (FPS)**：\[24, 60]

#### 支持编码格式

| 封装格式 | 视频编码 | 音频编码 |
| - | - | - |
| `mp4` | H.264 / H.265 | AAC / MP3 |
| `mov` | H.264 / H.265 | AAC / MP3 |

## 任务类型与限制

系统会按参考素材与**提示词意图**判定任务类型。后三种对 `size` / `duration` 有硬性限制，**违反会在任务开始后异步失败**（如 `InvalidParameter.TaskTypeConstraint`）：

| 任务类型 | 触发条件 | 限制 |
| - | - | - |
| 文生视频 | 仅文本 | 无 |
| 参考生视频 | 参考素材 + 普通描述提示词 | 无。**避免**在提示词中出现「编辑 / 延长 / 续写 / 删除 / 替换」等词，防止误判 |
| 视频编辑 | 参考素材 + 提示词含「编辑视频 / 增加 / 删除 / 修改 / 替换」等 | `size` 仅 `adaptive`，`duration` 仅 `-1`；待编辑视频须 4\~30s |
| 视频延长 | 参考素材 + 提示词含「向前 / 向后延长 / 延续 / 续写」 | `size` 仅 `adaptive` |
| 首帧 / 首尾帧 | `image_with_roles` 使用 `first_frame` / `last_frame` | `size` 仅 `adaptive`（提交阶段也会同步校验） |

### 用 `omni_reference_task_type` 把异步报错变成同步报错

传 `reference` / `edit` / `extend` 显式声明子任务类型后，**提交时就会校验该类型的限制**。不合格立即返回 400，任务不会创建、不扣任何额度，无需等到轮询 `failed`。

| 取值 | 含义 | 提交时校验的限制 |
| - | - | - |
| `auto`（默认） | 模型自行判定 | 无（不合格改为**异步**失败） |
| `reference` | 参考生视频 | 无（`size` / `duration` 不受限） |
| `edit` | 视频编辑 | `video_urls` 至少 1 个；`size` 只能 `adaptive`（或不传）；`duration` 只能 `-1`（或不传，见下）；源视频须 4\~30s |
| `extend` | 视频延长 | `video_urls` 至少 1 个；`size` 只能 `adaptive`（或不传） |

几个必须知道的点：

* **`edit` 不传 `duration` 时，平台自动按 `-1` 处理。** 平台对「未传 duration」的默认是下发 5 秒，而 `edit` 上游强制 `-1`，两者相撞会直接失败，所以这里帮你归一成 `-1`。代价是**预扣按 30 秒上限收押金**（同 `duration: -1` 的口径），完成后按实际用量退差。想要更小的预扣就别用 `edit`，改用默认的 `auto`。
* **`edit` 显式传 `duration` 只能是 `-1`**，传别的值直接 400（输出时长跟随源视频，本来就不由你定）。
* ⚠️ **指定了也仍可能异步报错 `InvalidParameter.TaskTypeMismatch`**：上游处理时会再结合提示词判一次任务类型，与你指定的不一致就拒。所以提示词仍要按对应类型的写法来写（`edit` 用「编辑 / 删除 / 替换…」，`extend` 用「向前 / 向后延长 / 续写…」）。
* Seedance 2.5 的**全部渠道行为一致**（同一套校验判据 + 同样下发给上游），不会出现「换个渠道结果不一样」。

## 素材库使用说明

参考素材可直接传公网 URL，也可先入素材库、再用 `asset://` 引用。**推荐入库**的场景：

1. **真人人脸素材必须走素材库**——直接传 URL 会被内容审核拦截，入库审核通过后才可用
2. **素材会复用多次**——入库一次，之后每次生成免重复审核，提交更快
3. **URL 是带签名的临时链接**——入库时平台会把素材固化，之后引用不依赖原始 URL 是否仍有效
4. 入库素材会**自动同步到全部可用渠道**，多渠道路由时无论落到哪个渠道都能直接用

素材库与 2.0 家族**共用**；审核通过后的 `asset://` 可在 2.0 / 2.5 生成请求中通用。完整提交接口字段亦可参见 [虚拟人像素材](/cn/api-reference/videos/seedance-2-0/private-avatar.md)。

### 上传素材

```bash theme={null}
POST /v1/seedance2/private-avatar/assets
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
```

```bash theme={null}
curl --request POST \
  --url https://api.apimart.ai/v1/seedance2/private-avatar/assets \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "model": "seedance-2.5",
    "group": { "name": "my-assets" },
    "asset_type": "Image",
    "assets": [
      { "url": "https://example.com/a.png", "name": "a" },
      { "url": "https://example.com/b.png", "name": "b" }
    ]
  }'
```

| 字段 | 必填 | 说明 |
| - | - | - |
| `model` | ❌ | 素材要配合使用的模型（默认 2.0）。**决定时长限制档位**；2.5 请传 `seedance-2.5` |
| `group` | ❌ | 素材组；不传自动创建 |
| `asset_type` | ✅ | `Image` / `Video` / `Audio` |
| `assets[].url` | ✅ | 素材公网 URL |
| `assets[].name` | ❌ | 素材名 |

响应返回本地任务 `id`，用 [获取任务状态](/cn/api-reference/tasks/status.md)（`GET /v1/tasks/{id}`）轮询审核结果；审核通过后从素材列表接口拿到 `asset://` 形式的素材 ID。

### 素材限制（提交时同步校验）

违规**立即返回 400**（标明第几个素材、违反哪条限制），不提交审核、不占审核额度：

| 素材 | 限制 |
| - | - |
| 图片 | jpeg / png / webp / bmp / tiff / gif / heic / heif；边长 \[300, 6000]px；宽高比 \[0.4, 2.5]；单张 \<30MB |
| 视频 | mp4 / mov；单个 ≤200MB；时长 **按 model 分档**：2.0 家族 \[2, 15]s，**2.5 \[2, 30]s** |
| 音频 | wav / mp3；单个 ≤15MB；时长分档同视频 |

报错示例：

```json theme={null}
{
  "error": {
    "code": "invalid_asset_material",
    "message": "video #1: duration must be between 2s and 15s for seedance-2.0 (got 30s)"
  }
}
```

> [!NOTE]
>
> 30s 的视频素材请提交时声明 `"model": "seedance-2.5"`（2.0 无法使用超过 15s 的素材）。\
> 平台探测不到的素材（网络波动等）会放行，交审核判定。

### 在生成请求中使用

审核通过的素材在 `image_urls` / `image_with_roles` / `video_urls` / `audio_urls` 中以 `asset://` 引用：

```json theme={null}
{
  "model": "seedance-2.5",
  "prompt": "@图片1 的人物在海边行走",
  "image_urls": ["asset://cm9xxxxxxxx"],
  "duration": 8
}
```

多渠道说明：素材入库后自动同步全部可用渠道；生成请求无论路由到哪个渠道都可直接引用。若某渠道的同步副本缺失，平台会用原始 URL 现场补传兜底（原始 URL 已过期则该渠道跳过、换渠道承接）。

### 管理接口速查

| 方法 | 路径 | 用途 |
| - | - | - |
| `GET` | `/v1/seedance2/private-avatar/assets` | 素材列表 |
| `GET` | `/v1/seedance2/private-avatar/assets/{asset_id}` | 单个素材详情（含审核状态） |
| `PATCH` | `/v1/seedance2/private-avatar/assets/{asset_id}` | 更新素材信息 |
| `DELETE` | `/v1/seedance2/private-avatar/assets/{asset_id}` | 删除素材 |
| `POST` / `GET` / `PATCH` / `DELETE` | `/v1/seedance2/private-avatar/groups[/{id}]` | 素材组管理 |

素材接口**免计费**（仅 Token 鉴权与限流），不产生消费记录。

### 常见问题

**Q: 审核要多久？**\
图片通常数秒；视频与真人素材可能数分钟。轮询任务 `id` 到终态即可。

**Q: 审核失败但看不出原因？**\
部分失败不返回具体原因（常见为素材抓取瞬时失败），平台已自动重试一次；仍失败请更换素材 URL（确认公网可直接下载）重新提交。

**Q: 同一素材给 2.0 和 2.5 都用，要传两次吗？**\
不用。入库一次即可，`asset://` 对两代通用；跨渠道 / 跨模型的同步由平台自动完成。

**Q: 能直接传真人素材 URL 吗？**\
真人素材必须先入素材库审核。

## 计费

以下规则适用于普通生成和样片；由样片生成正式片的计费见 [样片模式计费](#样片模式计费)。

* 按 **秒 × 分辨率档** 计费。
* **有参考视频输入时**：计费秒数 = 输入视频总时长（≤30s）+ 输出时长，走带输入参考的优惠档单价。
* `duration = -1`（自动时长）：提交时按上限 **30 秒**预扣，完成后按**实际产出**多退少补。
* 未传 `duration`：按 **5 秒**生成与计费。
* 任务失败或内容审核拦截：**全额退款**（仅成功出片收费）。

## 样片模式

先生成一条 480p 样片确认画面，满意后使用样片任务 ID 生成 1080p 正式片。正式片复用样片的提示词、参考素材、时长、宽高比、`seed`、是否有声及任务类型，使画面与样片对齐。

### 第一步：生成 480p 样片

在普通生成请求中增加 `"draft": true`，其余素材与任务类型限制保持一致。`resolution` 不传时自动使用 `480p`，传 `720p` 或 `1080p` 会返回 400。

```bash theme={null}
curl -X POST 'https://api.apimart.ai/v1/videos/generations' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "seedance-2.5",
    "prompt": "狐狸坐在草地上，镜头缓慢拉远，微风吹动毛发",
    "image_urls": ["https://example.com/reference.png"],
    "duration": 5,
    "size": "16:9",
    "draft": true
  }'
```

提交成功后，从 `data[0].task_id` 读取样片任务 ID。通过 [获取任务状态](/cn/api-reference/tasks/status.md) 轮询，直到 `data.status` 为 `completed` 后再提交正式片。

```bash theme={null}
curl 'https://api.apimart.ai/v1/tasks/task_01KZEVX5R6DM5K9T698P1SDKCR' \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

建议每 5～15 秒查询一次。`pending` 表示排队，`processing` 表示生成中，`completed` 表示成功，`failed` 表示失败。视频地址在 `data.result.videos[].url` 数组中，读取 `url[0]`。

### 第二步：生成 1080p 正式片

将第一步返回的任务 ID 填入 `draft_task_id`。`resolution` 不传时自动使用 `1080p`，其他分辨率会返回 400。

```bash theme={null}
curl -X POST 'https://api.apimart.ai/v1/videos/generations' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "seedance-2.5",
    "draft_task_id": "task_01KZEVX5R6DM5K9T698P1SDKCR",
    "output_format": "mov",
    "return_last_frame": true,
    "watermark": false
  }'
```

正式片会返回一个新的任务 ID，同样使用 `GET /v1/tasks/{task_id}` 查询结果。

以下字段由样片继承，**不得再次传入，即使值与样片一致也会返回 400**：

`prompt`、`image_urls`、`image_with_roles`、`video_urls`、`audio_urls`、`duration`、`size`、`aspect_ratio`、`seed`、`generate_audio`、`audio`、`omni_reference_task_type`、`generation_type`、`camerafixed`、`web_search`、`tools`。

可调整以下输出选项：

| 参数 | 说明 |
| - | - |
| `output_format` | `mp4`（默认）或 `mov` |
| `return_last_frame` | 是否返回尾帧图；不传时使用模型默认值，不沿用样片设置 |
| `watermark` | 是否加水印；不传时使用模型默认值，不沿用样片设置 |

> [!WARNING]
>
> `draft: true` 与 `draft_task_id` 互斥。样片和正式片均不支持 `service_tier`。
>
> 样片有效期从创建起计算，共 7 天。任务不存在、不属于当前用户、尚未成功、不是样片或已过期时，提交正式片会返回 400，不创建任务、不扣费。

正式片必须使用生成样片时的同一条线路，系统会自动关联。原线路暂时不可用时，提交会返回 400；稍后使用同一个 `draft_task_id` 重试即可。

同一条未过期的样片可以多次生成正式片，每次都是独立任务并单独计费。

### 样片模式计费

样片按普通 480p 视频计费。有参考视频时，输入视频时长照常计入，合计最多 30 秒。

正式片固定按**不含视频输入的 1080p 档位**计费；即使样片使用了参考视频，正式片也不会再次计入输入视频时长。

| 样片的时长设置 | 样片预扣 | 正式片预扣 |
| - | - | - |
| 显式指定 4～30 秒 | 按指定时长的 480p 档位预扣，参考视频按普通规则计入 | 按相同时长的 1080p 档位预扣，不计输入视频时长 |
| `duration: -1`，或 `edit` 省略时长被自动按 `-1` 处理 | 按最多 30 秒输出预扣，参考视频按普通规则计入 | 按最多 30 秒的 1080p 档位预扣 |
| 其他情况下省略 `duration` | 按 5 秒输出预扣，参考视频按普通规则计入 | 按 5 秒的 1080p 档位预扣 |

成功后按实际 token 用量结算，多退少补；失败全额退款。具体单价和折扣以模型定价为准。

```text theme={null}
样片 token 数 = (输入视频秒数 + 输出秒数) × 宽 × 高 × 24 ÷ 1024
正式片 token 数 = 输出秒数 × 宽 × 高 × 24 ÷ 1024
```

宽、高为对应任务的输出像素尺寸。成功后的 `data.usage.completion_tokens` 返回结算 token 数，可用于核账。

## 请求示例

### 文生视频（30 秒）

```json theme={null}
{
  "model": "seedance-2.5",
  "prompt": "一段极具电影感的30秒蒸汽朋克微缩景观序列",
  "size": "16:9",
  "resolution": "720p",
  "duration": 30
}
```

### 多模态参考（图 + 视频 + 音频）

```json theme={null}
{
  "model": "seedance-2.5",
  "prompt": "全程使用@视频1的第一视角构图，@音频1作为背景音乐，首帧为@图片1",
  "image_urls": [
    "https://example.com/pic1.jpg",
    "https://example.com/pic2.jpg"
  ],
  "video_urls": ["https://example.com/ref.mp4"],
  "audio_urls": ["https://example.com/bgm.mp3"],
  "size": "16:9",
  "duration": 11
}
```

### 视频编辑

```json theme={null}
{
  "model": "seedance-2.5",
  "prompt": "编辑视频：删除 @视频1 中的所有路人，只保留主角",
  "video_urls": ["https://example.com/input.mp4"],
  "size": "adaptive",
  "duration": -1,
  "output_format": "mov"
}
```

### 首尾帧生视频

```json theme={null}
{
  "model": "seedance-2.5",
  "prompt": "图中女孩对着镜头说\"茄子\"，360度环绕运镜",
  "image_with_roles": [
    {"url": "https://example.com/first.jpg", "role": "first_frame"},
    {"url": "https://example.com/last.jpg", "role": "last_frame"}
  ],
  "size": "adaptive",
  "duration": 5
}
```

### 私域素材

```json theme={null}
{
  "model": "seedance-2.5",
  "prompt": "人物在城市街道自然行走，阳光明媚",
  "image_urls": ["asset://cm9xxxxxxxx"],
  "duration": 5,
  "resolution": "720p"
}
```

### 联网搜索

```json theme={null}
{
  "model": "seedance-2.5",
  "prompt": "根据最新资讯生成一段科技新闻短视频开场",
  "size": "16:9",
  "resolution": "720p",
  "duration": 8,
  "tools": [{"type": "web_search"}]
}
```

## 常见错误

| 现象 | 原因 |
| - | - |
| 400 `resolution` 不支持 | 传了 `2k` / `4k` 等不支持的分辨率 |
| 400 `This model only supports duration 4-30 seconds, or -1` | `duration` 不在允许范围 |
| 400 `first_frame/last_frame tasks only support ratio=adaptive` | 首尾帧任务指定了具体宽高比 |
| 任务异步失败（编辑 / 延长类提示） | 提示词被判定为编辑 / 延长，但 `size` / `duration` 不满足对应限制（见上表） |
| 任务异步失败 `SensitiveContentDetected` | 素材或产物触发内容审核 |

## 响应（提交）

**code** `integer`

响应状态码，成功时为 200

**data** `array`

提交时返回 `status` / `task_id`

**数组元素**

**status** `string`

初始为 `submitted`

**task\_id** `string`

任务 ID，用于 [查询状态](/cn/api-reference/tasks/status.md)

## 查询完成态（`GET /v1/tasks/{task_id}`）

提交后使用 [获取任务状态](/cn/api-reference/tasks/status.md) 轮询。当 `status` 为 `completed` 时，结构如下。

### 完成态响应示例

```json theme={null}
{
  "code": 200,
  "data": {
    "id": "task_01KZEWTMH6TG3Z1X2QRP2B9ZG9",
    "status": "completed",
    "progress": 100,
    "created": 1786132648,
    "completed": 1786132748,
    "actual_time": 100,
    "estimated_time": 300,
    "cost": 0.3104,
    "credits_cost": 3.104,
    "usage": {
      "completion_tokens": 38800
    },
    "result": {
      "videos": [
        {
          "url": [
            "https://cdn.example.com/video/…-video_task_01KZEWTMH6TG3Z1X2QRP2B9ZG9.mp4"
          ],
          "expires_at": 1786219148
        }
      ]
    }
  }
}
```

### 完成态字段

| 字段 | 类型 | 说明 |
| - | - | - |
| `data.id` | string | 任务 ID |
| `data.status` | string | 完成态恒为 `completed` |
| `data.progress` | int | 完成态恒为 `100` |
| `data.created` / `data.completed` | int | 提交 / 完成时间（Unix 秒） |
| `data.actual_time` | int | 实际耗时（秒）= completed − created |
| `data.estimated_time` | int | 平台预估耗时（秒，参考值） |
| `data.cost` | float | **本单实扣金额（美元）**，已含折扣，与消费日志一致 |
| `data.credits_cost` | float | 实扣积分 = `cost × 10` |
| `data.usage.completion_tokens` | int | 本单消耗 token 数。核账：`cost = completion_tokens ÷ 10⁶ × token 单价 × 折扣` |
| `data.result.videos[].url` | **string\[]** | 视频地址。**注意是数组**，取 `url[0]`。本接口返回**平台转存后的长期地址** |
| `data.result.videos[].expires_at` | int | 链接过期时间戳（转存地址长期有效，此字段为兼容保留） |
| `data.result.videos[].last_frame_url` | string | 尾帧图片（仅提交时 `return_last_frame=true` 才有） |

### 备注

* 失败任务（`status=failed`）：`cost` 恒为 `0`（预扣已全额退款），错误原因在 `data.error.message`
* `usage` 在完成后的最初几秒可能尚未出现（结算落库有秒级延迟），再查一次即可

## 与 2.0 的差异

| 特性 | 2.0 | 2.5 |
| - | - | - |
| 模型名 | `seedance-2.0` 等 | `seedance-2.5` |
| 时长 | 约 4\~15s | **4\~30s**，或 `-1` 自动 |
| 分辨率 | 480p / 720p / 1080p / 4k | **480p / 720p / 1080p** |
| 参考图 | ≤9 | **≤30** |
| 参考视频 | ≤3，总时长约 \<15s | **≤10，总时长 ≤30s** |
| 参考音频 | ≤3，总时长 ≤15s | **≤10，总时长 ≤30s**；支持纯音频 |
| 输出格式 | 主要为 mp4 | **mp4 / mov** |
| 水印 | — | `watermark` |
| 私域 `asset://` | 支持 | **通用**（同一私域接口） |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.