HiAPI
Blog

Tutoriel

Erreur d'entrée d'image sur HiAPI : transmettez une URL accessible publiquement, pas du Base64

Oct 22, 2026
Erreur d'entrée d'image sur HiAPI : transmettez une URL accessible publiquement, pas du Base64

Sur HiAPI, les modèles image-to-image (image vers image) et à image de référence récupèrent votre image source depuis une URL HTTP(S) accessible publiquement — ils n'acceptent pas de chaîne d'octets base64 et ne peuvent pas atteindre d'adresse privée. Le piège le plus fréquent : une entrée d'image incorrecte semble avoir réussi — POST /v1/tasks renvoie 200 avec un taskId, et l'échec réel n'apparaît qu'au moment où vous interrogez la tâche. Voici les deux échecs que vous verrez réellement :

{ "code": 200, "message": "success",
  "data": { "status": "fail", "model": "gpt-image-2/image-to-image", "storage": "temp", "taskId": "tk-...",
    "error": { "code": "INVALID_REQUEST",
      "message": "The image URL could not be downloaded. Please provide a reachable public HTTP(S) URL and try again." } } }
{ "code": 200, "message": "success",
  "data": { "status": "fail", "model": "gpt-image-2/image-to-image", "storage": "temp", "taskId": "tk-...",
    "error": { "code": "TASK_FAILED", "message": "task failed" } } }

Le premier cas correspond à une URL inaccessible ; le second est le résultat générique obtenu quand on transmet une data URI base64 comme image — aucun indice, juste un task failed, et c'est là que la plupart des gens restent bloqués. Notez que le "message": "success" externe indique seulement que la requête d'interrogation elle-même a réussi ; le vrai résultat se trouve dans data.status.

Causes courantes (par probabilité décroissante)

  • Vous avez collé du base64 dans le champ image — une chaîne data:image/...;base64,.... Ce champ attend une URL que le serveur peut récupérer, pas des octets en ligne. Sur gpt-image-2/image-to-image, la data URI est acceptée à la soumission, puis la tâche se termine en status: fail, avec le code d'erreur TASK_FAILED / task failed.

  • L'URL n'est pas accessible publiquement. http://localhost, 127.0.0.1, les IP internes, les fichiers nécessitant une connexion et les liens pré-signés expirés échouent tous avec INVALID_REQUEST — « The image URL could not be downloaded… ».

  • Mauvais nom de champ (variable selon les modèles, voir le tableau ci-dessous). Le champ d'entrée d'image n'est pas uniforme entre familles de modèles. Un nom incorrect est rejeté dès la soumission par un HTTP 400, par exemple l'utilisation erronée de image_url sur gpt-image-2/image-to-image :

    { "code": 400, "data": null, "error_code": "INVALID_REQUEST",
      "message": "invalid input: input_urls: missing required field \"input_urls\"; <root>: additional properties 'image_url' not allowed" }
    
  • Vous avez utilisé un model id nu pour faire de l'édition. Un id nu (par exemple gpt-image-2) est du texte-vers-image pur, sans aucun champ image défini, donc le champ image est rejeté : 400 invalid input: <root>: additional properties 'input_urls' not allowed. Pour l'édition, utilisez l'id de route image-to-image : gpt-image-2/image-to-image.

Comment lire les codes d'erreur : « problème d'entrée » ou « problème amont »

