# 灵造AI（中巨量）开放平台 API 文档

**版本：** 1.0 ｜ **更新日期：** 2026-07-30

---

## 概述

开放平台让你用程序（或让大模型）调用平台的内容生产能力：

| 能力 | 接口 | 是否需要素材 |
|---|---|---|
| 动画视频（文案 → 动效短视频） | `POST /open/fluid-tasks` | **不需要** |
| 数字人视频（形象口播 + 素材/动画） | `POST /open/digital-human-tasks` | 需要（口播全程模式除外） |
| 视频混剪（素材检索 + 配音 + 字幕） | `POST /open/tasks` | 需要 |

配套还有配置查询（音色 / 背景音乐 / 片尾 / 数字人 / 素材分组 / 封面模板）、任务进度与产出查询、任务删除、账户积分查询。

> 开放平台只提供**视频**能力。图文创作（抽帧成图 + 文案）暂不对外开放，请在网页端「创作中心 → 图文内容创作」使用。

**接口根地址**：`https://ai-mix.chuhaibang.com/api/v1/open`

**在线文档**：<https://ai-mix.chuhaibang.com/open-api> ｜ **AI Skill**：<https://ai-mix.chuhaibang.com/open-api/skill>
（两个页面都免登录，可直接分享给对接的开发者）

---

## 认证

所有接口都要带请求头：

| 请求头 | 说明 |
|---|---|
| `X-Api-Key` | 在「个人中心 → 开放平台」点「获取 API 密钥」生成，形如 `lz_xxxxxxxx...` |

```bash
curl "https://ai-mix.chuhaibang.com/api/v1/open/account" -H "X-Api-Key: lz_你的密钥"
```

失败响应：

| HTTP | detail | 含因 |
|---|---|---|
| 401 | `缺少 X-Api-Key` | 没带请求头 |
| 401 | `无效的 API 密钥` | 密钥错误或已被重置 |
| 403 | `账号已被禁用` | 账号被平台停用 |

**密钥安全**：密钥请尽可能在服务端使用；怀疑泄漏时可在个人中心点「重置」，旧密钥立即失效。

---

## 统一响应格式

成功（HTTP 200）：

```json
{ "code": 0, "message": "ok", "data": { } }
```

失败（HTTP 4xx / 5xx）：

```json
{ "detail": "错误描述" }
```

常用状态码：

| 状态码 | 含义 |
|---|---|
| 200 | 成功 |
| 400 | 参数校验失败 / 业务错误（素材不足等） |
| 401 | 密钥无效 |
| 402 | **积分不足**（`detail` 含所需与剩余积分） |
| 403 | 越权（引用他人素材、访问他人任务）或账号被禁用 |
| 404 | 资源不存在 |
| 422 | 请求体字段类型/取值不合法（FastAPI 校验，`detail` 为数组） |

---

## 计费规则

API 与网页端**共用同一份积分**（`永久积分 + 当月月度积分`）。创建任务时先校验余额，
建任务成功后立即扣除；建任务失败不扣费。积分流水会带「· 开放平台API」后缀，便于对账。

| 任务类型 | 计价公式（系数由平台配置，见个人中心「订阅管理」） |
|---|---|
| 视频混剪 | `ceil(目标时长 / 8 × 系数) × 数量` |
| 数字人视频 | `ceil(目标时长 / 15 × 系数) × 数量` |
| 动画视频 | `ceil(目标时长 / 15 × 系数) × 数量` |

提交前建议先查 `GET /open/account` 的 `total_credits`。积分不足时返回：

```json
{ "detail": "积分不足：本次需要 120，剩余 45" }
```

---

## 资源归属与配额

- 音色 / 背景音乐 / 片尾 / 数字人：可用「平台预设（已上架）」+「你自己上传的」；
  引用他人上传的返回 403，引用已下架预设返回 400。
- 素材分组（`clip_group_ids`）：只能用自己的分组，或平台标记的热门分组（`clip_source=hot`）。
- 任务查询 / 删除：只能操作自己的任务（含网页端创建的）。
- 存储、社媒账号数等配额与网页端一致，超限时相关接口返回 403。

