视频生成

异步任务模型的完整流程——提交任务、轮询状态、取回视频,覆盖统一接口与 Kling、即梦官方格式路由。

视频生成是异步任务模型:提交请求只拿回 task_id,需要轮询任务状态,完成后再取视频内容。 不要期望提交接口同步返回视频。

端点总览

方法路径说明
POST/v1/video/generations提交任务(统一格式)
GET/v1/video/generations/{task_id}查询任务(统一格式响应)
POST/v1/videos提交任务(OpenAI Sora 兼容格式)
GET/v1/videos/{task_id}查询任务(OpenAI 视频格式响应)
GET/v1/videos/{task_id}/content取回视频文件内容
POST/v1/videos/{video_id}/remix基于已有视频二次创作(Sora 兼容)
POST/kling/v1/videos/text2video可灵官方格式:文生视频
POST/kling/v1/videos/image2video可灵官方格式:图生视频
GET/kling/v1/videos/text2video/{task_id}可灵官方格式:查询
GET/kling/v1/videos/image2video/{task_id}可灵官方格式:查询
POST/jimeng/?Action=...&Version=2022-08-31即梦官方格式:提交与查询合一

统一格式与 Sora 兼容格式提交的是同一种任务,task_id 通用: 用 /v1/video/generations 提交的任务也可以用 /v1/videos/{task_id} 查询,反之亦然。

第一步:提交任务

POST/v1/video/generations

通用参数

modelstring必填

视频模型 ID,如 kling-v2-masterjimeng-video-3.0-prosora-2veo-3.1-generate-preview

promptstring

文本提示词。模型无 media Schema 时必填;配置了 Schema 时以 input_schema.required 为准

imagestring

单图输入(URL 或 Base64),用于图生视频/首帧

imagesstring[]

多图输入(首尾帧、参考图等,语义随厂商而异)

durationinteger

视频时长(秒),默认值与可选值随模型而异

sizestring

尺寸或分辨率,如 1280x720720P1080P,格式随厂商而异

modestring

生成模式,可灵专用:std(标准)/ pro(高品质)

默认值: std
secondsstring

Sora 兼容参数:时长(秒)

input_referencestring

Sora 兼容参数:输入参考图

metadataobject

各 adaptor 从 metadata 读取自己已实现的字段——下文对照表之外的字段不保证下发,因为请求体会被反序列化进各厂商的强类型结构,未知键直接丢弃。只有已配置 Schema 的模型才透传 input_schema 声明的 arguments

duration/size 等通用字段不会自动转换成厂商字段名(例如不会把 duration 改名为 seconds), 各适配器只按自己的规则取通用字段;其余厂商参数放 metadata,但这不是通用的原样透传: 各适配器会把 metadata 反序列化进自己的类型结构,只有下文对照表中的字段会下发,未知键被丢弃。 受 Schema 约束的透传只适用于已配置 media Schema 的模型(见媒体工具 Schema)。

提交响应

提交成功的关键产出是任务标识。各厂商的提交响应骨架不同: 多数厂商返回 OpenAI 视频对象(含 idtask_id),Vertex 只返回 {"task_id": "..."}, Sora 透传上游原始对象(通常只有 id)。读取时统一用 id ?? task_id 兜底

响应200
{
  "id": "task_9f8e7d6c5b4a",
  "task_id": "task_9f8e7d6c5b4a",
  "object": "video",
  "model": "kling-v2-master",
  "status": "",
  "progress": 0,
  "created_at": 1753700000
}
  • 拿到任务标识后,一切进展都以轮询为准,不要解析提交响应里的 status
  • 提交响应的其余字段(modelcreated_at 等)随厂商而异,以实际返回为准

提交即预扣费。配额不足的提交会被直接拒绝(HTTP 403 quota_not_enough)。 任务失败时的退款规则见下文「失败与重试」。

第二步:轮询任务状态

