Tutoriel
hiapi /v1/tasks : tâche bloquée ou expirée : diagnostic et stratégie de réessai
Vous avez soumis une tâche via POST https://api.hiapi.ai/v1/tasks, obtenu un taskId, mais lorsque vous interrogez GET /v1/tasks/{taskId}, data.status reste bloqué sur queued ou handling depuis plusieurs minutes — elle semble « bloquée » ; ou bien votre boucle de polling a atteint la limite que vous avez fixée sans jamais obtenir d'état terminal, et vous avez signalé un timeout. Ne vous précipitez pas sur un renvoi : les tâches hiapi sont asynchrones, « pas encore terminée » et « déjà en échec » sont deux choses différentes ; diagnostiquez d'abord pour éviter d'aggraver la situation.
Si vous voyez
data.statusdéjà àfail,error.codeàTASK_TIMEOUT, ou un HTTP 504 littéral levé par le navigateur/proxy — c'est un autre type de problème (la tâche a réellement échoué, ou le timeout se situe au niveau réseau entre vous et hiapi) ; consultez Dépannage des timeouts et erreurs 504 des tâches HiAPI. Cet article ne traite que des scénarios de « blocage » où la tâche tarde à atteindre un état terminal.
Symptômes du problème
Une tâche « bloquée » renvoie à peu près ceci lors de la requête (HTTP 200, mais la tâche est toujours dans un état non terminal) :
{
"data": {
"taskId": "…",
"status": "queued",
"output": null,
"error": null
}
}
Caractéristique clé : data.status vaut queued (en file d'attente) / handling (en traitement) / archiving (en archivage), data.error est null, et data.output est encore vide. Cela signifie que la tâche est saine, simplement pas encore terminée.
hiapi ne compte que deux états terminaux pour une tâche : data.status à success ou fail. Tant qu'il n'est pas l'un de ces deux, la tâche n'est pas terminée — les « blocages » se produisent presque toujours dans cette phase non terminale.
Deux « faux blocages » faciles à confondre :
La requête renvoie directement
404:{"code": 404, "data": null, "message": "task not found"}Ce n'est pas un blocage : soit le
taskIdest erroné, soit la tâche n'a jamais été créée, soit l'enregistrement de la tâche a expiré — vérifiez ledata.taskIdobtenu lors de la soumission.Rejet synchrone dès la soumission (aucun
taskIdobtenu), par exemple un model incorrect :{"code": 400, "data": null, "error_code": "MODEL_UNAVAILABLE", "message": "model not available via /v1/tasks"}Ce type de cas relève d'un problème de requête lui-même, pas d'une tâche bloquée ; corrigez et soumettez à nouveau.
Causes fréquentes (par ordre de probabilité)
1. Encombrement de la file d'attente (la plus fréquente)
Lorsqu'un modèle (modèle d'image, de vidéo, ou tout modèle à forte charge de calcul) est massivement sollicité, votre tâche patiente dans la file d'attente de ce modèle jusqu'à être prise par un worker.
- Signal :
data.statusestqueued,data.errorestnull, et peu de temps s'est écoulé depuis la soumission. - Correctif : ralentissez le rythme de polling, une requête toutes les 5–10 secondes suffit, n'enchaînez pas à 100 ms. La plupart des tâches sont prises en une à deux minutes.
2. Les modèles lourds sont intrinsèquement longs
La tâche a déjà été prise (handling/archiving), mais ce modèle est naturellement lent à s'exécuter — les vidéos longues, les hautes résolutions et les images de référence multiples allongent significativement la durée.
- Signal :
data.statusesthandlingouarchivingdepuis plusieurs minutes, sans erreur. - Correctif : accordez une limite de polling plus large aux tâches lourdes (prévoyez une marge selon les capacités du modèle). Longue durée ≠ échec, ne coupez pas juste avant le résultat.
3. Un polling mal configuré (la cause la plus souvent confondue avec un « blocage »)
Beaucoup de « blocages » sont en réalité des problèmes côté client : un intervalle de polling trop court qui vous fait tourner en rond, l'absence de limite, ou une limite trop courte qui abandonne trop tôt.
- Signal : le
data.statuscôté serveur progresse normalement, mais votre boucle a levé un timeout prématurément, ou vous ne lisez pas du toutdata.status. - Correctif : utilisez un intervalle fixe (5 secondes recommandées) + une limite raisonnable (environ 10 minutes pour une tâche standard, plus pour les tâches lourdes). Le timeout doit être déterminé par votre boucle, et non par un état
timeoutcôté serveur — hiapi ne possède pas cet état.
4. Le point de terminaison de callback est injoignable
Si vous avez fourni un callback lors de la soumission, la tâche elle-même peut déjà être success, mais le résultat n'atteint pas votre endpoint, d'où une impression de « silence ».
- Signal : une requête active montre
data.statusdéjà àsuccess,data.outputcontient des données, mais votre endpoint de callback n'a rien reçu. - Correctif : l'adresse de callback doit être accessible publiquement, recevoir des
POST, et renvoyer un2xxen environ 10 secondes ; sinon, passez au polling. Détails dans Pourquoi le callback des tâches hiapi ne se déclenche pas.
Étapes de correction
- Consultez d'abord l'état, ne renvoyez pas au feeling :
GET /v1/tasks/{taskId}, lisezdata.statusetdata.error. - Aiguillez selon l'état :
queued/handling/archiving→ toujours en cours, attendez 5–10 secondes avant de revérifier (causes 1 / 2).success→ tâche réussie, récupérez le résultat dansdata.output; si vous attendiez un callback qui n'arrive pas → cause 4.fail→ lisezdata.error.codeetdata.error.message; si c'estTASK_TIMEOUT→ voir le guide sur les timeouts et les 504.404 task not found→ letaskIdest erroné ou la tâche n'a pas été créée ; vérifiez ledata.taskIddans la réponse de soumission.
- L'output a une durée de validité : l'URL de téléchargement dans
data.outputporte unexpireAt(environ 7 jours) ; une fois obtenue, enregistrez-la / transférez-la rapidement, ne conservez pas de lien à chaud à long terme. - Vérifiez qu'il ne s'agit pas d'un problème d'authentification / de requête : exécutez d'abord l'exemple de vérification minimal ci-dessous, pour écarter un problème de key ou de model id.
- Si vous devez vraiment réessayer, usez du backoff : voir la section suivante sur la stratégie de réessai, ne renvoyez pas le même body en boucle serrée.
Exemple de vérification minimal
Utilisez une requête minimale pour confirmer que la key et l'interface de tâches fonctionnent. Utilisez l'id brut du model (ex. : gpt-image-2) :
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"input": { "prompt": "a single red apple on a white background, studio lighting" }
}'
Une soumission réussie renvoie une réponse du type {"data":{"taskId":"…","status":"queued"}}. Interrogez avec le taskId :
curl -s "https://api.hiapi.ai/v1/tasks/<taskId>" \
-H "Authorization: Bearer $HIAPI_API_KEY"
- Si la réponse est
401avec un body{"error":{"code":"permission_denied","type":"hiapi_error","request_id":"…"}}— le problème vient de la key, pas de la tâche. Consultez d'abord Dépannage de l'erreur API Key invalide. - Si la soumission est rejetée par
400+"error_code":"MODEL_UNAVAILABLE"— c'est un problème de model id. Passez l'id brut et reportez-vous à Erreur hiapi « modèle indisponible ».
Stratégie de réessai sans aggravation
- Backoff exponentiel : 5s → 15s → 45s recommandés.
- Plafond de 3 tentatives : après un troisième échec, escaladez (changer de modèle, réduire la configuration, ou ouvrir un ticket), ne bouclez pas indéfiniment.
- Chaque réessai est une nouvelle tâche : un
POST /v1/taskscorrespond à un nouveautaskIdet peut générer une nouvelle facturation. hiapi ne promet pas de « re-soumission idempotente » — ne comptez pas sur le renvoi du même body pour réutiliser l'ancienne tâche. - En cas de 429, ralentissez le débit de soumission, pas le débit de polling : voir Comment corriger l'erreur de limitation de débit (429) hiapi.
Un exemple Python fiable de polling + backoff :
import time, os, requests
BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}"}
def submit_and_wait(body, poll_interval=5, max_wait=600):
r = requests.post(BASE, json=body, headers=HEADERS, timeout=30)
r.raise_for_status()
task_id = r.json()["data"]["taskId"]
deadline = time.time() + max_wait
while time.time() < deadline:
time.sleep(poll_interval)
data = requests.get(f"{BASE}/{task_id}", headers=HEADERS, timeout=30).json()
status = (data.get("data") or {}).get("status")
if status == "success":
return data["data"]["output"]
if status == "fail":
raise RuntimeError(data["data"].get("error"))
# queued / handling / archiving → continuer d'attendre
raise TimeoutError(f"task {task_id} 在 {max_wait}s 内未到终态")
Notez que la détermination de l'état terminal ne reconnaît que success et fail ; tous les autres états (queued / handling / archiving) imposent de continuer d'attendre, et le timeout est déterminé par votre max_wait.
Quand escalader
- Réessai avec backoff 3 fois, chaque fois le même
data.error.code→ pas une secousse transitoire, changez l'entrée ou de modèle. - La tâche reste longtemps en
queuedsans aucune progression → consultez la console hiapi pour voir s'il y a des notifications de plateforme, et ouvrez un ticket avec lerequest_id. data.statusest déjàsuccessmais le callback n'arrive jamais → ne reposez plus sur le callback pour cet endpoint, passez au polling.
Liens internes associés
- Dépannage des timeouts et erreurs 504 des tâches HiAPI — à lire si la tâche échoue réellement en
TASK_TIMEOUT, ou si vous voyez un 504 littéral. - Pourquoi le callback des tâches hiapi ne se déclenche pas — article dédié aux « faux blocages » dus à un callback absent.
- Dépannage de l'erreur API Key invalide|Erreur modèle indisponible|Erreur de limitation 429
FAQ
Q : À partir de quand parle-t-on de « timeout » ? Existe-t-il une durée de timeout uniforme ?
R : Il n'y a pas de chiffre uniforme, cela dépend du modèle ; les tâches lourdes (vidéo longue, haute résolution) prennent plus de temps. De plus, hiapi n'a pas d'état timeout côté serveur — le timeout est généralement l'atteinte de la limite que votre boucle de polling s'est fixée. Une tâche réellement expirée côté serveur aura data.status:"fail" + error.code:"TASK_TIMEOUT" ; dans ce cas, voir le guide sur les timeouts et les 504.
Q : La tâche est queued depuis 30 secondes, faut-il annuler et réessayer ?
R : Non. 30 secondes est dans la norme pour tout modèle non trivial ; attendez au moins deux minutes avant d'envisager un réessai.
Q : Peut-on annuler une tâche en cours d'exécution ? R : L'annulation n'est généralement pas prise en charge ; même si elle l'était, la file d'attente / le slot de calcul est souvent déjà occupé. Laisser la tâche se terminer et récupérer le résultat est plus avantageux.
Q : La même requête fonctionnait hier, mais est bloquée aujourd'hui ? R : Dans la grande majorité des cas, il s'agit d'un encombrement de la file d'attente du modèle (cause 1). Changez pour un modèle aux capacités similaires, ou attendez 5–10 minutes que la file se résorbe avant de réessayer.
Q : Toutes les tâches expirent, est-ce un problème de mon compte ? R : Consultez d'abord la console hiapi pour vérifier s'il y a des notifications au niveau du compte, puis confirmez si vous êtes soumis à une limitation de débit (voir le guide 429). Si tout est normal et qu'un seul modèle échoue, il s'agit probablement de la file d'attente ou du backend de ce modèle, pas de votre compte.
Q : Réessayer une tâche bloquée / expirée entraîne-t-il une double facturation ?
R : Chaque POST /v1/tasks est une nouvelle tâche facturable. Une tâche en échec sans résultat n'est généralement pas facturée en production, mais la file d'attente / le slot de calcul peut déjà être occupé. Si le coût vous importe, vérifiez a posteriori sur la page d'utilisation.
Articles similaires
Voir tous les articles →-
Tutoriel
Comment appeler hailuo-2.3-fast/image-to-video via l'API HiAPI : curl et Python en pratique
La première requête exploitable du palier image-vers-vidéo rapide et économique — de l'ID du modèle au téléchargement du MP4
-
Tutoriel
Comment appeler hailuo-2.3/text-to-video via l'API HiAPI : curl, Python et exemples de requêtes exécutables
-
Tutoriel
Utiliser Kandinsky 6.0 Pro texte-vers-vidéo sur HiAPI : tutoriel curl et Python
Démonstration pratique axée sur la requête : construire l'appel du prompt au clip vidéo, soumettre la requête, interroger l'état d'achèvement et télécharger le résultat