---

## 成品保留期 ⚠️

**通过 API 创建的任务，成品默认只保留 1 天**，之后由系统每日定时任务整批硬删——
DB 记录与磁盘文件（成品视频、封面、配音）一并删除，**不可恢复**。

这么设计是因为 API 能批量出片，不清理会迅速堆满存储配额。

| 想要的效果 | 怎么做 |
|---|---|
| 拿到链接就下载走（推荐） | 什么都不用做，用完即弃 |
| 成品长期留在平台 | 提交任务时传 `"keep_forever": true` |

```json
{
  "description": "...",
  "voice_id": 1,
  "keep_forever": true
}
```

> **`keep_forever: true` 的成品会持续占用你的存储配额**，且不再自动清理。
> 批量场景请自行控制数量，或改为「下载到自己的存储后调 `DELETE /open/tasks/{id}` 删除」。
> 存储超限会导致素材上传等接口返回 403。

其它说明：

- 保留期与 `keep_forever` 都只对 API 创建的任务生效；网页端/小程序创建的任务走各自的策略，在那两端传该字段无效。
- 已被提取为模板广场模板的批次不会被清理。
- 保留天数由平台配置，如需调整请联系平台运营。
- 任务详情/列表会回显 `keep_forever`，可据此确认设置是否生效。

---

## 账户

### 查询账户与积分

```
GET /open/account
```

响应 `data`（节选）：

| 字段 | 说明 |
|---|---|
| `plan_code` / `plan_name` | 当前套餐（如 `pro` / 企业版） |
| `period` / `status` / `expires_at` | 计费周期、订阅状态、到期时间（永久版为 `null`） |
| `total_credits` | **可用积分合计**（永久 + 当月月度），提交前看这个 |
| `permanent_credits` | 永久积分余额 |
| `monthly_credits_remaining` | 当月月度积分余额 |
| `monthly_credits_reset_at` | 月度积分重置时间 |
| `storage_bytes_used` / `storage_bytes_limit` | 存储用量 / 上限（字节） |
| `domestic_accounts_used` / `_limit`、`overseas_accounts_used` / `_limit` | 社媒账号数用量 |

---

## 配置查询

以下接口都是 `GET`，无参数（除标注外），返回列表。

> 💡 **不想调接口找 ID？** 在「个人中心 → 开放平台」打开**开发者模式**，创作页面的数字人、
> 音色、背景音乐、片尾、素材分组旁会直接显示 `#ID`，点一下即可复制。

### 朗读音色

```
GET /open/voices
```

```json
{
  "code": 0, "message": "ok",
  "data": [
    {"id": 1, "name": "女声-甜美", "audio_url": "https://.../voices/x.wav", "is_preset": true, "sort_order": 10}
  ]
}
```

> `id` 即各任务的 `voice_id`。`audio_url` 是试听直链。

### 背景音乐

```
GET /open/bgm
```

字段：`id` / `name` / `file_url` / `duration` / `tags` / `sort_order`。对应 `bgm_id`、`bgm_ids`。

### 片尾视频

```
GET /open/outros
```

字段：`id` / `title` / `file_url` / `duration` / `width` / `height`。对应 `outro_id`、`outro_ids`。

### 数字人形象

```
GET /open/digital-humans
```

字段：`id` / `name` / `description` / `file_url` / `cover_url` / `is_preset`。对应 `digital_human_id`。

### 素材分组

```
GET /open/clip-groups?source=group   # 我的分组（默认）
GET /open/clip-groups?source=hot     # 平台热门分组
```

字段：`id` / `name` / `description` / `clip_count`。对应 `clip_group_id`、`clip_group_ids`。

| `source` | 返回 | 配套的 `clip_source` |
|---|---|---|
| `group`（默认） | 你自己在网页端建的分组 | `"group"` |
| `hot` | 平台整理的热门素材分组，全体用户可用 | `"hot"` |

两者的 `clip_source` 必须和分组来源对应：拿 `source=hot` 的 ID 去配 `clip_source: "group"` 会报 403。