两套查询路径的状态枚举不通用。 统一格式 /v1/video/generations/{task_id} 返回大写内部枚举 (SUBMITTED / IN_PROGRESS / SUCCESS / FAILURE 等),OpenAI 视频格式 /v1/videos/{task_id} 返回小写枚举(queued / in_progress / completed / failed)。 在同一条链路里混用两种判断(例如用统一格式查询却比对 completed)会让状态机永远等不到终态。 选定一种格式后全链路保持一致。

两套查询路径返回不同的响应结构与状态枚举,混用是接视频接口最常见的错误。

统一格式查询

GET/v1/video/generations/{task_id}
Veo(Gemini / Vertex 渠道)任务不要用本路径轮询。 Veo 任务在查询时实时回源, 本路径返回的是另一种结构(status 取值为 queued / processing / succeeded / failed, 而非下表的内部枚举),按下表比对 SUCCESS 会永远等不到。Veo 任务请统一用 /v1/videos/{task_id} 查询,以 completed / failed 判定终态。

响应包裹在 data 中,状态为内部任务枚举:

响应200
{
  "code": "success",
  "message": "",
  "data": {
    "task_id": "task_9f8e7d6c5b4a",
    "action": "generate",
    "status": "IN_PROGRESS",
    "fail_reason": "",
    "submit_time": 1753700000,
    "start_time": 1753700005,
    "finish_time": 0,
    "progress": "30%",
    "data": { ... }
  }
}

data 内字段全部固定返回(不存在缺省省略的情况):

task_idstring

任务 ID

actionstring

任务动作,如 generatetextGenerate

statusstring

内部状态枚举,见下表

fail_reasonstring

双语义字段:失败时是失败原因;成功时被复用为视频地址(历史设计,注意按 status 区分解读)

submit_time / start_time / finish_timeint64

提交 / 开始 / 完成时间戳,未发生时为 0

progressstring

带百分号的字符串(如 "30%"),粒度较粗,仅作展示

dataobject

上游最近一次响应原文(内联 base64 等大字段会被服务端脱敏截断),结构随厂商而异

status含义
NOT_START已创建,尚未提交上游
SUBMITTED已提交上游,等待受理
QUEUED上游排队中
IN_PROGRESS生成中
SUCCESS生成成功(终态)
FAILURE生成失败(终态),原因见 fail_reason
UNKNOWN状态未知

任务状态是如何更新的

理解状态流有助于设计轮询节奏:

  1. 提交后任务落库,初始状态 NOT_START
  2. 后台同步器每约 15 秒扫描未完成任务,逐个回源查询上游,把厂商私有状态映射为内部枚举落库
  3. Gemini / Vertex(Veo)渠道除外——它们在你的查询请求到达时实时回源刷新,其余厂商都以最近一轮后台同步为准
  4. progress 是展示用的粗粒度值:终态为 100%,进行中的取值随厂商覆盖规则而不同, 不要把它当精确进度条,更不要用它判断完成

因此轮询间隔小于 15 秒对大多数厂商不会看到更新的数据。

查询响应中的状态、进度、地址均以服务端同步结果为准,不同上游厂商返回的字段完备度不同; 下文中标注「取决于上游」的字段请以实际返回为准。

OpenAI 视频格式查询

GET/v1/videos/{task_id}

响应为 OpenAI 视频对象,状态为小写枚举:

