# Wan 2.2 Spicy 视频生成 API 对接文档

## 概述

Wan 2.2 Spicy 视频生成接口，为 **480P 固定分辨率**模型，支持三种生成模式：

- **文生视频（T2V）**：仅凭提示词生成视频，不传任何图片。
- **图生视频（I2V）**：基于 1 张首帧图片生成视频。
- **参考生视频（R2V）**：基于最多 5 个参考素材（参考图 / 参考视频 / 首帧图）生成视频。

模式由请求参数自动判定，无需额外开关，判定优先级为 **R2V > I2V > T2V**（详见下方参数说明）。

> **注意**：本模型分辨率固定为 480P。无论请求传入何种 `resolution`，一律按 480P 出网并计价。

**Base URL**: `https://api.apiverse.ai`

---

## 认证方式

所有接口均需要在请求头中携带 API Key 进行认证：

```
Authorization: Bearer {YOUR_API_KEY}
```

## 快速开始

### cURL 示例

**创建 Wan 2.2 Spicy 任务（图生视频）**
```bash
curl -X POST "https://api.apiverse.ai/api/v2/open/aigc/wan-2.2-spicy" \
  -H "Authorization: Bearer your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "女孩开始跳舞，在结尾捧出一束花",
    "imageUrls": ["https://example.com/first-frame.jpg"],
    "duration": 5
  }'
```

**查询任务状态**
```bash
curl -X GET "https://api.apiverse.ai/api/v2/open/aigc/task_abc123" \
  -H "Authorization: Bearer your_api_key_here"
```

**查询账户余额**
```bash
curl -X GET "https://api.apiverse.ai/api/v2/open/balance" \
  -H "Authorization: Bearer your_api_key_here"
```

---

## 接口列表

### 1. 创建 Wan 2.2 Spicy 视频生成任务

**POST** `/api/v2/open/aigc/wan-2.2-spicy`

创建一个 Wan 2.2 Spicy 视频生成任务（480P 固定），支持文生视频（T2V）、图生视频（I2V）、参考生视频（R2V）三种模式。

**Content-Type**: `application/json`

#### 请求参数

| 参数 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| prompt | string | 是 | 视频描述提示词，用于指导人物动作、镜头运动或场景变化 |
| imageUrls | string[] | 否 | 首帧图片 URL 列表，最多 1 张（多传仅取第一张）。传入即为图生视频（I2V）模式 |
| r2vMedia | object[] | 否 | 参考素材列表，最多 5 个。传入即为参考生视频（R2V）模式。元素结构见下方「r2vMedia 元素结构」 |
| resolution | string | 否 | 分辨率固定为 480P，传入其他值一律按 480P 处理 |
| duration | integer | 否 | 视频时长（秒），范围 5~8，默认 5 |
| ratio | string | 否 | 视频宽高比：`16:9`(默认) / `9:16` / `1:1`。R2V 模式生效；I2V 模式下输出尺寸由首帧图决定，此参数不生效 |
| negativePrompt | string | 否 | 反向提示词，用于指定不希望出现的内容 |
| promptOptimization | boolean | 否 | 是否开启提示词优化，默认 `true` |
| taskNickname | string | 否 | 任务昵称，便于业务侧标识 |
| callbackUrl | string | 否 | 任务完成后的回调通知 URL |

#### r2vMedia 元素结构

| 字段 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| type | string | 是 | 素材类型：`reference_image`(参考图) / `reference_video`(参考视频) / `first_frame`(首帧图) |
| url | string | 是 | 素材的 URL 地址 |

#### 生成模式判定

三种模式互斥，按以下优先级自动判定：

| 模式 | 触发条件 | 说明 |
|------|---------|------|
| 参考生视频（R2V） | 传入 `r2vMedia`（非空） | 基于最多 5 个参考素材生成 |
| 图生视频（I2V） | 传入 `imageUrls`（非空）且未传 `r2vMedia` | 基于 1 张首帧图生成 |
| 文生视频（T2V） | `imageUrls` 与 `r2vMedia` 均为空 | 仅凭提示词生成 |

#### 时长规则

| 分辨率 | 时长范围 | 多段生成 | 说明 |
|--------|---------|---------|------|
| 480P | 5~8 秒 | 不支持 | 超出范围会被自动 clamp 到 [5, 8] 区间 |

> **说明**：
> - `imageUrls` 支持 JPG / PNG / WebP 格式，建议图片大小不超过 5MB，推荐使用清晰的人像图
> - `r2vMedia` 参考图建议不超过 2MB，参考视频与图片合计不超过 5 个素材
> - 本模型不支持多段生成（`multiShot`）与 15 秒以上长视频
> - `promptOptimization` 开启后会先对提示词做改写再生成，效果更佳但耗时略增
> - 创建任务时会预扣费，余额不足将返回错误

#### 请求示例