> 分组与其中片段的维护（上传、下载链接、智能拆条、去水印）在网页端「素材管理」完成。

### 分组内片段（分页）

```
GET /open/clip-groups/{group_id}/clips?page=1&page_size=20
```

用于需要精确指定片段时取 `clip_group_clip_ids`。

### 任务分组

```
GET /open/groups
```

给作品归类用（平台公共分组），对应 `group_id`。

### 封面模板

```
GET /open/cover-templates?portrait=true
```

字段：`template_id` / `name` / `image`（排版示意图）/ `is_random`。对应 `cover_config.template_id`。
真实封面大字由系统按每条视频的文案自动提取，不需要你传文字。

返回的**第一项是「随机封面模板」**（`template_id` 为 `__random__`、`is_random: true`）：
传它则每条视频各自随机取一个真实模板，适合批量出片时避免封面雷同。

```json
{"cover_config": {"template_id": "__random__"}}
```

---

## 创作任务

三类视频任务的**公共字段**：

| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
| `description` | string | 必填 | 主题或固定文案，1–3000 字 |
| `use_fixed_copy` | bool | false | true = `description` 即最终文案，AI 不改写正文 |
| `humanize` | bool | false | 去 AI 味引擎（仅 AI 生成文案时有效） |
| `voice_id` | int | — | 朗读音色，见 `/open/voices` |
| `tts_language` | `zh` \| `en` | null | 留空按文案自动判断 |
| `tts_speed` | float | 1.0 | 0.8–1.2 |
| `bgm_id` / `bgm_ids` | int / int[] | null | 多选时每条视频随机取一首 |
| `bgm_volume` | int | 25 | 1–200（相对原声百分比） |
| `bgm_loop` | bool | true | false = 只播一遍 |
| `quantity` | int | 10 / 3 | 生成条数（动画视频默认 3，上限 200；其它上限 1000） |
| `resolution` | string | `1080x1920` | 形如 `宽x高` |
| `target_duration` | int | 15 | 目标时长（秒），1–600 |
| `video_bitrate` | `1M`\|`2M`\|`4M` | 1M（动画 2M） | 码率 |
| `outro_id` / `outro_ids` | int / int[] | null | 片尾，多选时随机取一个 |
| `cover_config` | object | null | `{"template_id": "xx"}`，见 `/open/cover-templates` |
| `group_id` | int | null | 归入某个任务分组 |
| `keep_forever` | bool | false | **永久保留成品**。默认 false，成品只保留 1 天；true 则不再自动清理（见下方「成品保留期」） |
| `enable_title` | bool | false | 顶部大标题烧录 |
| `title_texts` | string | null | 每行一条，按条分配；留空则用 AI 提取 |
| `title_font_size` | float | 5.0 | 相对画面高度百分比 0.1–10 |
| `title_y_percent` | float | 8.0 | 距顶部百分比 |
| `title_font_color` | string | `#ffffff` | 十六进制色值 |
| `enable_subtitle` | bool | false | 逐句字幕 |
| `transition_type` | string | null | 转场，如 `fade` / `dissolve` / `pixelize`；留空随机 |

创建成功统一返回：

```json
{
  "code": 0, "message": "ok",
  "data": {"task_id": 123, "title": "秋季护肤要点", "quantity": 5, "status": 0, "content_type": "fluid"}
}
```

### 1. 动画视频（推荐入门，无需素材）

```
POST /open/fluid-tasks
```

专属字段：

| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
| `fluid_style` | `auto`\|`karaoke`\|`table`\|`poster`\|`terminal`\|`timeline` | auto | 视觉样式：卡点字幕 / 表格 / 海报 / 终端 / 时间轴 |

```bash
curl -X POST "https://ai-mix.chuhaibang.com/api/v1/open/fluid-tasks" \
  -H "X-Api-Key: lz_你的密钥" -H "Content-Type: application/json" \
  -d '{
    "description": "三个方法让短视频完播率翻倍",
    "voice_id": 1,
    "fluid_style": "karaoke",
    "quantity": 2,
    "target_duration": 30,
    "enable_subtitle": true
  }'
```

