获取视频生成任务状态
通过创建视频生成任务提交任务后,轮询 GET /v1/video/generations/{task_id} 直到任务进入终态,再从 GET /v1/videos/{task_id}/content 下载视频。轮询读取的是 RouteAPI 在后台刷新的任务记录,因此 10–15 秒的间隔已经足够。
获取任务记录
Section titled “获取任务记录”GET /v1/video/generations/{task_id}任务按 API Key 所属用户隔离:属于其他账户的 task_id 会被报告为 task_not_exist。
curl https://api.routeapi.ai/v1/video/generations/task_G2RdWGt4t1nck5fYqTjwREKJo8Ze4RAV \ -H "Authorization: Bearer $ROUTEAPI_KEY"{ "code": "success", "message": "", "data": { "id": 4512, "created_at": 1792048450, "updated_at": 1792048569, "task_id": "task_G2RdWGt4t1nck5fYqTjwREKJo8Ze4RAV", "platform": "54", "user_id": 1024, "group": "default", "channel_id": 18, "quota": 123456, "action": "generate", "status": "SUCCESS", "progress": "100%", "fail_reason": "", "result_url": "https://...mp4", "submit_time": 1792048458, "start_time": 1792048461, "finish_time": 1792048569, "properties": { "input": "", "origin_model_name": "seedance-2.0-fast" }, "data": { "id": "cgt-xxxxxxxx", "status": "succeeded" } }}任务记录字段
Section titled “任务记录字段”| 字段 | 说明 |
|---|---|
code | 任务可读时为 "success";失败时使用下文的任务错误结构 |
data.id | 内部行 ID,任何请求都不使用 |
data.task_id | RouteAPI 任务 ID——轮询和下载都用它 |
data.status | NOT_START、SUBMITTED、QUEUED、IN_PROGRESS、SUCCESS 或 FAILURE |
data.progress | 进度字符串,如 "30%" 或 "100%" |
data.result_url | 任务成功后的视频 URL。它可能指向 RouteAPI 下载端点,也可能直接指向上游有期限的 URL |
data.fail_reason | 失败原因,其余情况为空 |
data.submit_time / start_time / finish_time | Unix 秒。任务开始和结束前,start_time、finish_time 为 0 |
data.created_at / updated_at | Unix 秒,该行的创建时间与最后更新时间 |
data.quota | 该任务扣除的额度 |
data.platform | 执行该任务的上游渠道类型编号 |
data.group / data.channel_id / data.user_id | 计费分组、渠道与所属账户。向支持咨询任务时有用 |
data.action | 任务类型:generate、textGenerate、firstTailGenerate、referenceGenerate 或 remixGenerate |
data.properties | 存储的任务属性:origin_model_name、upstream_model_name,适配器采集时 input 中还有上游请求快照。仅供排查 |
data.data | 上游供应商最新的任务响应体,为调试而存储。其结构因供应商而异 |
| 状态 | 含义 | 下一步 |
|---|---|---|
NOT_START | 任务行已建立,但尚未轮询上游 | 继续轮询 |
SUBMITTED / QUEUED | 已受理,在供应商队列中等待 | 继续轮询 |
IN_PROGRESS | 正在生成 | 继续轮询 |
SUCCESS | 成功终态 | 下载视频 |
FAILURE | 失败终态 | 读取 fail_reason;预扣金额已退回 |
只有 SUCCESS 是成功终态;FAILURE 是失败终态,看到它时预扣金额已经退回。其他状态都表示需要继续轮询。
import osimport timeimport requests
BASE = "https://api.routeapi.ai"HEADERS = {"Authorization": f"Bearer {os.environ['ROUTEAPI_KEY']}"}
task_id = requests.post( f"{BASE}/v1/video/generations", headers=HEADERS, json={ "model": "seedance-2.0-fast", "prompt": "An orange cat stretching on a windowsill at sunrise", "duration": 5, "resolution": "720p", "ratio": "16:9", }, timeout=60,).json()["task_id"]
while True: task = requests.get(f"{BASE}/v1/video/generations/{task_id}", headers=HEADERS, timeout=30).json()["data"] print(task["status"], task["progress"])
if task["status"] == "SUCCESS": video = requests.get(f"{BASE}/v1/videos/{task_id}/content", headers=HEADERS, timeout=300) video.raise_for_status() with open(f"{task_id}.mp4", "wb") as f: f.write(video.content) break if task["status"] == "FAILURE": raise SystemExit(f"task failed: {task['fail_reason']}")
time.sleep(15)完整 Shell 示例
Section titled “完整 Shell 示例”#!/usr/bin/env bashset -euo pipefail: "${ROUTEAPI_KEY:?set ROUTEAPI_KEY first}"BASE="${ROUTEAPI_BASE:-https://api.routeapi.ai}"AUTH="Authorization: Bearer $ROUTEAPI_KEY"
TASK_ID=$(curl -sS -X POST "$BASE/v1/video/generations" \ -H "$AUTH" -H "Content-Type: application/json" \ -d '{"model":"seedance-2.0-fast","prompt":"An orange cat stretching on a windowsill at sunrise","duration":4,"resolution":"480p","ratio":"16:9"}' \ | jq -er .task_id)
echo "task: $TASK_ID"
for _ in $(seq 1 60); do RESP=$(curl -sS "$BASE/v1/video/generations/$TASK_ID" -H "$AUTH") STATUS=$(echo "$RESP" | jq -r .data.status) echo "status: $STATUS $(echo "$RESP" | jq -r .data.progress)"
case "$STATUS" in SUCCESS) curl -sSL -o "$TASK_ID.mp4" "$BASE/v1/videos/$TASK_ID/content" -H "$AUTH" echo "saved $TASK_ID.mp4" exit 0 ;; FAILURE) echo "failed: $(echo "$RESP" | jq -r .data.fail_reason)" exit 1 ;; esac
sleep 15done
echo "timed out waiting for the task"exit 1轮询 GET /v1/video/generations/{task_id} 通常只读取本地任务记录,因此把间隔保持在 10–15 秒,不要高频请求端点。
GET /v1/videos/{task_id}/content通过 RouteAPI 流式传输视频字节,调用方无需访问供应商的存储。响应带有 Cache-Control: public, max-age=86400 和上游的 Content-Type(内联 Base64 结果默认 video/mp4)。
curl -L -o out.mp4 \ https://api.routeapi.ai/v1/videos/task_G2RdWGt4t1nck5fYqTjwREKJo8Ze4RAV/content \ -H "Authorization: Bearer $ROUTEAPI_KEY"该路由接受 API Key 或控制台会话,且只返回调用方自己任务的视频数据。其错误使用 {"error": {"message": "...", "type": "..."}} 对象结构:
| 状态码 | 含义 |
|---|---|
| 400 | 任务尚未完成;消息中带有当前状态 |
| 404 | 任务未知,或该任务属于其他账户 |
| 403 | 解析出的视频 URL 被出站访问保护规则拒绝 |
| 500 | 任务行或其渠道读取失败,或视频 URL 无法解析 |
| 502 | 无法连接供应商、供应商返回非 200 状态码,或视频 URL 为空 |
| 状态码 | 错误码 | 含义 |
|---|---|---|
| 400 | task_not_exist | task_id 未知或属于其他账户 |
| 500 | get_task_failed | RouteAPI 无法读取自身的任务行 |
| 500 | marshal_response_failed、copy_response_body_failed | RouteAPI 无法序列化或写出响应 |
在路由之前被拒绝的请求使用标准的中间件错误体 {"error": {"message": ..., "type": "error", "code": ...}},而不是任务结构。
- 创建视频生成任务 — 提交任务与通用请求格式。
- OpenAI 视频格式 — 同一任务的
/v1/videos方言与remix。 - 素材(Assets) — 素材 API 返回
404表示该账户尚无素材空间。 - 常见错误 — 所有模型端点共用的状态码。