Distinguez deux phases dans la réponse : la soumission (réponse directe de POST /v1/tasks) et l'état final (le data.status obtenu via GET /v1/tasks/<taskId>) :

  • HTTP 400 à la soumission, enveloppe plate {"code":400,"data":null,"error_code":"INVALID_REQUEST","message":"invalid input: ..."} → votre requête a un problème de structure/champ (problème d'entrée). Aucune tâche n'est créée, aucun frais. Corrigez le nom du champ ou le model id.
  • HTTP 401 à la soumission, enveloppe imbriquée {"error":{"code":"permission_denied","type":"hiapi_error","request_id":"..."}} → c'est un problème d'authentification (clé incorrecte ou sans droits), pas un problème d'entrée.
  • HTTP 200 + taskId à la soumission, mais data.status: "fail" à l'interrogation : regardez data.error.code —
    • INVALID_REQUEST avec un message « could not be downloaded » → l'URL de l'image est inaccessible (toujours votre problème d'entrée : remplacez l'image par une URL accessible publiquement).
    • TASK_FAILED avec un message « task failed » → échec générique, sans indication. Écartez d'abord le base64 / une entrée incorrecte ; si l'échec persiste, traitez-le comme un problème de « génération amont ».

En résumé : un 4xx à la soumission relève de la requête / de l'authentification ; seul un fail en état final peut impliquer le téléchargement ou la génération amont ; et dans tous les cas, ne vous laissez pas tromper par le "message":"success" externe, seul data.status fait foi.

Le nom du champ d'entrée d'image varie selon le modèle

Le tableau ci-dessous est vérifié par tests sur le schéma d'entrée actuel de chaque modèle (vérifiez toujours sur la page du modèle, les champs varient selon la famille) :

Model id (route image-to-image) Champ d'entrée d'image Type
gpt-image-2/image-to-image input_urls tableau de chaînes
seedream-5.0-pro/image-to-image image_urls tableau de chaînes
nano-banana-pro image_input tableau de chaînes

Le champ doit être placé dans l'objet input ; la plupart des modèles à image de référence exigent un tableau (même pour une seule image).

Étapes de correction

  1. Hébergez l'image sur une URL HTTP(S) accessible publiquement. Téléversez-la vers n'importe quel stockage objet / CDN (Cloudflare R2, S3, GCS, etc.) et rendez l'objet public en lecture, ou utilisez une URL pré-signée encore valide.
  2. Vérifiez qu'elle est accessible sans authentification. Dans une session vierge (ou depuis une machine autre que la vôtre), exécutez curl -sI "<votreURL>" : vous devez obtenir 200 avec un content-type image/*. Si elle exige un cookie, un header ou un VPN, le serveur ne pourra pas la récupérer.
  3. Utilisez le model id image-to-image, pas l'id nu. Pour l'édition, appelez gpt-image-2/image-to-image (ou la route i2i correspondant à votre modèle), pas gpt-image-2.
  4. Utilisez le nom de champ indiqué dans la doc du modèle (input_urls / image_urls / image_input), à placer dans input.
  5. Ne transmettez jamais de base64. Si vous n'avez que des octets, téléversez-les d'abord, puis transmettez l'URL obtenue.
  6. Soumettez d'abord, interrogez ensuite. Faites GET /v1/tasks/<taskId> jusqu'à ce que data.status vaille success ou fail. En cas d'échec, lisez data.error.message — « could not be downloaded » signale un problème d'URL, pas de prompt.

Exemple de vérification minimal

Commencez par un contrôle de connectivité sans frais : lister les modèles ne crée aucune tâche et ne coûte rien.

curl -s https://api.hiapi.ai/v1/models \
  -H "Authorization: Bearer $HIAPI_API_KEY"

Un retour 200 avec un tableau data indique que votre clé fonctionne. Une mauvaise clé renvoie 401 + {"error":{"code":"permission_denied", ... ,"type":"hiapi_error"}} — c'est un problème d'authentification, pas d'entrée. Envoyez ensuite une requête image-to-image correcte : un champ modèle avec une URL accessible publiquement.

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/image-to-image",
    "input": {
      "prompt": "remplace le fond par un blanc de studio propre",
      "input_urls": ["https://your-public-host.example.com/source.png"]
    }
  }'

Remplacez input_urls par l'URL de votre propre image accessible. Une soumission réussie renvoie data.taskId ; interrogez ensuite GET https://api.hiapi.ai/v1/tasks/<taskId> jusqu'à ce que data.status vaille success, puis récupérez le résultat dans data.output[0].url (cette URL a une durée de validité ; téléchargez-la ou copiez-la rapidement, ne stockez pas de lien direct).

Liens associés

Questions fréquentes

Peut-on transmettre du base64 aux modèles image-to-image de HiAPI ? Non. Le champ image attend une URL HTTP(S) publique que le serveur peut télécharger. Une chaîne data:image/...;base64,... est acceptée à la soumission sur certains modèles, mais la tâche se termine ensuite en status: fail, avec le code d'erreur TASK_FAILED / task failed. Téléversez les octets vers un emplacement public et transmettez l'URL.

Mon POST /v1/tasks a renvoyé 200, mais la tâche a échoué, pourquoi ? Le 200 de soumission indique seulement que la requête a été acceptée. Le téléchargement de l'image et la génération ont lieu ensuite. Interrogez GET /v1/tasks/<taskId> ; une entrée d'image incorrecte s'y révèle par data.status: fail, avec error.code valant INVALID_REQUEST (« The image URL could not be downloaded… ») ou TASK_FAILED.

Dans quel champ faut-il mettre l'URL de l'image ? Cela dépend du modèle. gpt-image-2/image-to-image utilise input_urls, seedream-5.0-pro/image-to-image utilise image_urls, nano-banana-pro utilise image_input (tous des tableaux). Vérifiez le schéma actuel sur la page du modèle avant d'envoyer la requête.

Une URL localhost ou privée fonctionne-t-elle ? Non. HiAPI récupère l'image depuis ses propres serveurs, donc localhost, 127.0.0.1, les adresses internes, les liens visibles seulement après connexion et les URL pré-signées expirées échouent tous avec « The image URL could not be downloaded. ». Utilisez une URL résoluble publiquement et sans authentification.

Que signifie l'erreur additional properties 'input_urls' not allowed ? Vous avez transmis le champ image à un modèle qui ne le définit pas — souvent parce que vous avez utilisé l'id texte-vers-image nu (gpt-image-2) au lieu de la route image-to-image (gpt-image-2/image-to-image), ou le nom de champ d'un autre modèle. C'est un 400 à la soumission ; voir le guide 400 Bad Request ci-dessus.

Les tâches d'image échouées sont-elles facturées ? Les requêtes rejetées par un 400 à la soumission ne sont pas facturées ; en revanche, une tâche acceptée (200 + taskId) qui échoue ensuite peut être facturée — voir « Les requêtes échouées sont-elles facturées ? » ci-dessus. Corrigez donc l'URL avant de relancer.

Articles similaires

Voir tous les articles →

Commencez avec des artefacts IA persistants

Obtenez votre clé API et appelez des modèles d'image, de vidéo et d'audio via une API unique basée sur les tasks.

Lire la documentation de l'API