**图生视频（I2V）**
```json
{
  "prompt": "女孩开始跳舞，在结尾捧出一束花",
  "imageUrls": ["https://example.com/first-frame.jpg"],
  "duration": 5,
  "promptOptimization": true
}
```

**文生视频（T2V）**
```json
{
  "prompt": "夜晚的赛博朋克城市街道，霓虹灯闪烁，镜头缓慢向前推进",
  "duration": 6,
  "ratio": "16:9",
  "negativePrompt": "模糊，低画质，畸变"
}
```

**参考生视频（R2V）**
```json
{
  "prompt": "保留角色美术风格，生成一段流畅的动画",
  "r2vMedia": [
    { "type": "reference_image", "url": "https://example.com/ref-1.png" },
    { "type": "reference_image", "url": "https://example.com/ref-2.png" }
  ],
  "duration": 8,
  "ratio": "16:9"
}
```

#### 响应参数

| 参数 | 类型 | 说明 |
|-----|------|------|
| code | int | 状态码，0 表示成功 |
| msg | string | 状态信息 |
| data.taskId | string | 任务 ID，用于查询任务状态 |
| data.status | string | 任务状态，创建时固定为 `processing` |
| data.createdAt | string | 创建时间 |

#### 响应示例

**成功**
```json
{
  "code": 0,
  "msg": "success",
  "data": {
    "taskId": "task_20260727103000_abc12345",
    "status": "processing",
    "createdAt": "2026-07-27 10:30:00"
  }
}
```

**余额不足**
```json
{
  "code": 40001,
  "msg": "余额不足，当前余额: 0.0100 USD，需要: 0.0880 USD",
  "data": null
}
```

---

### 1.1 OpenAI 兼容接口（创建视频）

**POST** `/v1/video/generations`

面向已有 OpenAI SDK / new-api 生态的兼容入口，遵循 OpenAI 视频生成协议。创建为**异步**：返回 `task_id`，再用下方 `GET /v1/video/generations/{task_id}` 轮询结果。业务逻辑、计费与 `/api/v2/open/aigc/wan-2.2-spicy` 完全一致。

**Content-Type**: `application/json`

#### 请求参数

| 参数 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| model | string | 是 | 固定 `wan-2.2-spicy` |
| prompt | string | 是 | 视频描述提示词 |
| image | string | 否 | 首帧图片 URL，传入即为图生视频（I2V）模式 |
| duration | integer | 否 | 视频时长（秒），范围 5~8，默认 5 |
| size | string | 否 | 尺寸，如 `854x480`，自动换算为最接近的 `ratio`（`16:9` / `9:16` / `1:1` 等） |
| metadata | object | 否 | 承载 OpenAI 标准字段之外的私有参数，见下方「metadata 扩展参数」 |

#### metadata 扩展参数

| 字段 | 类型 | 说明 |
|-----|------|------|
| negativePrompt | string | 反向提示词 |
| promptOptimization | boolean | 是否开启提示词优化，默认 `true` |

> 说明：
> - 分辨率固定 480P，`metadata` 中传入 `resolution` 不生效
> - `image` 有值即为图生视频（I2V），为空则为文生视频（T2V）；OpenAI 协议入口暂不支持 R2V 多参考素材，如需请使用 `/api/v2/open/aigc/wan-2.2-spicy`

#### 请求示例

```json
{
  "model": "wan-2.2-spicy",
  "prompt": "女孩开始跳舞，在结尾捧出一束花",
  "image": "https://example.com/first-frame.jpg",
  "duration": 5,
  "size": "854x480"
}
```

#### 响应示例

```json
{
  "id": "task_20260727103000_abc12345",
  "object": "video",
  "model": "wan-2.2-spicy",
  "created_at": 1769480400,
  "task_id": "task_20260727103000_abc12345",
  "status": "queued"
}
```

失败时返回 OpenAI 标准错误结构：

```json
{
  "error": {
    "message": "余额不足，当前余额: 0.0100 USD，需要: 0.0880 USD",
    "type": "insufficient_quota"
  }
}
```

---

### 1.2 OpenAI 兼容接口（查询视频）

**GET** `/v1/video/generations/{task_id}`

轮询查询视频任务状态与结果。

#### 路径参数

| 参数 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| task_id | string | 是 | 创建接口返回的任务 ID |

#### 响应参数

| 参数 | 类型 | 说明 |
|-----|------|------|
| task_id | string | 任务 ID |
| status | string | 任务状态：`queued` / `in_progress` / `completed` / `failed` |
| url | string | 生成视频 URL（`completed` 时返回） |
| format | string | 视频格式，固定 `mp4` |
| error | object | 失败信息（`failed` 时返回，含 `code` / `message`） |

#### 响应示例

**完成**
```json
{
  "task_id": "task_20260727103000_abc12345",
  "status": "completed",
  "url": "https://fc-gw-sh.oss-accelerate.aliyuncs.com/videos/output_001.mp4",
  "format": "mp4"
}
```