响应200
{
  "id": "task_9f8e7d6c5b4a",
  "object": "video",
  "model": "kling-v2-master",
  "status": "completed",
  "progress": 100,
  "created_at": 1753700000,
  "completed_at": 1753700120,
  "metadata": {
    "url": "https://cdn.example.com/video.mp4"
  }
}
status对应内部状态含义
queuedSUBMITTED / QUEUED排队中
in_progressIN_PROGRESS生成中
completedSUCCESS完成,视频地址在 metadata.url
failedFAILURE失败,原因在 error.message
unknown其他(含 NOT_STARTUNKNOWN状态未知

字段完备度随上游厂商不同,带 omitempty 的字段不满足条件时整个键不会出现

字段返回条件
idobjectstatusprogresscreated_at恒定返回
model键恒定存在,但部分厂商(可灵、即梦、Vidu)值为空字符串
task_id仅部分厂商返回(豆包;Sora 透传的上游响应若含此键也会带出)
completed_at任务记录有更新时间时返回;可灵取上游时间,可能缺失
metadata.url完成后的视频地址。可灵/Vidu 仅在上游返回地址时出现;即梦/豆包/万相恒定出现(未完成时可能是空字符串);Gemini 不出现(必须走 /content 下载);Vertex 当前实现不提供产物地址(见下方「取回视频内容」的限制说明)
seconds仅可灵(取上游时长)与 Sora 透传
sizeexpires_atremixed_from_video_id仅 Sora 透传的上游响应可能包含
error失败时出现(可选,部分厂商某些失败场景不返回,如海螺在上游业务码成功但任务失败时无此键),结构为 { "message": "...", "code": "..." },读取用 error?.message 兜底。各家填充见下

Sora 渠道特殊:该格式的查询响应直接透传上游原始 JSON,字段以 OpenAI 官方视频对象为准。

失败时的响应

任务进入 FAILURE / failed 后:

  • 统一格式:data.statusFAILUREdata.fail_reason 为失败原因(上游原始错误信息透传),data.progress"100%"
  • OpenAI 格式:statusfailederror.message / error.code 承载原因。各家填充来源不同:
厂商error.message 来源error.code 来源
可灵上游 message上游数字错误码的字符串形式
即梦上游 message上游业务码(成功为 10000
海螺上游 StatusMsg上游 StatusCode
豆包固定 "task failed"(上游不返回详情)固定 "failed"
万相上游 message上游 code
Vidu上游 errcode上游 errcode
Sora上游原始错误对象透传同左

任务经后台同步首次进入失败终态时,平台自动退还预扣额度(同一任务只退一次)。

已知限制(Veo 退款竞态):Veo(Gemini / Vertex)任务若恰好由你的查询请求先观察到失败, 预扣额度可能不会自动退还,且此时失败原因可能缺失;由后台同步先观察到失败则正常退款。 对涉及 Veo 的失败任务,请以控制台额度记录为准核对,差额请联系平台处理。

第三步:取回视频内容

GET/v1/videos/{task_id}/content

直接返回视频文件流(附带上游的 Content-Type 等响应头,缓存 24 小时)。适用于两类场景:

  • 模型不暴露公开 CDN 地址(Sora、Gemini 接入的 Veo),必须经此接口下载
  • 希望隐藏上游地址、统一从积木域名下载

metadata.url 是可公开访问的 CDN 地址,也可以直接下载该地址(注意时效)。 任务未完成时调用返回 400;任务不存在返回 404。

已知限制(Vertex 产物暂不可取回):经 Vertex AI 接入的 Veo 任务,当前实现既不会在 查询响应中给出产物地址,/content 也无法下载。经 Gemini 原生 API 接入的 Veo 不受影响。

轮询建议

项目建议值
轮询间隔10–15 秒。后台同步器约 15 秒刷新一次(Veo 除外,查询时实时回源),更短的间隔看不到新数据
总超时建议 10–15 分钟,超时后标记本地失败并允许人工重查
退避策略连续多次 in_progress 后可将间隔拉长到 30 秒
完成判断只认终态:completed/SUCCESSfailed/FAILURE,不要用进度百分比判断
# 提交(任务标识用 id ?? task_id 兜底提取)
TASK_ID=$(curl -s https://api.jimu.chat/v1/video/generations \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $JIMU_API_KEY" \
  -d '{"model":"kling-v2-master","prompt":"一只猫在草地上奔跑","duration":5,"size":"1280x720"}' \
  | python -c "import sys,json;d=json.load(sys.stdin);print(d.get('id') or d.get('task_id'))")

# 轮询(每 10 秒一次)
while true; do
  STATUS=$(curl -s "https://api.jimu.chat/v1/videos/$TASK_ID" \
    -H "Authorization: Bearer $JIMU_API_KEY" \
    | python -c "import sys,json;print(json.load(sys.stdin)['status'])")
  echo "status=$STATUS"
  [ "$STATUS" = "completed" ] || [ "$STATUS" = "failed" ] && break
  sleep 10
done

# 下载
curl -L "https://api.jimu.chat/v1/videos/$TASK_ID/content" \
  -H "Authorization: Bearer $JIMU_API_KEY" -o video.mp4

失败与重试

  • 提交阶段失败(4xx/5xx):5xx 与 429 网关会自动换渠道重试;400 为请求本身问题,修复参数后再提交
  • 任务状态 failed / FAILURE:读取 error.messagefail_reason 定位原因。内容审核、提示词违规类失败不要原样重试
  • 重试新任务:失败的任务不能直接「重放」,需用相同参数重新提交一个新任务
  • 查询不存在的任务:两条查询路径对不存在的 task_id 均返回 HTTP 400(不是 404); 下载接口 /content 返回 404。task_id 只能由提交它的令牌查询,确认没跨令牌或拼写错误
HTTP 400 · task_not_exist(任务不存在)400
{
  "code": "task_not_exist",
  "message": "task_not_exist",
  "data": null
}
任务类接口的错误体形态与对话、图像等模型接口不同,三种错误形态的完整对照与排查指南见 错误处理与请求追踪

厂商参数对照

通用字段之外,厂商特有参数全部放 metadata 透传。下表按厂商列出:

可灵 Kling(kling-v1 / kling-v1-6 / kling-v2-master

metadata 参数类型说明
negative_promptstring反向提示词
image_tailstring尾帧图片 URL
cfg_scalefloat引导系数,默认 0.5
aspect_ratiostring1:1 / 16:9 / 9:16;未提供时由 size 推断
camera_controlobject镜头控制:type + config{horizontal,vertical,pan,tilt,roll,zoom}
static_mask / dynamic_masksstring / array静态/动态遮罩

通用字段映射:modemode(默认 std),duration→秒数字符串(默认 5),image→首帧。

即梦 Jimeng(jimeng-video-*jimeng_vgfm_t2v_l20

metadata 参数类型说明
aspect_ratiostring宽高比
seedint随机种子
framesint帧数

参考图不走 metadata:图生视频/参考图使用顶层 image(单张)或 images(多张,URL 或 Base64)。

海螺 MiniMax/Hailuo(MiniMax-Hailuo-*T2V-01*I2V-01*S2V-01

metadata 参数类型说明
resolutionstring512P / 720P / 768P / 1080P(可选范围随模型而异)
prompt_optimizerbool提示词自动优化
fast_pretreatmentbool快速预处理
first_frame_image / last_frame_imagestring首帧/尾帧图片 URL
subject_referencearray主体参考(仅 S2V-01),type 固定 character
aigc_watermarkboolAI 水印

时长组合:Hailuo-2.3 系列支持 6s/10s;T2V-01I2V-01S2V-01 固定 6s。

豆包 Seedance(doubao-seedance-*

metadata 参数类型说明
contentarray多模态内容,元素 typetext / image_url / video,可带 role: reference_image/first_frame/last_frame
resolution / ratiostring分辨率 / 宽高比
frames / seedint帧数 / 随机种子
generate_audiobool生成配音
camera_fixed / watermarkbool固定镜头 / 水印

万相 Wan(wan2.xwanx2.1-*

万相的上游请求是 { "input": {...}, "parameters": {...} } 结构,metadata 按同样两层组织:

metadata 参数类型说明
input.negative_promptstring反向提示词
input.first_frame_url / input.last_frame_urlstring首帧/尾帧图片
input.audio_urlstring配音音频 URL(wan2.5)
input.templatestring视频特效模板
parameters.resolutionstring480P / 720P / 1080P
parameters.sizestring精确尺寸,用 * 分隔,如 1920*10801280*720832*480
parameters.prompt_extendbool提示词智能改写,默认 true
parameters.watermark / parameters.audiobool水印 / 音频(wan2.5)
parameters.seedint随机种子

Gemini Veo(veo-3.x-*

以下参数对应 Gemini 原生 API 的 Veo 模型;经 Vertex AI 接入时参数集不同 (storageUrisampleCount 等),以实际接入方式的上游文档为准:

metadata 参数类型说明
aspectRatiostring16:9 / 9:16
durationSecondsnumber4 / 6 / 8 秒
negativePromptstring反向提示词
personGenerationstringallow_all / allow_adult
resolutionstring分辨率

Veo 查询时网关会实时回源刷新状态;产物取回方式见「取回视频内容」(Vertex 接入当前受限)。

Vidu(viduq1 / viduq2 / vidu1.5 / vidu2.0

metadata 参数类型说明
resolutionstring默认 1080p
movement_amplitudestringauto / small / medium / large
bgmbool背景音乐
seedint随机种子

images 数量决定模式:1 张=图生视频,2 张=首尾帧,3 张及以上=参考图生视频(仅 viduq2)。

Sora(sora-2 / sora-2-pro

使用 OpenAI 原生字段:seconds(时长)、sizeinput_reference(参考图), 支持 multipart/form-data 上传。建议直接用 /v1/videos 系列路径。

视频二次创作(remix)

POST/v1/videos/{video_id}/remix

基于一个已完成的 Sora 视频任务做二次创作。{video_id} 填原任务的 id

promptstring必填

二创指令(如何修改原视频),为空返回 400

返回与提交任务相同的任务标识结构,用 id ?? task_id 读取后按正常流程轮询。

官方格式兼容路由

这两组路由兼容厂商官方的请求体格式——如果你已经在用可灵或即梦的官方请求结构, 把请求地址换成积木、鉴权换成积木令牌即可,请求体不用改。 注意:响应不是厂商官方结构——提交返回任务标识,查询返回积木统一任务结构 ({"code":"success","data":{...}}),客户端需按本文前述的任务结构解析, 不能把官方 SDK 的响应模型直接对上。

可灵官方格式

POST /kling/v1/videos/text2video
POST /kling/v1/videos/image2video
GET  /kling/v1/videos/text2video/{task_id}
GET  /kling/v1/videos/image2video/{task_id}

请求体与可灵官方一致(model_namepromptimagenegative_promptaspect_ratiocamera_control 等),鉴权头换成积木令牌即可,不需要可灵的 JWT 密钥对。

curl https://api.jimu.chat/kling/v1/videos/text2video \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $JIMU_API_KEY" \
  -d '{
    "model_name": "kling-v2-master",
    "prompt": "一只猫在草地上奔跑",
    "duration": "5",
    "aspect_ratio": "16:9",
    "mode": "pro"
  }'

即梦官方格式

POST /jimeng/?Action=CVSync2AsyncSubmitTask&Version=2022-08-31   # 提交
POST /jimeng/?Action=CVSync2AsyncGetResult&Version=2022-08-31    # 查询

请求体与火山引擎即梦官方一致:提交时带 req_key(模型)、prompt 等; 查询时带 req_keytask_id。无需火山 AK/SK 签名,用积木令牌。

# 提交
curl "https://api.jimu.chat/jimeng/?Action=CVSync2AsyncSubmitTask&Version=2022-08-31" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $JIMU_API_KEY" \
  -d '{"req_key":"jimeng_vgfm_t2v_l20","prompt":"一只猫在草地上奔跑"}'

# 查询
curl "https://api.jimu.chat/jimeng/?Action=CVSync2AsyncGetResult&Version=2022-08-31" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $JIMU_API_KEY" \
  -d '{"req_key":"jimeng_vgfm_t2v_l20","task_id":"task_xxx"}'
即梦图像模型(jimeng-4.5 等)不走本页接口,而是走 /v1/chat/completions, 以 Markdown 图片链接形式返回结果,详见 对话接口