API 开发者文档

视频生成 API

用统一、稳定、易接入的 API,把文本、图片、音视频与首尾帧素材快速转化为视频内容。

概述

项目值
Base URLhttps://new.tangzhi.org
用户工作台https://new.tangzhi.org
模型定价https://docs.tangzhi.org/pricing

快速开始

创建 API 密钥,提交生成请求,然后使用任务 ID 查询结果并下载视频。

01 创建密钥登录控制台,在「令牌」页面创建 API Key,妥善保存在服务端环境变量中。
02 提交请求选择模型,传入提示词、画幅、时长和参考素材,获得任务 ID。
03 获取结果轮询任务状态,完成后通过 /content 地址下载视频文件。

鉴权与请求头

所有 API 请求使用 Bearer Token。API Key 仅应保存在服务端,不要写入浏览器代码、公开仓库或日志。

请求头值说明
AuthorizationBearer 你的_API_KEY必填,用于识别账户和调用权限
Content-Typeapplication/jsonJSON 请求必填
Authorization: Bearer 你的_API_KEY
Content-Type: application/json

接口端点

所有视频模型共用以下三个端点:

POST/v1/videos创建视频生成任务
GET/v1/videos/:taskId查询任务状态和进度
GET/v1/videos/:taskId/content下载已完成任务的视频文件

通用请求参数

创建任务时使用以下参数,具体约束(如 prompt 长度、可选值)因模型而异,详见 模型定价。

参数类型必填说明
modelstring是模型名称,以 模型定价 中开放调用的模型为准
promptstring是视频内容描述,长度限制因模型而异
modestring是references / frames(默认 references)
aspect_ratiostring否画面比例,如 16:9、9:16,范围因模型而异
durationnumber否视频时长(秒),范围因模型而异;按秒计费模型按此时长计费
resolutionstring否分辨率,如 480p、720p、1080p,需与模型匹配
referencesobject否参考素材块,留空即为纯文生视频
framesobject条件mode=frames 时必填
client_task_idstring是幂等任务 ID,最长 128 字符,仅支持字母、数字、下划线、连字符和点号
mode 互斥:references 模式不能带 frames,frames 模式不能带 references。

references 结构

参考素材放在 references 对象内,当前仅支持公网可访问的 URL,不支持 multipart/form-data 文件上传,也不接收 base64 / data URL。

{
  "references": {
    "image": "https://example.com/ref.jpg",
    "images": ["https://example.com/ref1.jpg", "https://example.com/ref2.jpg"],
    "video": "https://example.com/ref.mp4",
    "videos": ["https://example.com/ref1.mp4", "https://example.com/ref2.mp4"],
    "audio": "https://example.com/ref.mp3",
    "audios": ["https://example.com/ref1.mp3", "https://example.com/ref2.mp3"]
  }
}
字段类型说明
imagestring单张参考图(1 张时用此字段)
imagesstring[]多张参考图(≥2 张时用此字段)
videostring单个参考视频(1 条时用此字段)
videosstring[]多个参考视频(≥2 条时用此字段)
audiostring单个参考音频(1 条时用此字段)
audiosstring[]多个参考音频(≥2 条时用此字段)
image/images、video/videos、audio/audios 两两互斥。只有 1 个元素时必须用单数字段,≥2 个才能用复数字段;空数组、单元素数组均返回 400。各模型可用的图片/音频/视频数量上限见 模型定价。

frames 结构

首尾帧驱动模式,需将 mode 设为 frames。

{
  "frames": {
    "first_frame": "https://example.com/start.jpg",
    "last_frame": "https://example.com/end.jpg"
  }
}
字段类型必填说明
first_framestring是首帧图片 URL
last_framestring是尾帧图片 URL

响应格式

创建任务响应

{
  "id": "task_abc123def456",
  "object": "video",
  "model": "ch0101-sd-2.0-720p",
  "status": "queued",
  "progress": 0,
  "created_at": 1790403391
}

查询任务响应

完成状态:

{
  "id": "task_abc123def456",
  "object": "video",
  "model": "ch0101-sd-2.0-720p",
  "status": "completed",
  "progress": 100,
  "created_at": 1790403391,
  "completed_at": 1790403523
}

失败状态:

{
  "id": "task_abc123def456",
  "object": "video",
  "model": "ch0101-sd-2.0-720p",
  "status": "failed",
  "progress": 100,
  "created_at": 1790403391,
  "completed_at": 1790403523,
  "error": {
    "code": "video_generation_failed",
    "message": "失败原因描述"
  }
}

响应字段说明

字段类型出现时机说明
idstring始终任务唯一标识,用于查询与下载
objectstring始终固定值 "video"
modelstring始终使用的模型名
statusstring始终任务状态,见 任务状态
progressnumber始终进度百分比 0-100
created_atnumber始终创建时间戳(Unix 秒)
completed_atnumbercompleted / failed完成或失败时间戳
errorobjectfailed失败信息,含 code 与 message

任务完成后,使用 GET /v1/videos/:taskId/content 下载视频文件(video/mp4)。

任务状态

状态说明
queued任务已创建,等待处理
in_progress任务正在处理中
completed任务完成,通过 GET /v1/videos/:taskId/content 下载视频
failed任务失败,error.message 含失败原因
unknown未知状态,请稍后重新查询

