异步任务

视频生成通常需要几分钟,LYRouter 以异步任务的方式提供:POST /v1/videos 提交后立即返回一个以 aigwt_ 开头的任务 ID,之后用 GET /v1/videos/{id} 查询状态,完成后用 GET /v1/videos/{id}/content 下载视频。网关会替你向服务商轮询任务进度,你的查询只读取网关记录的状态;费用在任务完成时结算,失败或超时的任务不收费。各模型的参数、尺寸和计费单位见多模态能力,本页只讲任务的生命周期。

生命周期

步骤 方法与路径 返回
1. 提交 POST https://api.lyrouter.com/v1/videos 任务对象,status 为 queued
2. 查询 GET https://api.lyrouter.com/v1/videos/{id} 任务对象,status 随进度变化
3. 下载 GET https://api.lyrouter.com/v1/videos/{id}/content 302 跳转到视频文件地址
删除 DELETE https://api.lyrouter.com/v1/videos/{id} 任务已结束时返回任务对象并带 "deleted": true;任务记录不会因此删除,进行中的任务返回 409
  • 提交:鉴权与其他接口相同。请求体可以是 JSON,也可以是 multipart/form-data(OpenAI 官方 SDK 的 videos.create() 使用这种格式);用表单提交时,input_reference 只能填可公开访问的 https:// 地址:目前上传文件不会报错,但文件会被忽略,任务按没有参考视频的方式生成并照常计费;first_frame、last_frame、reference_image、reference_audio 请用 JSON 提交,目前它们在表单里会被换成占位值转发给服务商,导致提交被服务商拒绝或任务失败。参数见多模态能力中的「视频通用参数」和各模型章节。
  • 同一模型的其他任务:部分模型还提供 POST /v1/videos/regenerations(视频升清)和 POST /v1/videos/context(上下文增强,产出的是文本),它们返回同样的任务对象,用同样的方式查询,见多模态能力。
  • 谁能查询:同一工作空间内的任意 API Key 都能查询、下载该工作空间的任务;其他工作空间的 Key 查询时返回 404。
  • 只接受具体模型:虚拟模型和 lyrouter/auto 不能用于视频接口,失败时也不会改用默认模型。

任务对象

提交、查询返回的都是同一种任务对象。下面是一个已完成任务的示例:

{
  "id": "aigwt_volcengine_videos_MXgno8VlzuzZtJl0kq83jA",
  "object": "video",
  "model": "doubao-seedance-2-0-mini-260615",
  "status": "completed",
  "progress": 100,
  "created_at": 1791950400,
  "completed_at": 1791950538,
  "expires_at": 1792555200,
  "seconds": 5,
  "size": "1280x720",
  "usage": { "duration_seconds": 5, "completion_tokens": 108900 }
}
字段 说明
id 网关的任务 ID,格式为 aigwt_<服务商>_<任务类型>_<随机串>。它不是服务商的任务 ID,向服务商报障时请用 error.provider_request_id
object 固定为 video
model 实际调用的上游模型名,可能与请求中的模型 ID 写法不同
status queued、in_progress、completed、failed,见下表
progress 完成前为 0,完成后为 100,不表示中间进度,请以 status 判断
created_at / completed_at 提交时间、结束时间(Unix 秒)。completed_at 只在任务结束后出现
expires_at 任务记录的过期时间,提交后 7 天。过期后查询返回 404
seconds / size 原样回显提交时的值
output_text 仅上下文增强任务有,为增强后的提示词
error 仅 failed 时出现,见下文「失败的任务」
usage 任务完成后的计量:视频任务为 duration_seconds(视频秒数),按 Token 计费的模型(如 Seedance)另有 completion_tokens;上下文增强任务为 completion_tokens
status 含义 你需要做的
queued 已受理,尚未开始生成 继续轮询
in_progress 服务商正在生成 继续轮询
completed 已完成 调用 /content 下载,或读取 output_text
failed 已失败 读取 error,不收费

失败的任务

失败的任务查询时仍返回 HTTP 200,status 为 failed,原因在 error 中:

