概述
CMR Video API 根据文本提示词和可选的图片、视频素材,异步生成视频,适用于营销内容制作、短视频创作、视频编辑等场景。你只需使用统一的接口和 CMR API Key,即可调用不同厂商的视频生成模型。视频生成为异步任务:先调用创建接口提交任务并获得任务 ID,再通过查询接口轮询任务状态,任务完成后从响应中获取视频下载地址。相关操作使用以下接口:
POST /v1/videos — 创建视频生成任务GET /v1/videos/{video_id} — 查询单个任务GET /v1/videos — 查询任务列表DELETE /v1/videos/{video_id} — 取消任务
前提条件
2. 已创建模型路由实例,详细操作指导请参见 创建模型路由实例。
3. 已创建 BYOK 实例,详细操作指导请参见 创建 BYOK 实例。
4. 已创建模型路由访问密钥(API Key),详细操作指导请参见 创建模型路由访问密钥。
5. 已完成视频生成模型关联和模型路由策略配置,详细操作指导请参见 配置模型调度管理。
接口地址与鉴权
请求地址
POST {CMR_BASE_URL}/v1/videosGET {CMR_BASE_URL}/v1/videos/{video_id}GET {CMR_BASE_URL}/v1/videosDELETE {CMR_BASE_URL}/v1/videos/{video_id}
CMR_BASE_URL 为控制台展示的实例访问地址。请求使用 CMR 模型名称和 CMR API Key,无需填写厂商的接口地址或 API Key。
请求头
Header | 必填 | 说明 |
Authorization | 是 | Bearer <CMR_API_KEY> |
Content-Type | 是 | 固定为 application/json |
快速开始
将示例中的访问地址、API Key 和模型名称替换为自己的配置。
cURL
# ① 创建任务curl --request POST "${CMR_BASE_URL}/v1/videos" \\--header "Authorization: Bearer ${CMR_API_KEY}" \\--header "Content-Type: application/json" \\--data '{"model": "kling-v3","contents": [{ "type": "text", "text": "一只橙色小猫在窗台上看向镜头,阳光洒在毛发上" }],"duration": 5,"resolution": "1080p","aspect_ratio": "16:9"}'# → {"id":"video_abc123","error":null}# ② 轮询任务状态,直到 status 为 completed 或 failedcurl --request GET "${CMR_BASE_URL}/v1/videos/video_abc123" \\--header "Authorization: Bearer ${CMR_API_KEY}"# ③ status=completed 后,从 outputs[0].url 获取视频并尽快下载转存
Python
import osimport timeimport requestsbase_url = os.environ["CMR_BASE_URL"]headers = {"Authorization": f"Bearer {os.environ['CMR_API_KEY']}","Content-Type": "application/json",}# ① 创建任务resp = requests.post(f"{base_url}/v1/videos",headers=headers,json={"model": "kling-v3","contents": [{"type": "text", "text": "一只橙色小猫在窗台上看向镜头,阳光洒在毛发上"}],"duration": 5,"resolution": "1080p","aspect_ratio": "16:9",},timeout=30,)resp.raise_for_status()video_id = resp.json()["id"]# ② 轮询任务状态(建议间隔 5 秒以上)while True:task = requests.get(f"{base_url}/v1/videos/{video_id}",headers=headers,timeout=30,).json()if task["status"] in ("completed", "failed", "expired"):breaktime.sleep(5)# ③ 获取结果if task["status"] == "completed":print(task["outputs"][0]["url"]) # 视频地址,请尽快下载转存else:print(task["error"])
创建任务
POST /v1/videos
请求参数
参数 | 类型 | 必填 | 说明 |
model | string | 是 | CMR 模型名称,可用值以控制台为准 |
contents | array | 是 | |
task_type | string | 否 | 任务类型: text_to_video(文生视频)、image_to_video(图生视频)、video_reference(视频参考)。不传时按素材自动推断;显式传入时须与素材匹配 |
duration | integer | "auto" | 否 | 视频时长,单位秒。 "auto" 表示由模型自选时长(仅部分模型支持) |
resolution | string | 否 | 分辨率档位: 480p、540p、720p、768p、1080p、2k、4k |
aspect_ratio | string | 否 | 宽高比: 16:9、9:16、1:1、4:3、3:4、21:9、2:3、3:2 |
audio | string | 否 | 音频设置: native(生成视频时附带音频)、original(保留参考视频的原声,需在 contents 中包含视频素材)、none(默认,无声)。所选模型是否支持音频以模型为准,不支持时按无声处理或返回相应错误 |
seed | integer | 否 | 随机种子,用于结果复现(按模型支持) |
watermark | boolean | 否 | 是否添加水印,默认 false(按模型支持) |
negative_prompt | string | 否 | 负向提示词,描述不希望出现的内容(按模型支持) |
参数取值与模型能力:
duration、resolution、aspect_ratio 等参数的取值是否被所选模型支持,由模型侧校验——传入了模型不支持的取值时,请求会返回相应错误(错误信息来自模型侧,便于排查)。选填参数是否生效取决于所选模型,未填写的选填参数 CMR 不自动补默认值。素材结构
contents 数组中每项为一个素材对象:类型 | 格式 | 说明 |
文本 | {"type":"text","text":"..."} | 提示词,唯一入口。一个任务至少一个 |
图片 | {"type":"image","role":"first_frame" | "last_frame" | "reference","url":"...","id":"..."} | url 支持公网 URL 或 Data URI;role 标注用途(首帧/尾帧/参考图);id 为可选引用锚点,供提示词引用素材,同任务内唯一 |
视频 | {"type":"video","role":"base" | "feature","url":"...","id":"..."} | 仅支持公网 URL; base 为待编辑的主体视频,feature 为参考视频 |
主体 | {"type":"element","element_id":"..."} | 厂商侧预置的主体素材 ID(按模型支持) |
素材与任务类型的匹配:
任务类型 | contents 组成 | 说明 |
文生视频 text_to_video | 仅文本 | 传入图片或视频会返回 400 |
图生视频 image_to_video | 文本 + 图片 ≥1 | 可用首帧/尾帧/参考图;须至少一张图片 |
视频参考 video_reference | 文本 + 视频 ≥1 + 可选图片 | 以视频为参考生成新视频 |
格式约束:图片支持 jpg/jpeg/png/webp,大小 ≤50MB,短边 ≥300px;视频支持 mp4/mov,时长限制以所选模型为准。
first_frame+last_frame 与 reference 类素材不可混用;base 与 feature 视频不可混用。请求示例
图生视频(指定首帧):
{"model": "kling-v3","contents": [{ "type": "text", "text": "让画面中的主体自然转头,微风吹动头发" },{ "type": "image", "role": "first_frame", "url": "https://example.com/start.jpg" }],"duration": 5,"resolution": "1080p","aspect_ratio": "16:9"}
视频生视频:
{"model": "kling-3.0-omni","contents": [{ "type": "text", "text": "让画面主体自然转头" },{ "type": "video", "role": "feature", "url": "https://example.com/clip.mp4" }]}
响应参数
参数 | 类型 | 是否一定返回 | 说明 |
id | string | 是 | 任务 ID,后续查询、取消的唯一句柄 |
error | object | null | 是 | 成功恒为 null;失败时返回统一错误格式 |
响应示例
{"id": "video_abc123","error": null}
创建接口为异步受理:返回
id 只表示任务已受理排队,不代表生成成功,请通过查询接口获取最终结果。Provider 自定义参数
CMR 实例默认开启参数转换,并默认透传厂商自定义参数。按厂商要求将参数放入请求即可,无需逐个配置放行;如果实例已配置参数过滤规则,则按该规则处理。
例如,所选模型支持
return_last_frame(返回尾帧图,用于多段视频接力)时,可以这样请求:{"model": "doubao-seedance-2-5","contents": [{ "type": "text", "text": "清晨的咖啡馆里,一杯咖啡冒着热气" }],"return_last_frame": true}
如需设置默认值、修改参数值或过滤字段,可在目标 CMR 实例的参数转换配置中设置规则。通过管理 API 配置时,使用 CreateParamTranslationConfig 保存、TestParamTranslationConfig 预览;Video 规则的端点填写 video。配置方法和示例可参考参数协议转换说明。自定义参数的名称、填写层级和取值以厂商说明为准。更换模型或厂商后,请确认这些参数仍然适用。
查询任务
GET /v1/videos/{video_id}
路径参数
video_id 为创建时返回的任务 ID。响应参数
基本字段:
参数 | 类型 | 是否一定返回 | 说明 |
id | string | 是 | 任务 ID |
object | string | 是 | 固定为 video |
status | string | 是 | |
created_at | integer | 是 | 任务创建时间,Unix 时间戳,单位为秒 |
completed_at | integer | null | 是 | 任务到达终态的时间;未终态时为 null |
model | string | 是 | 创建请求中的模型名称 |
error | object | null | 是 | 任务失败原因;成功和进行中为 null |
outputs | array | 否 | 生成产物,仅 status=completed 时返回 |
usage | object | 否 | 用量信息,仅终态时返回 |
任务失败:查询接口本身失败(如任务不存在、无权限)返回统一错误格式;任务生成失败是任务属性而非请求失败——查询仍返回 HTTP 200,失败原因在
error 字段中。产物
outputs[](当前每个任务返回一个视频):参数 | 类型 | 是否一定返回 | 说明 |
outputs[].url | string | 是 | 视频下载地址(临时地址,请尽快转存) |
outputs[].cover_url | string | null | 是 | 封面图地址;模型未提供时为 null |
outputs[].watermark_url | string | null | 是 | 含水印版本地址;模型未提供时为 null |
outputs[].last_frame_url | string | null | 是 | 尾帧图地址(用于多段接力);未请求或模型不支持时为 null |
用量
usage(终态返回;进行中为 null):参数 | 类型 | 是否一定返回 | 说明 |
usage.seconds | integer | 是 | 实际生成时长,单位秒 |
usage.width / usage.height | integer | null | 是 | 视频像素宽高;无法确定时为 null |
usage.fps | integer | null | 是 | 帧率;模型未提供时为 null |
usage.tokens | integer | null | 是 | 按 Token 计费模型的用量;按秒计费模型为 null |
usage.billing | array | null | 是 | 部分模型返回的官方计费明细(金额、资源包抵扣等),对账依据;模型未提供时为 null |
CMR 只返回模型实际提供的用量字段内容,缺失项为
null 而非补 0。响应示例
{"id": "video_abc123","object": "video","status": "completed","created_at": 1787000000,"completed_at": 1787000300,"model": "kling-v3","error": null,"outputs": [{"url": "https://example-cdn.com/output/abc123.mp4?sign=...","cover_url": "https://example-cdn.com/output/abc123_cover.jpg?sign=...","watermark_url": null,"last_frame_url": null}],"usage": {"seconds": 5,"width": 1920,"height": 1080,"fps": 24,"tokens": null,"billing": null}}
查询任务列表
GET /v1/videos
请求参数
参数 | 类型 | 说明 |
status | string | 按状态过滤: queued、in_progress、completed、failed、expired |
model | string | 按模型名称精确过滤 |
offset | integer | 偏移量,默认 0(按创建时间降序) |
limit | integer | 每页数量,1 - 100,默认 20 |
响应参数
参数 | 类型 | 说明 |
data | array | 任务列表,每项含 id、object、status、model、created_at、completed_at、error(不含 outputs/usage,获取产物请查询单任务) |
total | integer | 满足当前过滤条件的任务总数 |
offset + limit < total 时还有下一页,由调用方自行判断。列表仅返回当前 CMR API Key 所属实例的任务。取消任务
DELETE /v1/videos/{video_id}
仅
queued(排队中)状态的任务可取消。取消成功返回 204 No Content(无响应体)。取消成功后,任务进入
failed 终态,error.code 为 cancelled。是否支持取消取决于所选模型对应的厂商:不支持时返回 405(
cancel_not_supported);任务已开始生成或已终态时返回 409(conflict)。任务状态
状态 | 说明 |
queued | 已受理,排队中(此状态可取消) |
in_progress | 生成中 |
completed | 生成成功, outputs 可用 |
failed | 生成失败(含用户取消、内容审核不通过),原因见 error |
expired | 任务超过保留期,产物已不可用 |
状态只会向前迁移,不会回退;终态(
completed/failed/expired)不再变化。建议轮询间隔 5 秒以上,避免高频查询。结果地址说明
outputs[].url 为模型侧的临时下载地址,各厂商有效期不同(最短约 12 小时),请在任务完成后尽快下载转存。地址过期后访问会失败,且 CMR 不提供重新获取地址的能力。
需要精确过期时间的调用方,可自行解析地址中的签名参数(如 URL 中的
Expires、q-sign-time 等字段,以实际返回为准)。错误响应
请求失败时,CMR 返回统一的错误格式:
{"error": {"message": "duration 7 超出模型支持范围","type": "invalid_request_error","param": "duration","code": "invalid_parameter"}}
参数 | 说明 |
error.message | 错误说明;来自模型侧的错误保留原文,便于排查 |
error.type | 错误类型 |
error.param | 相关请求参数;无法定位时为 null |
error.code | 错误码,以实际响应为准 |
常见错误码
HTTP | type | code | 场景与处理建议 |
400 | invalid_request_error | invalid_parameter | 请求格式错误、素材组合不匹配、参数取值不被模型支持。检查并修正请求 |
400 | invalid_request_error | content_policy_violation | 内容未通过审核。调整提示词或素材 |
400 | invalid_request_error | model_not_supported | 模型不存在或未绑定到实例。检查模型名称 |
401 | authentication_error | unauthorized | API Key 无效。检查 CMR_API_KEY |
403 | permission_error | capability_not_enabled | 实例未开通视频能力 |
403 | permission_error | forbidden | 访问了不属于当前 Key 的任务 |
404 | not_found_error | not_found | 任务不存在。检查 video_id |
405 | invalid_request_error | cancel_not_supported | 该模型不支持取消 |
409 | invalid_request_error | conflict | 取消的任务不在排队状态 |
429 | rate_limit_error | rate_limited | 并发任务数或创建频率超限。参考 Retry-After(如有),降低频率后重试 |
500 | api_error | internal_error | 平台内部错误。稍后重试 |
502 | api_error | upstream_error | 模型侧创建失败且重试耗尽。稍后重试;持续失败时记录任务 ID 并联系支持 |