Aller au contenu

Obtenir une tâche vidéo

Après avoir soumis une tâche via Créer une tâche vidéo, interrogez GET /v1/video/generations/{task_id} jusqu’à ce que la tâche atteigne un état terminal, puis téléchargez la vidéo depuis GET /v1/videos/{task_id}/content. L’interrogation lit un enregistrement que RouteAPI rafraîchit en arrière-plan, donc un intervalle de 10 à 15 secondes suffit.

GET /v1/video/generations/{task_id}

Les tâches sont limitées à l’utilisateur de la clé API : un task_id appartenant à un autre compte est signalé comme task_not_exist.

Fenêtre de terminal
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" }
}
}
ChampDescription
code"success" pour une tâche lisible ; en cas d’échec, la forme d’erreur de tâche décrite plus bas
data.idID de ligne interne ; utilisé dans aucune requête
data.task_idID de tâche RouteAPI — la valeur à utiliser pour interroger et télécharger
data.statusNOT_START, SUBMITTED, QUEUED, IN_PROGRESS, SUCCESS ou FAILURE
data.progressChaîne de progression comme "30%" ou "100%"
data.result_urlURL de la vidéo une fois la tâche réussie. Elle peut pointer vers le point de terminaison de téléchargement RouteAPI ou directement vers une URL amont à durée de vie limitée
data.fail_reasonRaison de l’échec ; vide sinon
data.submit_time / start_time / finish_timeSecondes Unix. start_time et finish_time valent 0 avant le démarrage et la fin
data.created_at / updated_atSecondes Unix, date de création et date de dernière mise à jour de la ligne
data.quotaQuota facturé pour la tâche
data.platformType numérique du canal amont qui a exécuté la tâche
data.group / data.channel_id / data.user_idGroupe de facturation, canal et compte propriétaire. Utile pour un échange avec le support
data.actionType de tâche : generate, textGenerate, firstTailGenerate, referenceGenerate ou remixGenerate
data.propertiesPropriétés stockées : origin_model_name, upstream_model_name, et l’instantané de la requête amont dans input lorsque l’adaptateur l’enregistre. Pour le diagnostic
data.dataDernière charge utile de tâche du fournisseur amont, stockée pour le débogage. Sa forme dépend du fournisseur
StatutSignificationAction
NOT_STARTLa ligne existe mais l’amont n’a pas encore été interrogéContinuer à interroger
SUBMITTED / QUEUEDAcceptée, en attente dans la file du fournisseurContinuer à interroger
IN_PROGRESSEn cours de générationContinuer à interroger
SUCCESSSuccès terminalTélécharger la vidéo
FAILUREÉchec terminalLire fail_reason ; le montant réservé a déjà été remboursé

Seul SUCCESS est un succès terminal ; FAILURE est un échec terminal et le montant réservé a déjà été remboursé au moment où vous le voyez. Tout le reste signifie continuer à interroger.

import os
import time
import 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)
#!/usr/bin/env bash
set -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 15
done
echo "timed out waiting for the task"
exit 1

L’interrogation de GET /v1/video/generations/{task_id} ne lit normalement que l’enregistrement local, gardez donc un intervalle de 10 à 15 secondes plutôt que de marteler le point de terminaison.

GET /v1/videos/{task_id}/content

Diffuse les octets de la vidéo via RouteAPI, l’appelant n’a donc pas besoin d’atteindre le stockage du fournisseur. La réponse porte Cache-Control: public, max-age=86400 et le Content-Type amont (par défaut video/mp4 pour les résultats Base64 intégrés).

Fenêtre de terminal
curl -L -o out.mp4 \
https://api.routeapi.ai/v1/videos/task_G2RdWGt4t1nck5fYqTjwREKJo8Ze4RAV/content \
-H "Authorization: Bearer $ROUTEAPI_KEY"

Cette route accepte une clé API ou une session console, et ne renvoie que les données des tâches appartenant à l’appelant. Ses erreurs utilisent la forme objet {"error": {"message": "...", "type": "..."}} :

StatutSignification
400La tâche n’est pas encore terminée ; le message contient le statut actuel
404Tâche inconnue, ou tâche appartenant à un autre compte
403L’URL de vidéo résolue a été rejetée par les règles de protection des accès sortants
500La ligne de tâche ou son canal n’a pas pu être lu, ou l’URL de la vidéo n’a pas pu être analysée
502Le fournisseur est injoignable, a renvoyé un statut non 200, ou l’URL de la vidéo était vide
StatutCodeSignification
400task_not_existLe task_id est inconnu ou appartient à un autre compte
500get_task_failedRouteAPI n’a pas pu lire sa propre ligne de tâche
500marshal_response_failed, copy_response_body_failedRouteAPI n’a pas pu sérialiser ou écrire la réponse

Les requêtes rejetées avant le routage utilisent le corps d’erreur standard du middleware {"error": {"message": ..., "type": "error", "code": ...}}, et non la forme de tâche.

  • Créer une tâche vidéo — soumettre une tâche et l’enveloppe de requête commune.
  • Format vidéo OpenAI — le dialecte /v1/videos de la même tâche, avec remix.
  • Assets — un 404 de l’API assets signifie que le compte n’a pas encore d’espace d’assets.
  • Erreurs courantes — codes de statut communs à tous les points de terminaison de modèles.