{
  "id": "aigwt_volcengine_videos_Qw3hTz0bVn1sLk8pYc4dRe",
  "object": "video",
  "model": "doubao-seedance-2-0-mini-260615",
  "status": "failed",
  "progress": 0,
  "created_at": 1791950400,
  "completed_at": 1791950482,
  "expires_at": 1792555200,
  "seconds": 5,
  "error": {
    "code": "OutputVideoSensitiveContentDetected",
    "message": "The request failed because the output video may contain sensitive information.",
    "provider_request_id": "021791950538123abcdef",
    "retryable": false
  }
}
error.code 含义
deadline_exceeded 提交后 24 小时仍未完成。目前这个状态不会同步到查询接口,GET /v1/videos/{id} 可能一直显示 queued 或 in_progress,请按下文「设置等待上限」处理
canceled 任务被取消。目前不支持取消进行中的任务,正常使用不会出现
upstream_error 服务商报告失败,但没有给出可识别的错误码
服务商的错误码 原样返回,例如 InvalidParameter、OutputVideoSensitiveContentDetected 等
  • error.provider_request_id:服务商自己的请求标识,联系服务商或 LYRouter 支持时提供它。没有时不出现。
  • error.retryable:false 表示原样重试也不会成功(例如参数不合法、内容审核未通过),需要修改请求;true 表示可以重试。网关无法判断时不出现这个字段,请不要把缺失当成 false。
  • 以上失败都不收费。

轮询建议

  • 间隔:提交后约 10 秒开始查询,之后逐步放宽到每 30 秒一次。网关在后台按自己的节奏向服务商轮询,查询得更频繁不会更早拿到结果。
  • 只在完成后下载:任务未完成时调用 /content 返回 409。这类 4xx 也会计入 API Key 的错误率,频繁调用可能触发熔断,请先查询到 completed 再下载。
  • 查询失败不等于任务失败:查询超时或网络错误时,保留任务 ID 继续查询,不要重新提交。重新提交会生成一个新任务并再次计费。
  • 设置等待上限:提交 24 小时后仍未完成的任务不会再有结果,也不收费,可以停止轮询。在控制台工作空间的 多媒体生成 页面按任务 ID 搜索,可以看到任务的「状态」(如「生成中」「已过期」)、「失败原因」和产物。
  • 服务商并发已满:提交时返回 429 upstream_concurrency_full 表示该服务商账户的并发任务已满,这个限制按服务商账户共享,换一个 API Key 也一样,请稍后重新提交。

下载产物

GET /v1/videos/{id}/content 返回 302,Location 头是服务商提供的带签名的视频地址。让客户端跟随跳转即可下载(cURL 加 -L,Python httpx 设 follow_redirects=True,Node.js 的 fetch 默认跟随)。只想拿到地址时不跟随跳转,读取 Location 头:

curl -s -o /dev/null -w '%{redirect_url}\n' \
  https://api.lyrouter.com/v1/videos/$TASK_ID/content \
  -H "Authorization: Bearer $LYROUTER_API_KEY"
  • 视频地址在任务完成时确定,之后每次调用 /content 都跳转到同一个地址。地址的有效期由服务商决定,通常为 24 小时,过期后无法通过网关重新获取,请拿到后立即下载或转存到自己的存储。
  • 上下文增强任务的结果是 output_text 中的文本,没有 /content 可下载。

计费与结算

  • 价格在提交时锁定:提交之后再调价,不影响这个任务的费用。
  • 数量按实际结果计算:任务完成时,按服务商实际返回的计量(如视频秒数、Token 数)计费,而不是按请求中填写的值。各模型的计费单位和分档见多模态能力。
  • 完成时扣费:费用在任务变为 completed 时结算;failed 的任务(包括超时)不收费。提交请求本身不产生费用。
  • 在日志中查看:在日志列表的 自定义列 中打开「任务类型」「费用」两列。提交请求的「任务类型」显示「异步」,任务结算前「费用」显示「结算中」,结算后显示该任务的费用。打开日志详情会看到「创建任务的这次请求本身不产生费用,钱记在它拉起的任务上」以及任务 ID,切换到「整个任务」可查看任务的「结算状态」和「任务费用」。失败的任务不会结算,日志列表可能一直显示「结算中」,请以 多媒体生成 页面中的任务状态为准。
  • 配额:任务的费用在结算时计入适用的信用点配额。

