Tutoriel
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. Surgpt-image-2/image-to-image, la data URI est acceptée à la soumission, puis la tâche se termine enstatus: fail, avec le code d'erreurTASK_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 avecINVALID_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 deimage_urlsurgpt-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, maisdata.status: "fail"à l'interrogation : regardezdata.error.code—INVALID_REQUESTavec 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_FAILEDavec 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
- 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.
- 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 obtenir200avec un content-typeimage/*. Si elle exige un cookie, un header ou un VPN, le serveur ne pourra pas la récupérer. - 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), pasgpt-image-2. - Utilisez le nom de champ indiqué dans la doc du modèle (
input_urls/image_urls/image_input), à placer dansinput. - Ne transmettez jamais de base64. Si vous n'avez que des octets, téléversez-les d'abord, puis transmettez l'URL obtenue.
- Soumettez d'abord, interrogez ensuite. Faites
GET /v1/tasks/<taskId>jusqu'à ce quedata.statusvaillesuccessoufail. En cas d'échec, lisezdata.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
- HiAPI 400 Bad Request : comment corriger une erreur de paramètre — explication détaillée du rejet par un 400 à la soumission, avant que la tâche ne démarre, en cas de nom de champ ou de model id incorrect.
- Les requêtes échouées sur HiAPI sont-elles facturées ? — règles de facturation lorsqu'une tâche échoue après avoir été acceptée.
- Vérifier les champs : page du modèle gpt-image-2 et page du modèle Nano Banana Pro.
- Tarification de l'API, et récupérez votre clé API dans la console.
- Documentation de l'API : créer une tâche, consulter le détail d'une tâche, authentification.
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 →-
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