**失败**
```json
{
  "task_id": "task_20260727103000_abc12345",
  "status": "failed",
  "format": "mp4",
  "error": {
    "code": "generation_error",
    "message": "生成失败：内容不符合规范"
  }
}
```

---

### 2. 查询任务状态

**GET** `/api/v2/open/aigc/{taskId}`

查询单个任务的执行状态。

#### 路径参数

| 参数 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| taskId | string | 是 | 任务 ID |

#### 响应参数

| 参数 | 类型 | 说明 |
|-----|------|------|
| code | int | 状态码，0 表示成功 |
| msg | string | 状态信息 |
| data.taskId | string | 任务 ID |
| data.status | string | 任务状态：`processing` / `success` / `failed` |
| data.result | string[] | 生成的视频 URL 列表（成功时返回） |
| data.errorMsg | string | 错误信息（失败时返回） |
| data.createdAt | string | 创建时间 |
| data.updatedAt | string | 更新时间 |

#### 响应示例

**成功**
```json
{
  "code": 0,
  "msg": "success",
  "data": {
    "taskId": "task_20260727103000_abc12345",
    "status": "success",
    "result": [
      "https://fc-gw-sh.oss-accelerate.aliyuncs.com/videos/2026/07/27/output_001.mp4"
    ],
    "createdAt": "2026-07-27 10:30:00",
    "updatedAt": "2026-07-27 10:32:10"
  }
}
```

**失败**
```json
{
  "code": 0,
  "msg": "success",
  "data": {
    "taskId": "task_20260727103000_abc12345",
    "status": "failed",
    "errorMsg": "生成失败：内容不符合规范",
    "createdAt": "2026-07-27 10:30:00",
    "updatedAt": "2026-07-27 10:30:50"
  }
}
```

---

### 3. 批量查询任务状态

**POST** `/api/v2/open/aigc/batch`

批量查询多个任务的执行状态（最多 100 个）。

#### 请求参数

| 参数 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| taskIds | string[] | 是 | 任务 ID 列表，最多 100 个 |

#### 请求示例

```json
{
  "taskIds": ["task_20260727103000_abc12345", "task_20260727103200_def67890"]
}
```

---

### 4. 查询账户余额

**GET** `/api/v2/open/balance`

查询当前用户的账户余额。

#### 响应示例

```json
{
  "code": 0,
  "msg": "success",
  "data": {
    "userId": "user@example.com",
    "balance": "19.3550",
    "frozenBalance": "0.0880",
    "currency": "USD"
  }
}
```

---

## 回调通知

当任务完成（成功或失败）时，如果创建任务时提供了 `callbackUrl`，系统会向该 URL 发送 POST 请求。

**Headers**
```
Content-Type: application/json
X-Funcloud-Event: task.completed
X-Funcloud-Signature: {签名}
```

**Body**
```json
{
  "event": "task.completed",
  "taskId": "task_20260727103000_abc12345",
  "status": "success",
  "result": ["https://fc-gw-sh.oss-accelerate.aliyuncs.com/videos/output_001.mp4"],
  "errorMsg": "",
  "timestamp": "2026-07-27T10:32:10+08:00",
  "signature": "a1b2c3d4e5f6..."
}
```

接收方应返回 HTTP 2xx 状态码表示成功接收。

---

## 错误码

| code | 说明 |
|------|------|
| 0 | 成功 |
| 10002 | 参数缺失或格式错误 |
| 10005 | API Key 无效或缺失 |
| 30003 | 任务不存在 |
| 40001 | 余额不足 |
| 90003 | 服务器内部错误 |

---

## 计费说明

Wan 2.2 Spicy 采用**按秒计费**（480P 单档单价）：

- 计费时长以请求的 `duration` 为准（clamp 到 5~8 秒）
- 实际单价以账户配置为准，可通过控制台查询
- 创建任务时按 `单价 × duration` 预扣费并冻结；任务成功后从冻结余额扣费，失败则全额退还

---

## 最佳实践

### 1. 轮询策略

- 前 30 秒：每 3 秒查询一次
- 30 秒 ~ 2 分钟：每 5 秒查询一次
- 2 分钟后：每 10 秒查询一次

### 2. 使用回调

生产环境建议使用回调通知而非轮询，减少 API 调用、更快获得结果通知。

### 3. 参数选择建议

- 首帧图建议使用清晰的人像图，提示词写明确的动作指令，效果最佳
- R2V 模式建议关闭 `promptOptimization`，以保留原始脚本结构
- 对提示词质量没把握时保留 `promptOptimization` 默认开启

### 4. 余额管理

- 创建任务前建议先查询余额，避免因余额不足导致任务失败
- 任务成功后会从冻结余额中扣费；失败后冻结金额自动退还到可用余额