Tutoriel
URL de sortie des tâches HiAPI expirée (expireAt) : téléchargez et archivez le résultat avant son invalidation
output[].url en état final porte un expireAt, une fois expiré c'est 404 — comment le détecter, comment télécharger à temps, comment récupérer après expiration.
Vous générez une image ou une vidéo avec POST /v1/tasks, et une fois la tâche terminée vous récupérez depuis data.output[0].url un lien temp.hiapi.ai — il s'ouvre à ce moment-là, mais quelques jours plus tard il renvoie une page HTML « Not Found » :
HTTP/2 404
content-type: text/html
Ce ne sont pas les octets de l'image/la vidéo qui sont renvoyés, mais une page 404 de Cloudflare. La cause est unique : l'URL de sortie des tâches est un lien temporaire avec une durée de validité, dès que expireAt (timestamp Unix) de l'état final est atteint, l'objet sur temp.hiapi.ai est purgé et le lien ne fonctionne plus.
Comprendre les champs de l'état final
Lorsque le polling de l'état final d'une tâche (GET /v1/tasks/{taskId}) réussit, les champs clés ressemblent à ceci :
{
"code": 200,
"data": {
"taskId": "tk-hiapi-xxxxxxxx",
"status": "success",
"storage": "temp",
"created": 1791828181,
"completed": 1791828201,
"output": [
{
"artifactId": "...",
"type": "image",
"url": "https://temp.hiapi.ai/....png",
"expireAt": 1792432981
}
]
},
"message": "success"
}
data.status == "success"est le seul état final de succès (l'échec est"fail", la file d'attente/le traitement estqueued/handling/archiving).data.outputest un tableau, chaque élément porte son propreurlet son propreexpireAt.expireAtest un timestamp Unix entier (pas une chaîne ISO). Pour déterminer l'expiration, on se fie uniquement à lui :now >= expireAtsignifie expiré.- La valeur de
data.storageest"temp"— c'est en soi un indice : c'est du stockage temporaire, pas destiné à une référence à long terme.
Quelle est la durée de validité ? Sur un échantillon mesuré,
expireAt - completed = 604800secondes (soit exactement 7 jours). Mais ne codez pas « 7 jours » en dur — fiez-vous auexpireAtpropre à chaque sortie, les différents modèles/stratégies de stockage pouvant varier.
Causes courantes (classées par probabilité d'occurrence)
- Avoir stocké le lien temporaire en base de données pour une référence à long terme : lors de l'insertion, c'est l'URL temporaire
temp.hiapi.ai/...qui est enregistrée, et au-delà deexpireAttout part en 404. C'est le piège le plus fréquent. - Ne pas avoir téléchargé immédiatement après l'état final : récupérer les octets longtemps après la fin de la tâche (au-delà du TTL).
- Croire qu'un nouveau polling peut « rafraîchir » le lien : un nouveau GET sur le même
taskIdrenvoie la même url et le mêmeexpireAt— les métadonnées persistent, mais l'objet lui-même ne se régénère pas après expiration, un nouveau GET ne vous donnera pas de nouveau lien. - Confondre le 404 avec un échec de tâche : la tâche est en fait
successdepuis longtemps, seule l'asset de sortie a expiré, ce sont deux choses distinctes.
Étapes de correction
- Dès l'état final, téléchargez immédiatement les octets. Après avoir détecté
data.status == "success"par polling, envoyez aussitôt un GET sur chaqueoutput[].urlpour récupérer le binaire, sans file d'attente ni report. - Archivez vers votre propre stockage objet (R2 / S3 / disque local), et remplacez par votre propre URL persistante.
- Ne stockez en base de données que votre propre URL persistante, jamais le lien temporaire
temp.hiapi.ai. - Vérifiez l'expiration avant de télécharger : téléchargez seulement si
now < expireAt; si déjà expiré, passez directement à la logique de relance. - Si expiré, seule la relance de la tâche est possible. Il n'existe pas de « échange du taskId contre un nouveau lien » — un nouveau GET sur le même taskId renvoie toujours cette url invalide. Pour obtenir à nouveau un résultat téléchargeable, il faut soumettre une nouvelle fois la tâche (facturation à nouveau).
- Contrôlez le timing des téléchargements pour les tâches en lot : parmi un lot, la tâche terminée en premier a aussi le
expireAtle plus précoce. Téléchargez immédiatement par ordre d'achèvement, n'attendez pas que tout le lot soit terminé pour télécharger en une fois, sinon les premières terminées risquent d'être proches de l'expiration.
Exemple de vérification minimal
Confirmez que votre clé fonctionne, que l'API de tâches produit un résultat, et voyez de vos yeux expireAt. Utilisez l'id brut du modèle (z-image, sans suffixe du type /text-to-image, sinon 400) :
# 1. Soumettre la tâche
curl -s https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "z-image",
"input": { "prompt": "a red apple on a wooden table" }
}'
# → {"code":200,"data":{"taskId":"tk-hiapi-..."},"message":"success"}
# 2. Faire du polling de l'état final avec le taskId de l'étape précédente, lire url et expireAt
curl -s https://api.hiapi.ai/v1/tasks/tk-hiapi-xxxx \
-H "Authorization: Bearer $HIAPI_API_KEY"
# Une fois data.status passé à "success", data.output[0].url / .expireAt sont disponibles
Si l'authentification échoue, la réponse est HTTP 401 + {"error":{"code":"permission_denied","type":"hiapi_error","request_id":"..."}} — c'est un problème de clé, pas d'expiration. Si la tâche est introuvable, c'est {"code":404,"data":null,"message":"task not found"} — généralement un taskId mal recopié ou une clé d'un autre environnement.
Liens associés
- Comment soumettre et faire du polling des tâches : documentation de démarrage rapide HiAPI
- Consulter votre clé API, voir l'historique des tâches : console
- Quels modèles sont disponibles : catalogue de modèles
- Exemple de page d'un modèle (celui utilisé pour la vérification de cet article) : Z-Image text-to-image
FAQ
Q : Quel est exactement le format de expireAt ?
R : Un timestamp Unix entier (secondes), par exemple 1792432981, pas une chaîne ISO. Utilisez now >= expireAt pour déterminer l'expiration.
Q : Après expiration du lien, peut-on faire un nouveau GET de la tâche pour « prolonger » le lien ?
R : Non. Un nouveau GET sur le même taskId renvoie toujours cette url d'origine et ce expireAt d'origine, l'objet ayant été purgé. Pour obtenir à nouveau un résultat téléchargeable, il faut relancer la tâche (facturation à nouveau).
Q : Après expiration, l'accès renvoie-t-il 403 ou 404 ?
R : C'est HTTP 404, et le body est une page Cloudflare « Not Found » en text/html, ni des octets d'image, ni un AccessDenied XML. Si votre logique de téléchargement n'accepte que 200, pensez à traiter « tout ce qui n'est pas 200 » comme un échec.
Q : La durée de validité est-elle fixe à 7 jours ?
R : Sur l'échantillon mesuré c'est 7 jours (604800 secondes), mais fiez-vous au expireAt propre à chaque sortie, n'écrivez pas le nombre de jours en dur dans le code.
Q : Comment télécharger un lot de tâches de la manière la plus sûre ?
R : Par ordre d'achèvement, celui qui passe en success en premier voit ses octets téléchargés en premier. La sortie terminée en premier a aussi le expireAt le plus précoce ; tout regrouper à la fin risque de tomber sur des échéances proches.
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