動画生成タスクの取得
動画生成タスクの作成でタスクを送信したら、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 は終了状態の失敗で、これが見えた時点で予約額はすでに返金されています。それ以外はすべてポーリングを続けることを意味します。
ポーリングの例
Section titled “ポーリングの例”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)完全なシェル例
Section titled “完全なシェル例”#!/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 1GET /v1/video/generations/{task_id} のポーリングは通常ローカルのタスクレコードを読むだけなので、間隔は 10〜15 秒に保ち、エンドポイントを叩きすぎないようにしてください。
動画をダウンロードする
Section titled “動画をダウンロードする”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": ...}} を使用します。
次のステップ
Section titled “次のステップ”- 動画生成タスクの作成 — タスクの送信と共通リクエスト形式。
- OpenAI 動画形式 — 同じタスクの
/v1/videos方言とremix。 - Assets(アセット) — アセット API の
404は、アカウントにまだアセット空間がないことを意味します。 - よくあるエラー — すべてのモデルエンドポイントが共有するステータスコード。