视频 API 完整调用规范
cnAPI 统一视频生成接口,覆盖文生视频、参考图片/视频/音频、首尾帧、回调、轮询、下载与错误处理。
本页是 cnAPI 对客户开放的统一视频生成规范。客户无需关心模型的内部接入方式;请始终使用本页的 cnAPI 域名、对外模型名和公开任务 ID。
当前公开视频模型共用同一套“提交→轮询/回调→下载”任务协议,但参考素材字段和能力边界按模型族区分。请勿将某一模型族的素材示例盲目套用到所有模型。
1. 接口速查
| 用途 | 方法与路径 | 说明 |
|---|---|---|
| 提交生成 | POST https://cnapi.vip/v1/videos | 提交文本和参考素材,返回任务 id |
| 查询任务 | GET https://cnapi.vip/v1/videos/{id} | 查询状态、进度和错误 |
| 获取视频 | GET https://cnapi.vip/v1/videos/{id}/content | 任务完成后获取视频文件 |
| 终态回调 | 提交时设置 callback_url | 完成或失败时向客户服务端 POST 事件 |
请求头
Authorization: Bearer sk-你的API密钥
Content-Type: application/json
Accept: application/jsonAPI 密钥必须保存在服务端,不得写入浏览器、小程序或 App 前端包。
2. 标准提交请求
最小文生视频请求
curl --request POST 'https://cnapi.vip/v1/videos' \
--header 'Authorization: Bearer sk-xxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"model": "SD2.5 720P",
"prompt": "雨夜城市中的银色跑车,低机位跟拍,霓虹倒影,电影感",
"duration": 8,
"size": "16:9"
}'duration 也可以写成字符串形式的 seconds:
{
"model": "SD2.5 720P",
"prompt": "日出时的海岸航拍,云层缓慢移动",
"seconds": "8",
"size": "16:9"
}公共请求字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
model | string | 是 | cnAPI 模型广场中显示的完整模型名 |
prompt | string | 条件必填 | 文本提示词;仅部分模型允许有参考素材时留空 |
negative_prompt | string | 否 | 多参考模型的负面提示词;Veo 使用 metadata.negativePrompt |
duration | integer | 否 | 视频时长,单位秒;与 seconds 二选一 |
seconds | string | 否 | 字符串形式的视频时长,例如 "8" |
size | string | 否 | 画面比例或尺寸,例如 16:9、1280x720 |
image | string | 否 | 单张参考图片 URL |
images | string[] | 否 | 参考图片 URL 数组,推荐用法 |
video | string | 否 | 单个参考视频 URL;Gemini Omni 必须使用此顶层字段 |
videos | string[] | 否 | 参考视频数组;其他多参考模型使用 metadata.referenceVideos |
seed | integer | 否 | 随机种子 |
generate_audio | boolean | 否 | 支持的模型上开启同步生成音频 |
camera_control | object | 否 | 镜头控制;仅在对应模型明确支持时使用 |
callback_url | string | 否 | 完成/失败终态回调地址 |
metadata | object | 否 | 参考视频、音频、首尾帧、比例等扩展字段 |
分辨率由销售模型名锁定。例如
wan3.0-video-1080p始终输出 1080P;不要依靠自行传入resolution绕过模型档位。
3. 参考图片、视频和音频
3.1 参考图片
多张图片统一使用顶层 images 数组:
{
"model": "SD2.5 720P",
"prompt": "保持人物面部、服装和配色一致,在海边缓慢行走,电影级柔光",
"duration": 10,
"size": "16:9",
"images": [
"https://cdn.example.com/character-front.jpg",
"https://cdn.example.com/character-side.jpg"
]
}单图也可以使用 image 或 input_reference,但新接入建议统一使用 images 数组。
3.2 参考视频
对能力表中支持多视频参考的 SD、Seedance、H3、Wan 和 Kling 系列,放在 metadata.referenceVideos:
{
"model": "SD2.0 720P",
"prompt": "参考镜头节奏和运镜,但保持主体外观不变",
"duration": 8,
"size": "16:9",
"images": ["https://cdn.example.com/subject.jpg"],
"metadata": {
"referenceVideos": [
"https://cdn.example.com/camera-motion.mp4"
]
}
}3.3 参考音频
对能力表中支持音频参考的 SD、Seedance、H3 和 Wan 系列,放在 metadata.referenceAudios:
{
"model": "minimax-h3-768p",
"prompt": "人物按照参考音频的节奏演唱,口型自然",
"duration": 10,
"size": "16:9",
"images": ["https://cdn.example.com/singer.jpg"],
"metadata": {
"referenceAudios": [
"https://cdn.example.com/voice-reference.mp3"
]
}
}minimax-h3-768p 使用参考音频时,必须同时提供至少一张图片、一个视频或首帧。
3.4 多参考模型的混合素材
{
"model": "SD2.5 720P",
"prompt": "使用参考图的产品外观、参考视频的镜头节奏和参考音频的声音氛围,制作科技广告",
"duration": 12,
"size": "16:9",
"images": [
"https://cdn.example.com/product-front.jpg",
"https://cdn.example.com/product-detail.jpg"
],
"metadata": {
"referenceVideos": [
"https://cdn.example.com/motion-reference.mp4"
],
"referenceAudios": [
"https://cdn.example.com/sound-reference.mp3"
]
}
}同一类素材不要同时使用多个别名字段。例如不要同时提交顶层 images 和 metadata.referenceImages;当多个兼容字段同时存在时,网关会选择其中一组,不保证合并。
3.5 素材 URL 要求
- 推荐使用可直接读取的公网 HTTPS URL。
- URL 不能依赖 Cookie、浏览器登录态、Referer 或自定义请求头。
- 不能使用
localhost、私网 IP、Docker 服务名或仅你内网可访问的地址。 - URL 在整个任务生成期间必须有效,建议有效期不少于 60 分钟。
- 图片建议使用 JPG、PNG 或 WebP;视频建议 MP4/MOV;音频建议 MP3/WAV。
- 视频建议不超过 50 MB/段,音频建议不超过 15 MB/段;过大素材可能在下载或审核阶段失败。
- 引用第三方素材前,请确保拥有必要的著作权、肖像权和使用授权。
4. 支持模型的首尾帧模式
首帧和尾帧放在 metadata.firstFrame 与 metadata.lastFrame:
{
"model": "Seedance-2.5-720p官方版",
"prompt": "从清晨的空旷广场平滑过渡到夜晚灯光亮起的同一构图",
"duration": 10,
"size": "16:9",
"metadata": {
"firstFrame": "https://cdn.example.com/start.jpg",
"lastFrame": "https://cdn.example.com/end.jpg"
}
}规则:
lastFrame不能单独使用,必须同时提供firstFrame。- 大多数支持首尾帧的模型不允许将首尾帧与普通参考图片/视频/音频混用。
- 模型能力表标记为“互斥”时,请在首尾帧和普通参考素材之间二选一。
5. 当前视频模型能力表
以下只使用 cnAPI 对外模型名。可用模型和价格以 模型广场 及账户当前权限为准。
Veo 调用差异
Veo 当前两个对外模型支持 4/6/8 秒、720P/1080P,可用于文生视频和单图生视频,不接受参考视频或参考音频。
{
"model": "veo-3.1-fast",
"prompt": "保持参考图中的主体,镜头缓慢靠近,背景云层自然移动",
"duration": 8,
"size": "1920x1080",
"images": ["https://cdn.example.com/reference.jpg"],
"metadata": {
"negativePrompt": "blur, distortion",
"generateAudio": true
}
}Veo 只读取第一张 images 图片;请不要传多张。横屏可使用 1280x720/1920x1080,竖屏可使用 720x1280/1080x1920。时长仅可选 4、6、8 秒。Veo 的负面提示词、种子和生成音频开关应使用 metadata.negativePrompt、metadata.seed 和 metadata.generateAudio。
Grok 视频调用差异
Grok 视频支持文生视频和最多一张首图,不支持多图、参考视频或参考音频。
{
"model": "grok-imagine-video-1.5",
"prompt": "保持参考图主体,从近景缓慢拉远,电影感",
"duration": 8,
"size": "16:9",
"images": ["https://cdn.example.com/start.jpg"],
"metadata": {
"resolution": "720p"
}
}grok-imagine-video 和 grok-imagine-video-1.5 可选 480P/720P;grok-imagine-video-1.5-1080p 固定 1080P,客户不应覆盖分辨率。
Gemini Omni 视频调用差异
gemini-omni-flash 固定输出 720P,支持最多 10 张图片或最多 1 个参考视频。该模型的参考视频必须使用顶层 video/videos,不是 metadata.referenceVideos。
{
"model": "gemini-omni-flash",
"prompt": "保持参考视频的镜头节奏,将主体替换为参考图中的产品",
"duration": 6,
"size": "16:9",
"images": ["https://cdn.example.com/product.jpg"],
"video": "https://cdn.example.com/reference.mp4"
}参考视频只支持 MP4/MOV,时长不得超过 10 秒,文件不得超过 64 MiB。该模型不支持参考音频和首尾帧。
| 对外模型名 | 时长 | 比例 | 输出 | 图/视频/音频上限 | 首尾帧 | 可控音效 |
|---|---|---|---|---|---|---|
veo-3.1-fast | 4/6/8 秒 | 16:9 9:16 | 720P/1080P | 1 / 0 / 0 | 不支持 | 原生音频,可用 metadata.generateAudio |
veo-3.1 | 4/6/8 秒 | 16:9 9:16 | 720P/1080P | 1 / 0 / 0 | 不支持 | 原生音频,可用 metadata.generateAudio |
grok-imagine-video | 1–15 秒 | 16:9 9:16 1:1 4:3 3:4 3:2 2:3 | 480P/720P | 1 / 0 / 0 | 不支持 | 不支持 |
grok-imagine-video-1.5 | 1–15 秒 | 同上 | 480P/720P | 1 / 0 / 0 | 不支持 | 不支持 |
grok-imagine-video-1.5-1080p | 1–15 秒 | 同上 | 1080P | 1 / 0 / 0 | 不支持 | 不支持 |
gemini-omni-flash | 3–10 秒 | 16:9 9:16 | 720P | 10 / 1 / 0 | 不支持 | 不支持 |
SD2.5 720P | 4–30 秒 | auto + 6 种常用比例 | 720P | 30 / 10 / 10 | 支持,与普通素材互斥 | 支持 generate_audio |
SD2.5 480P | 4–30 秒 | auto + 6 种常用比例 | 480P | 30 / 10 / 10 | 支持,与普通素材互斥 | 支持 generate_audio |
SD2.0 720P | 4–15 秒 | 1:1 21:9 16:9 9:16 3:4 4:3 | 720P | 9 / 3 / 3,三类合计最多 12 | 支持,与普通素材互斥 | 不可设置 |
minimax-h3-768p | 4–15 秒 | 1:1 16:9 9:16 | 768P | 10 / 5 / 5 | 支持 | 不可设置 |
Seedance-2.5-720p官方版 | 4–30 秒 | 16:9 9:16 1:1 4:3 3:4 21:9 | 720P | 30 / 10 / 10 | 支持,与普通素材互斥 | 不可设置 |
Seedance-2.0-720p官方版 | 4–15 秒 | 同上 | 720P | 9 / 3 / 3 | 支持,与普通素材互斥 | 不可设置 |
Seedance-2.0-fast-720p官方版 | 4–15 秒 | 同上 | 720P | 9 / 3 / 3 | 支持,与普通素材互斥 | 不可设置 |
seedance-2.0-mini-480p | 4–15 秒 | 同上 | 480P | 9 / 3 / 3 | 未公开,建议不传 | 不可设置 |
seedance-2.0-mini-720p | 4–15 秒 | 同上 | 720P | 9 / 3 / 3 | 未公开,建议不传 | 不可设置 |
wan3.0-video-720p | 4–30 秒 | 16:9 9:16 1:1 4:3 3:4 | 720P | 10 / 5 / 5 | 支持,与普通素材互斥 | 不可设置 |
wan3.0-video-1080p | 4–30 秒 | 同上 | 1080P | 10 / 5 / 5 | 支持,与普通素材互斥 | 不可设置 |
kling-3.0-turbo-720p | 4–15 秒 | 16:9 9:16 1:1 | 720P | 30 / 10 / 0 | 支持 | 支持 generate_audio |
kling-3.0-turbo-1080p | 4–15 秒 | 同上 | 1080P | 30 / 10 / 0 | 支持 | 支持 generate_audio |
kling-3.0-turbo-2k | 4–15 秒 | 同上 | 2K | 30 / 10 / 0 | 支持 | 支持 generate_audio |
kling-3.0-turbo-4k | 4–15 秒 | 同上 | 4K | 30 / 10 / 0 | 支持 | 支持 generate_audio |
SD2.5 720P 的“6 种常用比例”是 1:1、21:9、16:9、9:16、3:4、4:3。
模型特有规则
- Veo、Grok 和 Gemini Omni 不使用多参考模型的素材字段;必须按上方各自示例提交。
SD2.5 480P/SD2.5 720P:图片、视频、音频参考最完整;需要音效时可设置generate_audio。SD2.0 720P:三类普通参考素材各有上限,且总数不得超过 12。minimax-h3-768p:参考音频不能单独使用,必须同时有视觉参考。wan3.0-video-*:有参考素材时允许省略prompt,但为了结果可控,生产请求仍建议写明动作和镜头要求。kling-3.0-turbo-*:不支持参考音频;支持generate_audio。图片使用顶层images,视频参考仍建议使用metadata.referenceVideos。- 带分辨率后缀的模型名必须精确匹配;不要删除
-720p、-1080p、-2k或-4k。
6. 提交响应
提交成功后会立即返回公开任务 ID:
{
"id": "task_xxxxxxxxxxxxxxxxxxxxxxxx",
"task_id": "task_xxxxxxxxxxxxxxxxxxxxxxxx",
"object": "video",
"model": "SD2.5 720P",
"status": "queued",
"progress": 0,
"created_at": 1788249600
}请优先保存 id。task_id 仅用于兼容旧客户端,新接入不应只依赖它。
HTTP 200 表示“任务已被接收”,不代表视频已生成完成。
7. 轮询任务
curl 'https://cnapi.vip/v1/videos/task_xxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Authorization: Bearer sk-xxxx'统一状态
status | 含义 | 客户端动作 |
|---|---|---|
queued | 已接收,正在排队 | 继续等待 |
in_progress | 正在生成 | 继续等待 |
completed | 已完成 | 调用 /content 获取视频 |
failed | 已失败 | 读取 error.code 和 error.message |
unknown | 未知状态 | 短暂重试,持续出现时联系支持 |
完成响应示例:
{
"id": "task_xxxxxxxxxxxxxxxxxxxxxxxx",
"task_id": "task_xxxxxxxxxxxxxxxxxxxxxxxx",
"object": "video",
"model": "SD2.5 720P",
"status": "completed",
"progress": 100,
"created_at": 1788249600,
"completed_at": 1788250200
}失败响应示例:
{
"id": "task_xxxxxxxxxxxxxxxxxxxxxxxx",
"task_id": "task_xxxxxxxxxxxxxxxxxxxxxxxx",
"object": "video",
"model": "SD2.5 720P",
"status": "failed",
"progress": 100,
"error": {
"code": "video_generation_failed",
"message": "视频生成失败"
}
}轮询策略
- 提交后等待 3–5 秒再进行第一次查询。
- 建议每 10–15 秒查询一次,不要每秒轮询。
- 建议客户端总超时不少于 30 分钟。
queued或in_progress期间不要重复提交同一任务,否则可能重复计费。- 同时配置回调时,轮询可以作为容灾备用机制。
8. 回调(Webhook)
提交时设置
{
"model": "SD2.5 720P",
"prompt": "赛博朋克城市中的无人机航拍",
"duration": 8,
"size": "16:9",
"callback_url": "https://api.customer.example/webhooks/cnapi/video"
}callback_url 必须:
- 是公网可访问的 HTTP(S) URL,生产环境强烈建议 HTTPS;
- 不超过 2048 个字符;
- 不能指向私网 IP、
localhost、链路本地地址或受限制端口; - 能在 15 秒内返回任意
2xx响应。
回调只在终态发送:
video.completedvideo.failed
回调请求头
Content-Type: application/json
User-Agent: NewAPI-Task-Callback/1.0
X-NewAPI-Event: video.completed
X-NewAPI-Delivery: evt_task_xxx_completed
X-NewAPI-Timestamp: 1788250200
X-NewAPI-Signature: sha256=<hex-hmac>完成事件
{
"id": "evt_task_xxxxxxxxxxxxxxxxxxxxxxxx_completed",
"type": "video.completed",
"created_at": 1788250200,
"data": {
"task_id": "task_xxxxxxxxxxxxxxxxxxxxxxxx",
"model": "SD2.5 720P",
"status": "completed",
"progress": "100%",
"output_url": "https://cnapi.vip/v1/videos/task_xxxxxxxxxxxxxxxxxxxxxxxx/content",
"created_at": 1788249600,
"completed_at": 1788250200
}
}失败事件
{
"id": "evt_task_xxxxxxxxxxxxxxxxxxxxxxxx_failed",
"type": "video.failed",
"created_at": 1788250200,
"data": {
"task_id": "task_xxxxxxxxxxxxxxxxxxxxxxxx",
"model": "SD2.5 720P",
"status": "failed",
"progress": "100%",
"error": "视频生成失败",
"created_at": 1788249600,
"completed_at": 1788250200
}
}验证回调签名
签名秘钥是提交该任务时使用的完整 API Key(包含 sk- 前缀)。签名原文是:
X-NewAPI-Timestamp + "." + 原始请求体字节Node.js 验证示例:
import crypto from "node:crypto";
import express from "express";
const app = express();
// 必须先保留原始请求体,再解析 JSON。
app.use(
express.json({
verify: (req, _res, buffer) => {
req.rawBody = buffer;
},
}),
);
app.post("/webhooks/cnapi/video", (req, res) => {
const timestamp = req.header("X-NewAPI-Timestamp") || "";
const timestampNumber = Number(timestamp);
if (
!Number.isFinite(timestampNumber) ||
Math.abs(Date.now() / 1000 - timestampNumber) > 300
) {
return res.status(401).send("stale timestamp");
}
const received = (req.header("X-NewAPI-Signature") || "").replace(
/^sha256=/,
"",
);
const secret = process.env.API_KEY; // 完整 sk-xxxx
const signed = Buffer.concat([
Buffer.from(`${timestamp}.`, "utf8"),
req.rawBody,
]);
const expected = crypto
.createHmac("sha256", secret)
.update(signed)
.digest("hex");
const valid =
received.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected));
if (!valid) return res.status(401).send("invalid signature");
// 使用 X-NewAPI-Delivery 或 req.body.id 幂等去重。
console.log(req.body.type, req.body.data.task_id);
return res.sendStatus(204);
});回调重试和幂等
- 回调超时、网络错误或返回非
2xx时,cnAPI 会指数退避重试。 - 单次请求超时为 15 秒,最多尝试 8 次,退避上限为 15 分钟。
- 同一事件可能被投递多次。客户端必须使用
X-NewAPI-Delivery或事件id做幂等去重。 - 建议拒绝与本机时间相差超过 5 分钟的回调,降低重放风险。
- 建议先验签、保存事件并立即返回
2xx,耗时业务逻辑放入自己的异步队列。
9. 获取视频文件
任务进入 completed 后,使用内容接口:
curl --location \
'https://cnapi.vip/v1/videos/task_xxxxxxxxxxxxxxxxxxxxxxxx/content' \
--header 'Authorization: Bearer sk-xxxx' \
--output result.mp4说明:
- 客户端应允许 HTTP 3xx 跳转,
curl需要带--location。 - 返回通常为
video/mp4,也可能跳转到限时签名下载地址。 - 回调中的
output_url是不透明结果地址,可能具有有效期;不要解析其域名或路径结构。 - 不要拼接、保存或依赖任何内部任务 ID;只使用提交响应返回的公开
id。 - 如果你需要长期保存成品,应在完成后下载到自己的对象存储。
10. JavaScript 完整轮询示例
const baseUrl = "https://cnapi.vip";
const apiKey = process.env.API_KEY;
const submitResponse = await fetch(`${baseUrl}/v1/videos`, {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "SD2.5 720P",
prompt: "保持参考图的产品外观,黑色影棚中缓慢环绕运镜",
duration: 8,
size: "16:9",
images: ["https://cdn.example.com/product.jpg"],
metadata: {
referenceVideos: ["https://cdn.example.com/motion.mp4"],
},
callback_url: "https://api.customer.example/webhooks/cnapi/video",
}),
});
if (!submitResponse.ok) {
throw new Error(`submit failed: ${await submitResponse.text()}`);
}
const task = await submitResponse.json();
const deadline = Date.now() + 30 * 60 * 1000;
while (Date.now() < deadline) {
await new Promise((resolve) => setTimeout(resolve, 12000));
const response = await fetch(
`${baseUrl}/v1/videos/${encodeURIComponent(task.id)}`,
{ headers: { Authorization: `Bearer ${apiKey}` } },
);
if (!response.ok) {
throw new Error(`query failed: ${await response.text()}`);
}
const state = await response.json();
if (state.status === "completed") {
console.log(
`${baseUrl}/v1/videos/${encodeURIComponent(task.id)}/content`,
);
break;
}
if (state.status === "failed") {
throw new Error(state.error?.message || "video generation failed");
}
}11. 错误处理与重试
| 情况 | 处理建议 |
|---|---|
| HTTP 400 | 检查模型名、时长、比例、素材数量与字段位置 |
| HTTP 401 | API Key 缺失、错误或已失效 |
| HTTP 403 | 当前 Key 无模型或分组权限 |
| HTTP 404 | 任务不存在、不属于当前账户,或成品尚未就绪 |
| HTTP 429 | 请求过快或额度限制;按 Retry-After 或指数退避 |
| HTTP 5xx | 暂时服务错误;查询请求可退避重试 |
status=failed | HTTP 查询成功但生成失败;读取 error.message |
| 素材下载失败 | 确认 URL 公网可达、未过期、无防盗链和鉴权依赖 |
| 内容安全拦截 | 调整提示词或参考素材,不要原样无限重试 |
POST /v1/videos 暂不提供客户自定义的幂等键保证。如果客户在已发出完整请求后遇到网络超时,不要盲目立即重发,否则可能生成并计费多个任务。
这篇文档对您有帮助吗?