### 2. 数字人视频

```
POST /open/digital-human-tasks
```

专属字段：

| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
| `digital_human_id` | int | 必填 | 形象，见 `/open/digital-humans` |
| `head_duration` | 5 \| 8 \| 10 \| -1 \| -2 \| -3 | 5 | 正数=开头口播秒数；`-1`=全程口播；`-2`=片段中插；`-3`=画中画 |
| `pip_config` | object | null | 画中画配置（`head_duration=-3` 时必填）：`{"crop": {...}, "shape": "circle", "size": 0.3, "pos": {...}, "border": false}` |
| `clip_source` | `es`\|`group`\|`hot`\|`fluid` | es | 片段来源：全库检索 / 我的分组 / 热门分组 / 动画视频 |
| `fluid_style` | 同上 | auto | 动画样式（`clip_source=fluid` 与 `interlude_anim` 共用） |
| `interlude_anim` | bool | false | 穿插动画讲解：素材来源（`es`/`group`/`hot`）或全程口播（`head_duration=-1`）+ 实际配音≥20s 时，每约 60s 随机插入 1~2 段约 5s 的整屏动画卡（取当刻旁白做图文动效）。不满足条件自动忽略；单段渲染失败只跳过该段，不影响出片 |
| `clip_group_id` / `clip_group_ids` | int / int[] | null | `clip_source=group`/`hot` 时的分组 |
| `clip_group_clip_ids` | int[] | null | 精确指定片段 |
| `prefer_similar_ratio` | bool | true | 优先选画面比例接近的片段 |
| `auto_crawl` | bool | false | 保留字段（数字人任务当前不触发自动下载） |

> `head_duration=-1`（全程口播）不需要任何素材片段，可直接用。

### 3. 视频混剪

```
POST /open/tasks
```

专属字段：

| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
| `clip_source` | `es`\|`group`\|`hot` | es | 片段来源 |
| `clip_group_id` / `clip_group_ids` / `clip_group_clip_ids` | — | null | 同数字人 |
| `mute_original` | bool | false | 是否静音原片声音 |
| `prefer_similar_ratio` | bool | true | 同上 |
| `auto_crawl` | bool | false | **素材不足时自动去下载素材**（仅 `clip_source=es` 生效）：true 时任务先置 `status=5`（下载中），下载完成自动续跑 |

素材不足且 `auto_crawl=false` 时返回 400：

```json
{
  "detail": {
    "code": "INSUFFICIENT_CLIPS",
    "message": "可用片段不足（12/30）",
    "keywords": ["护肤", "秋季"],
    "clip_count": 12,
    "min_clips": 30
  }
}
```

## 任务查询

### 任务列表

```
GET /open/tasks?page=1&page_size=20&status=2&content_type=fluid&only_api=true
```

| 参数 | 说明 |
|---|---|
| `status` | 0 待处理 / 1 处理中 / 2 已完成 / 3 部分失败 / 4 全部失败 / 5 下载素材中 |
| `group_id` | 任务分组；`0` 表示未分组 |
| `content_type` | `video` / `fluid` / `digital_human`（`image` 为网页端创建的图文任务，API 不支持创建） |
| `only_api` | true = 只看通过 API 创建的任务（默认含网页端创建的） |

`data` 为分页结构 `{total, page, page_size, items}`，`items[]` 含 `id` / `title` / `status` /
`quantity` / `total_done` / `total_failed` / `content_type` / `cover_url` / `created_at` 等。

### 任务详情（含全部产出）

```
GET /open/tasks/{task_id}
```

```json
{
  "code": 0, "message": "ok",
  "data": {
    "task": {"id": 123, "status": 2, "quantity": 2, "total_done": 2, "total_failed": 0, "content_type": "fluid"},
    "jobs": [
      {
        "id": 8801, "job_index": 0, "status": 4,
        "script_text": "……成片文案……",
        "distribute_copy": "……可直接用于发布的文案……",
        "output_url": "https://.../output/xxx.mp4",
        "cover_url": "https://.../output/xxx.jpg",
        "duration": 30.2,
        "image_urls": null
      }
    ]
  }
}
```