建议每 5-15 秒查询一次,生成通常需要 1-6 分钟,视模型、时长与排队情况而定。

client_task_id 幂等说明

每次创建任务都必须传入 client_task_id,建议使用你业务系统里的唯一订单号。

场景建议
首次创建任务使用新的 client_task_id
请求超时使用同一个 client_task_id 重试,避免同一业务订单生成新任务
视频取回失败使用同一个 client_task_id 重新提交,系统会继续尝试取回同一任务结果
新业务订单使用新的 client_task_id
不要为同一笔业务订单随机更换 client_task_id。任务进行中或已完成时重复提交,请求会被拒绝,请使用原任务 ID 查询。

错误处理

请求失败时返回非 2xx 状态码,响应体格式如下:

{
  "error": {
    "code": "invalid_params",
    "message": "具体错误描述",
    "type": "new_api_error"
  }
}
HTTP 状态码常见原因
400参数错误:缺少必填字段、素材字段单复数用法错误、时长或分辨率超出模型范围
401API Key 缺失、无效或已禁用
403余额不足,或当前分组无权调用该模型
429请求过于频繁,请降低频率后重试
503模型暂时不可用(model_not_found),请确认模型名称或稍后重试

按秒计费的模型在提交时按 duration 预扣费用,任务失败会退回。

代码示例

创建任务

curl -X POST https://new.tangzhi.org/v1/videos \
  -H "Authorization: Bearer 你的_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "ch0101-sd-2.0-720p",
    "prompt": "人物向前走,背景流动变换",
    "client_task_id": "order_20260926_000001",
    "mode": "references",
    "aspect_ratio": "16:9",
    "duration": 5,
    "resolution": "720p"
  }'

图生视频(参考图)

curl -X POST https://new.tangzhi.org/v1/videos \
  -H "Authorization: Bearer 你的_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "ch0101-sd-2.0-720p",
    "prompt": "让画面中的人物微笑并挥手",
    "client_task_id": "order_20260926_000002",
    "mode": "references",
    "duration": 5,
    "resolution": "720p",
    "references": { "image": "https://example.com/ref.jpg" }
  }'

首尾帧

curl -X POST https://new.tangzhi.org/v1/videos \
  -H "Authorization: Bearer 你的_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "ch0101-sd-2.0-720p",
    "prompt": "镜头从白天平滑过渡到夜晚",
    "client_task_id": "order_20260926_000003",
    "mode": "frames",
    "duration": 5,
    "resolution": "720p",
    "frames": {
      "first_frame": "https://example.com/start.jpg",
      "last_frame": "https://example.com/end.jpg"
    }
  }'

查询任务状态

curl https://new.tangzhi.org/v1/videos/task_abc123def456 \
  -H "Authorization: Bearer 你的_API_KEY"

下载视频

curl -o output.mp4 https://new.tangzhi.org/v1/videos/task_abc123def456/content \
  -H "Authorization: Bearer 你的_API_KEY"

Python 完整轮询示例

import time
import requests

BASE = "https://new.tangzhi.org"
HEADERS = {"Authorization": "Bearer sk-xxxxxxxxxxxxxxxx", "Content-Type": "application/json"}
CLIENT_TASK_ID = "order_20260926_000001"

# 1. 创建任务
resp = requests.post(f"{BASE}/v1/videos", headers=HEADERS, json={
    "model": "ch0101-sd-2.0-720p",
    "prompt": "人物向前走,背景流动变换",
    "client_task_id": CLIENT_TASK_ID,
    "mode": "references",
    "aspect_ratio": "16:9",
    "duration": 5,
    "resolution": "720p"
}, timeout=120)
resp.raise_for_status()
task_id = resp.json()["id"]
print(f"任务已创建:{task_id}")

# 2. 轮询任务状态
while True:
    task = requests.get(f"{BASE}/v1/videos/{task_id}", headers=HEADERS, timeout=30).json()
    status = task["status"]
    print(f"状态: {status} ({task.get('progress', 0)}%)")
    if status in ("completed", "failed"):
        break
    time.sleep(10)

# 3. 下载视频
if task["status"] == "completed":
    video = requests.get(f"{BASE}/v1/videos/{task_id}/content", headers=HEADERS, timeout=300).content
    with open("output.mp4", "wb") as f:
        f.write(video)
    print("已保存 output.mp4")
else:
    print(f"失败: {task.get('error', {}).get('message', '未知原因')}")

Node.js 示例

const BASE = "https://new.tangzhi.org";
const headers = { Authorization: "Bearer sk-xxxxxxxxxxxxxxxx", "Content-Type": "application/json" };

const created = await fetch(`${BASE}/v1/videos`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    model: "ch0101-sd-2.0-720p",
    prompt: "人物向前走,背景流动变换",
    client_task_id: "order_20260926_000001",
    mode: "references",
    duration: 5,
    resolution: "720p",
  }),
}).then((r) => r.json());

let task;
do {
  await new Promise((r) => setTimeout(r, 10000));
  task = await fetch(`${BASE}/v1/videos/${created.id}`, { headers }).then((r) => r.json());
  console.log(task.status, task.progress);
} while (!["completed", "failed"].includes(task.status));

模型与定价

全部可用模型、素材数量上限、时长范围、分辨率、人脸限制与实时价格,请查看 模型定价表。价格与控制台实时同步。