完整示例:提交、轮询、下载

把 MODEL_ID 换成模型广场中的视频模型 ID,并按该模型支持的取值填写 seconds、size(见多模态能力)。cURL 示例需要 jq,请保存为脚本文件后用 bash 运行(出错时用 exit 退出)。

BASE=https://api.lyrouter.com/v1
AUTH="Authorization: Bearer $LYROUTER_API_KEY"

# 1. 提交任务;没拿到任务 ID 就打印响应并退出,不要继续轮询
RESP=$(curl -s "$BASE/videos" -H "$AUTH" -H "Content-Type: application/json" \
  -d '{"model":"MODEL_ID","prompt":"一只柯基在草地上奔跑,阳光穿过树叶","seconds":5}')
TASK_ID=$(echo "$RESP" | jq -r '.id // empty')
if [ -z "$TASK_ID" ]; then echo "提交失败:$RESP"; exit 1; fi
echo "task: $TASK_ID"

# 2. 轮询:从 10 秒开始,逐步放宽到 30 秒,直到结束;最多等 2 小时
DELAY=10
GIVE_UP_AT=$(( $(date +%s) + 2 * 3600 ))
while true; do
  if [ "$(date +%s)" -gt "$GIVE_UP_AT" ]; then
    echo "$TASK_ID 仍在生成,可稍后用同一个 ID 继续查询"; exit 1
  fi
  sleep $DELAY
  DELAY=$(( DELAY * 3 / 2 > 30 ? 30 : DELAY * 3 / 2 ))
  TASK=$(curl -s "$BASE/videos/$TASK_ID" -H "$AUTH")
  STATUS=$(echo "$TASK" | jq -r '.status')
  echo "status: $STATUS"
  case "$STATUS" in
    completed|failed) break ;;
    queued|in_progress|"") ;;  # 空值多为网络抖动:保留任务 ID 继续查
    *) echo "查询出错:$TASK"; exit 1 ;;
  esac
done

# 3. 完成则下载,失败则打印原因
if [ "$STATUS" = "completed" ]; then
  curl -sL "$BASE/videos/$TASK_ID/content" -H "$AUTH" -o video.mp4
else
  echo "$TASK" | jq '.error'
fi

常见错误

错误响应为 {"error":{"message":"...","type":"...","code":"..."}}。

状态码 error.message error.code 原因与处理
404 video task not found not_found 任务 ID 不存在、已超过 7 天、属于其他工作空间,或传入的是服务商的任务 ID。确认使用提交时返回的 aigwt_ ID
409 video is not ready yet not_ready 任务还没完成(或已失败)就调用了 /content。先查询到 completed
409 cancelling an in-flight video task is not supported: ... cancel_not_supported 对进行中的任务调用了 DELETE。服务商不提供取消接口,请等待任务结束
429 upstream concurrency full upstream_concurrency_full 服务商账户的并发任务已满,换 API Key 无效,稍后重新提交
400 具体参数的校验原文 invalid_parameter 视频参数不合法,例如尺寸、时长不在模型支持的范围内。按报错修改,见多模态能力
400 unsupported parameters for this model: <参数名> unsupported_parameters 带了 X-Gateway-Strict-Parameters: true 且有模型不支持的参数,见网关扩展请求头与响应头
403 Model is not available in the model plaza model_not_available 模型没有在本工作空间开通,或使用了虚拟模型、lyrouter/auto。换用已开通的具体模型 ID
  • 用表单提交时 input_reference 只能传 URL。目前上传文件不会报错,文件会被忽略,任务按没有参考视频的方式生成并照常计费;只有填了非 URL 的文本(如 video.mp4)时才返回 400 纯文本 input_reference must be a URL; uploading a file is not supported by this gateway (pass a publicly reachable https:// URL instead)。这类由网关返回的纯文本报错,响应头目前仍是 Content-Type: application/json,解析前请先判断正文是不是 JSON。
  • 提交时服务商拒绝请求的,状态码和报错原文由服务商决定。完整列表见错误码与请求标识。