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.
Obtenir l’enregistrement de tâche
Section intitulée « Obtenir l’enregistrement de tâche »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.
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" } }}Champs de l’enregistrement de tâche
Section intitulée « Champs de l’enregistrement de tâche »| Champ | Description |
|---|---|
code | "success" pour une tâche lisible ; en cas d’échec, la forme d’erreur de tâche décrite plus bas |
data.id | ID de ligne interne ; utilisé dans aucune requête |
data.task_id | ID de tâche RouteAPI — la valeur à utiliser pour interroger et télécharger |
data.status | NOT_START, SUBMITTED, QUEUED, IN_PROGRESS, SUCCESS ou FAILURE |
data.progress | Chaîne de progression comme "30%" ou "100%" |
data.result_url | URL 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_reason | Raison de l’échec ; vide sinon |
data.submit_time / start_time / finish_time | Secondes Unix. start_time et finish_time valent 0 avant le démarrage et la fin |
data.created_at / updated_at | Secondes Unix, date de création et date de dernière mise à jour de la ligne |
data.quota | Quota facturé pour la tâche |
data.platform | Type numérique du canal amont qui a exécuté la tâche |
data.group / data.channel_id / data.user_id | Groupe de facturation, canal et compte propriétaire. Utile pour un échange avec le support |
data.action | Type de tâche : generate, textGenerate, firstTailGenerate, referenceGenerate ou remixGenerate |
data.properties | Proprié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.data | Dernière charge utile de tâche du fournisseur amont, stockée pour le débogage. Sa forme dépend du fournisseur |
| Statut | Signification | Action |
|---|---|---|
NOT_START | La ligne existe mais l’amont n’a pas encore été interrogé | Continuer à interroger |
SUBMITTED / QUEUED | Acceptée, en attente dans la file du fournisseur | Continuer à interroger |
IN_PROGRESS | En cours de génération | Continuer à interroger |
SUCCESS | Succès terminal | Télécharger la vidéo |
FAILURE | Échec terminal | Lire 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.
Exemple d’interrogation
Section intitulée « Exemple d’interrogation »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)Exemple shell complet
Section intitulée « Exemple shell complet »#!/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 1L’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.
Télécharger la vidéo
Section intitulée « Télécharger la vidéo »GET /v1/videos/{task_id}/contentDiffuse 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).
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": "..."}} :
| Statut | Signification |
|---|---|
| 400 | La tâche n’est pas encore terminée ; le message contient le statut actuel |
| 404 | Tâche inconnue, ou tâche appartenant à un autre compte |
| 403 | L’URL de vidéo résolue a été rejetée par les règles de protection des accès sortants |
| 500 | La 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 |
| 502 | Le fournisseur est injoignable, a renvoyé un statut non 200, ou l’URL de la vidéo était vide |
| Statut | Code | Signification |
|---|---|---|
| 400 | task_not_exist | Le task_id est inconnu ou appartient à un autre compte |
| 500 | get_task_failed | RouteAPI n’a pas pu lire sa propre ligne de tâche |
| 500 | marshal_response_failed, copy_response_body_failed | RouteAPI 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.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- 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/videosde la même tâche, avecremix. - Assets — un
404de 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.