Tutoriale
Errore di input immagine su HiAPI: passa un URL accessibile pubblicamente, non Base64
I modelli image-to-image e con immagine di riferimento su HiAPI recuperano l'immagine sorgente da un URL HTTP(S) accessibile pubblicamente: non accettano stringhe di byte base64 e non riescono a raggiungere indirizzi privati. La trappola più comune è questa: un input immagine errato sembra andato a buon fine — POST /v1/tasks restituisce 200 con un taskId, e il vero fallimento emerge solo quando interroghi il task. I due tipi di fallimento che vedrai realmente sono questi:
{ "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" } } }
Il primo è il ritorno per un URL irraggiungibile; il secondo è il risultato generico che ottieni quando passi un base64 data URI come immagine — nessun indizio, solo un task failed, ed è questo il punto in cui la maggior parte delle persone si blocca. Nota che il "message": "success" esterno indica solo che la richiesta di polling stessa è riuscita; il risultato vero è in data.status.
Cause comuni (in ordine di probabilità decrescente)
Hai incollato base64 nel campo immagine — una stringa
data:image/...;base64,.... Questo campo vuole un URL che il server possa scaricare, non byte inline. Sugpt-image-2/image-to-image, il data URI viene accettato in fase di invio, poi il task termina constatus: fail, codice erroreTASK_FAILED/task failed.L'URL non è raggiungibile pubblicamente.
http://localhost,127.0.0.1, IP di rete interna, file che richiedono login per essere visti, link pre-firmati scaduti: tutti falliscono conINVALID_REQUEST— "The image URL could not be downloaded…".Nome del campo sbagliato (varia da modello a modello, vedi tabella sotto). Il campo di input immagine non è uniforme tra le famiglie di modelli. Un nome errato viene bloccato in fase di invio con HTTP
400, per esempio usando per erroreimage_urlsugpt-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" }Hai usato il model id nudo per fare editing. Un id nudo (ad esempio
gpt-image-2) è puro text-to-image, non definisce affatto il campo immagine, quindi il campo immagine viene rifiutato:400 invalid input: <root>: additional properties 'input_urls' not allowed. Per fare editing usa l'id della route image-to-image:gpt-image-2/image-to-image.
Come leggere i codici di errore: capire se è un «problema di input» o un «problema upstream»
Dividi il ritorno in due fasi: fase di invio (la risposta diretta di POST /v1/tasks) e stato finale (data.status ottenuto interrogando GET /v1/tasks/<taskId>):
- HTTP 400 in fase di invio, envelope piatto
{"code":400,"data":null,"error_code":"INVALID_REQUEST","message":"invalid input: ..."}→ c'è un problema nella struttura/campi della tua richiesta (problema di input). Il task non viene creato, nessun addebito. Basta correggere il nome del campo o il model id. - HTTP 401 in fase di invio, envelope annidato
{"error":{"code":"permission_denied","type":"hiapi_error","request_id":"..."}}→ è un problema di autenticazione (key errata o senza permessi), non di input. - HTTP 200 in fase di invio +
taskId, ma al pollingdata.status: "fail": guardadata.error.code—INVALID_REQUESTcon message "could not be downloaded" → l'URL dell'immagine non è scaricabile (è comunque un tuo problema di input: sostituisci l'immagine con un URL raggiungibile pubblicamente).TASK_FAILEDcon message "task failed" → fallimento generico, senza indizi. Escludi prima base64 / input errati; se dopo averli esclusi fallisce ancora, trattalo come problema di «generazione upstream».
In sintesi: i 4xx in fase di invio sono problemi a livello di richiesta / autenticazione, solo il fail in stato finale può coinvolgere il download o la generazione upstream; e in ogni caso, non farti ingannare dal "message":"success" esterno: fa sempre fede data.status.
Il nome del campo di input immagine varia da modello a modello
La tabella seguente è verificata empiricamente sugli input schema attuali dei rispettivi modelli (controlla comunque sempre la pagina del modello, i campi variano da famiglia a famiglia):
| Model id (route image-to-image) | Campo di input immagine | Tipo |
|---|---|---|
gpt-image-2/image-to-image |
input_urls |
array di stringhe |
seedream-5.0-pro/image-to-image |
image_urls |
array di stringhe |
nano-banana-pro |
image_input |
array di stringhe |
Il campo va messo dentro l'oggetto input; la maggior parte dei modelli con immagine di riferimento richiede un array (anche se c'è una sola immagine).
Passi per la correzione
- Ospita l'immagine su un URL HTTP(S) accessibile pubblicamente. Caricala su qualsiasi object storage / CDN (Cloudflare R2, S3, GCS, ecc.) e imposta l'oggetto in lettura pubblica, oppure usa un URL pre-firmato ancora valido.
- Verifica che sia accessibile senza autenticazione. In una sessione pulita (o da una macchina diversa dalla tua) esegui
curl -sI "<il-tuo-URL>": deve rispondere200con content-typeimage/*. Se richiede cookie, header o VPN, il server non riesce a scaricarla. - Usa il model id image-to-image, non l'id nudo. Per fare editing chiama
gpt-image-2/image-to-image(o la route i2i corrispondente al tuo modello), nongpt-image-2. - Usa il nome del campo indicato nella documentazione di quel modello (
input_urls/image_urls/image_input), dentroinput. - Non passare mai base64. Se hai solo i byte, prima caricali, poi passa l'URL ottenuto.
- Prima invia, poi interroga.
GET /v1/tasks/<taskId>finchédata.statusnon èsuccessofail. In caso di fallimento leggidata.error.message: se compare "could not be downloaded" è un problema di URL, non del tuo prompt.
Esempio minimo di verifica
Fai prima un controllo di connettività a costo zero: elencare i modelli non crea alcun task e non costa nulla.
curl -s https://api.hiapi.ai/v1/models \
-H "Authorization: Bearer $HIAPI_API_KEY"
Se restituisce 200 con un array data, la tua key funziona. Una key errata restituisce 401 + {"error":{"code":"permission_denied", ... ,"type":"hiapi_error"}} — quello è un problema di autenticazione, non di input. Poi invia una richiesta image-to-image corretta: nel campo del modello metti un URL raggiungibile pubblicamente.
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": "把背景换成干净的影棚白",
"input_urls": ["https://your-public-host.example.com/source.png"]
}
}'
Sostituisci input_urls con l'URL della tua immagine raggiungibile. Un invio riuscito restituisce data.taskId; poi interroga GET https://api.hiapi.ai/v1/tasks/<taskId> finché data.status non è success, e prendi il risultato da data.output[0].url (quell'URL ha una scadenza: scaricalo o copialo altrove appena possibile, non salvarlo come hotlink).
Link correlati
- HiAPI 400 Bad Request: come correggere gli errori nei parametri — spiegazione dettagliata di nomi di campo o model id errati, bloccati dal 400 in fase di invio prima che il task parta.
- Le richieste fallite su HiAPI vengono addebitate? — le regole di fatturazione quando un task fallisce dopo essere stato accettato.
- Verifica dei campi: pagina del modello gpt-image-2 e pagina del modello Nano Banana Pro.
- Prezzi API, e vai alla console per ottenere la API Key.
- Documentazione API: creare un task, consultare i dettagli del task, autenticazione.
Domande frequenti
Posso passare base64 ai modelli image-to-image di HiAPI?
No. Il campo immagine vuole un URL HTTP(S) pubblico che il server possa scaricare. Una stringa data:image/...;base64,... viene accettata in fase di invio da alcuni modelli, ma il task poi termina con status: fail, codice errore TASK_FAILED / task failed. Carica i byte in una posizione pubblica e passa l'URL.
Il mio POST /v1/tasks ha restituito 200, ma il task è fallito: perché?
Il 200 in fase di invio indica solo che la richiesta è stata accettata. Il download dell'immagine e la generazione avvengono dopo. Interroga GET /v1/tasks/<taskId>: un input immagine errato si manifesta lì con data.status: fail, con error.code pari a INVALID_REQUEST ("The image URL could not be downloaded…") oppure TASK_FAILED.
In quale campo va messo esattamente l'URL dell'immagine?
Dipende dal modello. gpt-image-2/image-to-image usa input_urls, seedream-5.0-pro/image-to-image usa image_urls, nano-banana-pro usa image_input (tutti array). Prima di inviare la richiesta, verifica lo schema attuale sulla pagina del modello.
Un URL localhost o privato va bene?
No. HiAPI scarica le immagini dai propri server, quindi localhost, 127.0.0.1, indirizzi di rete interna, link visibili solo dopo il login e URL pre-firmati scaduti falliscono tutti con "The image URL could not be downloaded.". Usa un URL risolvibile pubblicamente e senza autenticazione.
Cosa significa additional properties 'input_urls' not allowed?
Hai passato il campo immagine a un modello che non lo definisce — di solito perché hai usato l'id nudo text-to-image (gpt-image-2) invece della route image-to-image (gpt-image-2/image-to-image), oppure il nome del campo di un altro modello. È un 400 in fase di invio, vedi la guida 400 Bad Request sopra.
I task immagine falliti vengono addebitati?
Le richieste respinte con 400 in fase di invio non vengono addebitate; ma un task accettato (200 + taskId) che fallisce in seguito può essere addebitato — vedi «Le richieste fallite vengono addebitate?» sopra. Quindi, prima di riprovare, correggi l'URL.
Articoli correlati
Vedi tutti gli articoli →-
Tutoriale
Come chiamare hailuo-2.3-fast/image-to-video tramite l'API HiAPI: pratica con curl e Python
La prima richiesta funzionante per il livello image-to-video veloce ed economico — dall'ID del modello al download di un MP4
-
Tutoriale
Come chiamare hailuo-2.3/text-to-video tramite l'API HiAPI: curl, Python ed esempi di richiesta eseguibili
-
Tutoriale
Utilizzare Kandinsky 6.0 Pro su HiAPI per la generazione di video da testo: tutorial con curl e Python
Dimostrazione pratica guidata dalla richiesta: costruire la chiamata da prompt a clip video, inviare la richiesta, monitorare lo stato di completamento e scaricare il risultato