- `jobs[].status`：0 待处理 / 1 生成台词中 / 2 检索素材中 / 3 合成中 / **4 已完成** / 5 失败。
  **判断成功要用 `4`**（0–3 都是进行中的阶段），失败看 `5` 的 `error_msg`。
- 成片取 `output_url`；封面取 `cover_url`。
- 所有 URL 都是公网可直接下载的直链。
- **成品默认只保留 1 天**（见「成品保留期」），请及时下载；需要长期留存就在提交时传 `keep_forever: true`。

### 产出分页列表

```
GET /open/tasks/{task_id}/jobs?page=1&page_size=20
```

批量很大（几百条）时用这个，避免详情接口一次返回过多数据。

### 删除任务

```
DELETE /open/tasks/{task_id}
```

删除任务及其产出文件，不可恢复，已消耗积分不退。

---

## 典型流程

```
1. GET  /open/account            # 看积分够不够
2. GET  /open/voices             # 选音色，拿 voice_id
   GET  /open/clip-groups        # （需要素材的任务）选素材分组
3. POST /open/fluid-tasks        # 提交任务，拿 task_id
4. GET  /open/tasks/{task_id}    # 每 10~30s 轮询一次
   → task.status == 2  取 jobs[].output_url
   → task.status == 3/4 看 jobs[].error_msg
5. 下载成品（默认 1 天后自动清理；要长期保留见「成品保留期」）
```

轮询建议：视频类生成耗时与 `quantity × target_duration` 正相关，通常几分钟到几十分钟；
间隔 15–30 秒即可，不要 1 秒一次。

---

## Python 示例

```python
import time
import requests

BASE = "https://ai-mix.chuhaibang.com/api/v1/open"
HEADERS = {"X-Api-Key": "lz_你的密钥", "Content-Type": "application/json"}


def post(path: str, payload: dict) -> dict:
    r = requests.post(f"{BASE}{path}", json=payload, headers=HEADERS, timeout=30)
    if r.status_code != 200:
        raise RuntimeError(f"HTTP {r.status_code}: {r.text}")
    return r.json()["data"]


def get(path: str, **params) -> dict:
    r = requests.get(f"{BASE}{path}", params=params, headers=HEADERS, timeout=30)
    if r.status_code != 200:
        raise RuntimeError(f"HTTP {r.status_code}: {r.text}")
    return r.json()["data"]


# 1) 余额与音色
print("积分：", get("/account")["total_credits"])
voice_id = get("/voices")[0]["id"]

# 2) 提交动画视频任务（不需要素材）
task = post("/fluid-tasks", {
    "description": "三个方法让短视频完播率翻倍",
    "voice_id": voice_id,
    "fluid_style": "karaoke",
    "quantity": 2,
    "target_duration": 30,
    "enable_subtitle": True,
})
task_id = task["task_id"]

# 3) 轮询到完成
while True:
    detail = get(f"/tasks/{task_id}")
    status = detail["task"]["status"]
    if status in (2, 3, 4):
        break
    print("处理中：", detail["task"]["total_done"], "/", detail["task"]["quantity"])
    time.sleep(20)

# 4) 取结果
for job in detail["jobs"]:
    if job["status"] == 2:
        print(job["output_url"])
        print("发布文案：", job.get("distribute_copy"))
    else:
        print("失败：", job.get("error_msg"))
```

---

## 让大模型直接调用（AI Skill）

个人中心「开放平台」页可下载 **Claude Skill**（`lingzao-video-skill.zip`）。
解压后把 `lingzao-video` 目录放进 Claude 的 skills 目录（Claude Code 为 `~/.claude/skills/`），
把 API 密钥写入环境变量 `LINGZAO_API_KEY`（或对话中直接给它），
之后用自然语言下指令即可，例如：

> 用数字人做 5 条讲「秋季护肤」的短视频，每条 30 秒，配轻快点的背景音乐

skill 会自行选择任务类型、查音色/素材分组、提交任务、轮询进度并把成片链接给你。
