cnAPIcnAPI
API 文档视频(Video)

视频 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/json

API 密钥必须保存在服务端,不得写入浏览器、小程序或 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"
}

公共请求字段

字段类型必填说明
modelstringcnAPI 模型广场中显示的完整模型名
promptstring条件必填文本提示词;仅部分模型允许有参考素材时留空
negative_promptstring多参考模型的负面提示词;Veo 使用 metadata.negativePrompt
durationinteger视频时长,单位秒;与 seconds 二选一
secondsstring字符串形式的视频时长,例如 "8"
sizestring画面比例或尺寸,例如 16:91280x720
imagestring单张参考图片 URL
imagesstring[]参考图片 URL 数组,推荐用法
videostring单个参考视频 URL;Gemini Omni 必须使用此顶层字段
videosstring[]参考视频数组;其他多参考模型使用 metadata.referenceVideos
seedinteger随机种子
generate_audioboolean支持的模型上开启同步生成音频
camera_controlobject镜头控制;仅在对应模型明确支持时使用
callback_urlstring完成/失败终态回调地址
metadataobject参考视频、音频、首尾帧、比例等扩展字段

分辨率由销售模型名锁定。例如 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"
  ]
}

单图也可以使用 imageinput_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"
    ]
  }
}

同一类素材不要同时使用多个别名字段。例如不要同时提交顶层 imagesmetadata.referenceImages;当多个兼容字段同时存在时,网关会选择其中一组,不保证合并。

3.5 素材 URL 要求

  1. 推荐使用可直接读取的公网 HTTPS URL。
  2. URL 不能依赖 Cookie、浏览器登录态、Referer 或自定义请求头。
  3. 不能使用 localhost、私网 IP、Docker 服务名或仅你内网可访问的地址。
  4. URL 在整个任务生成期间必须有效,建议有效期不少于 60 分钟。
  5. 图片建议使用 JPG、PNG 或 WebP;视频建议 MP4/MOV;音频建议 MP3/WAV。
  6. 视频建议不超过 50 MB/段,音频建议不超过 15 MB/段;过大素材可能在下载或审核阶段失败。
  7. 引用第三方素材前,请确保拥有必要的著作权、肖像权和使用授权。

4. 支持模型的首尾帧模式

首帧和尾帧放在 metadata.firstFramemetadata.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.negativePromptmetadata.seedmetadata.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-videogrok-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-fast4/6/8 秒16:9 9:16720P/1080P1 / 0 / 0不支持原生音频,可用 metadata.generateAudio
veo-3.14/6/8 秒16:9 9:16720P/1080P1 / 0 / 0不支持原生音频,可用 metadata.generateAudio
grok-imagine-video1–15 秒16:9 9:16 1:1 4:3 3:4 3:2 2:3480P/720P1 / 0 / 0不支持不支持
grok-imagine-video-1.51–15 秒同上480P/720P1 / 0 / 0不支持不支持
grok-imagine-video-1.5-1080p1–15 秒同上1080P1 / 0 / 0不支持不支持
gemini-omni-flash3–10 秒16:9 9:16720P10 / 1 / 0不支持不支持
SD2.5 720P4–30 秒auto + 6 种常用比例720P30 / 10 / 10支持,与普通素材互斥支持 generate_audio
SD2.5 480P4–30 秒auto + 6 种常用比例480P30 / 10 / 10支持,与普通素材互斥支持 generate_audio
SD2.0 720P4–15 秒1:1 21:9 16:9 9:16 3:4 4:3720P9 / 3 / 3,三类合计最多 12支持,与普通素材互斥不可设置
minimax-h3-768p4–15 秒1:1 16:9 9:16768P10 / 5 / 5支持不可设置
Seedance-2.5-720p官方版4–30 秒16:9 9:16 1:1 4:3 3:4 21:9720P30 / 10 / 10支持,与普通素材互斥不可设置
Seedance-2.0-720p官方版4–15 秒同上720P9 / 3 / 3支持,与普通素材互斥不可设置
Seedance-2.0-fast-720p官方版4–15 秒同上720P9 / 3 / 3支持,与普通素材互斥不可设置
seedance-2.0-mini-480p4–15 秒同上480P9 / 3 / 3未公开,建议不传不可设置
seedance-2.0-mini-720p4–15 秒同上720P9 / 3 / 3未公开,建议不传不可设置
wan3.0-video-720p4–30 秒16:9 9:16 1:1 4:3 3:4720P10 / 5 / 5支持,与普通素材互斥不可设置
wan3.0-video-1080p4–30 秒同上1080P10 / 5 / 5支持,与普通素材互斥不可设置
kling-3.0-turbo-720p4–15 秒16:9 9:16 1:1720P30 / 10 / 0支持支持 generate_audio
kling-3.0-turbo-1080p4–15 秒同上1080P30 / 10 / 0支持支持 generate_audio
kling-3.0-turbo-2k4–15 秒同上2K30 / 10 / 0支持支持 generate_audio
kling-3.0-turbo-4k4–15 秒同上4K30 / 10 / 0支持支持 generate_audio

SD2.5 720P 的“6 种常用比例”是 1:121:916:99:163:44: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
}

请优先保存 idtask_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.codeerror.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": "视频生成失败"
  }
}

轮询策略

  1. 提交后等待 3–5 秒再进行第一次查询。
  2. 建议每 10–15 秒查询一次,不要每秒轮询。
  3. 建议客户端总超时不少于 30 分钟
  4. queuedin_progress 期间不要重复提交同一任务,否则可能重复计费。
  5. 同时配置回调时,轮询可以作为容灾备用机制。

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.completed
  • video.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 401API Key 缺失、错误或已失效
HTTP 403当前 Key 无模型或分组权限
HTTP 404任务不存在、不属于当前账户,或成品尚未就绪
HTTP 429请求过快或额度限制;按 Retry-After 或指数退避
HTTP 5xx暂时服务错误;查询请求可退避重试
status=failedHTTP 查询成功但生成失败;读取 error.message
素材下载失败确认 URL 公网可达、未过期、无防盗链和鉴权依赖
内容安全拦截调整提示词或参考素材,不要原样无限重试

POST /v1/videos 暂不提供客户自定义的幂等键保证。如果客户在已发出完整请求后遇到网络超时,不要盲目立即重发,否则可能生成并计费多个任务。

How is this guide?