Tutorial
Error de entrada de imágenes en HiAPI: envía una URL de acceso público, no Base64
Los modelos de imagen a imagen (image-to-image) y de imagen de referencia de HiAPI obtienen tu imagen de origen desde una URL HTTP(S) accesible públicamente: no aceptan cadenas de bytes en base64 ni pueden acceder a direcciones privadas. El error más fácil de cometer es que una entrada de imagen errónea parece haber funcionado: POST /v1/tasks devuelve 200 con un taskId, y el fallo real solo aparece cuando consultas el estado de la tarea. Los dos tipos de fallo que verás en la práctica son estos:
{ "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" } } }
El primero es la respuesta para una URL inaccesible; el segundo es el resultado genérico que se obtiene al pasar un data URI base64 como imagen: sin ninguna indicación, solo un task failed, que es justo donde más gente se queda atascada. Ojo: el "message": "success" del nivel externo solo indica que esta solicitud de consulta se realizó correctamente; el resultado real está en data.status.
Causas habituales (de mayor a menor probabilidad)
Pegaste base64 en el campo de imagen: una cadena
data:image/...;base64,.... Este campo requiere una URL que el servidor pueda descargar, no bytes en línea. Engpt-image-2/image-to-image, el data URI se acepta en la fase de envío, pero después la tarea termina constatus: faily el código de errorTASK_FAILED/task failed.La URL no es accesible públicamente.
http://localhost,127.0.0.1, direcciones IP de red interna, archivos que requieren iniciar sesión para verse y enlaces prefirmados caducados fallarán todos conINVALID_REQUEST: "The image URL could not be downloaded…".Nombre de campo incorrecto (varía según el modelo, consulta la tabla siguiente). Los campos de entrada de imágenes no son uniformes entre familias de modelos. Un nombre incorrecto se rechaza en la fase de envío con HTTP
400, por ejemplo usando por errorimage_urlengpt-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" }Usaste un model id básico para editar. Un id básico (por ejemplo
gpt-image-2) es solo texto a imagen y no define ningún campo de imagen, así que el campo de imagen se rechaza:400 invalid input: <root>: additional properties 'input_urls' not allowed. Para editar, usa el id de la ruta de imagen a imagen:gpt-image-2/image-to-image.
Cómo leer los códigos de error: distinguir si es «problema de entrada» o «problema del proveedor»
Divide la respuesta en dos fases: la fase de envío (la respuesta directa de POST /v1/tasks) y el estado final (el data.status que se obtiene al consultar GET /v1/tasks/<taskId>):
- HTTP 400 en la fase de envío, sobre plano
{"code":400,"data":null,"error_code":"INVALID_REQUEST","message":"invalid input: ..."}→ hay un problema con la estructura o los campos de tu solicitud (problema de entrada). La tarea no se ha creado y no se factura. Basta con corregir el nombre del campo o el model id. - HTTP 401 en la fase de envío, sobre anidado
{"error":{"code":"permission_denied","type":"hiapi_error","request_id":"..."}}→ es un problema de autenticación (clave incorrecta o sin permisos), no un problema de entrada. - HTTP 200 en la fase de envío +
taskId, perodata.status: "fail"al consultar el estado: revisadata.error.code:INVALID_REQUESTcon message "could not be downloaded" → no se puede descargar la URL de la imagen (sigue siendo un problema de tu entrada: cambia la imagen por una URL accesible públicamente).TASK_FAILEDcon message "task failed" → fallo genérico, sin indicaciones. Descarta primero base64 o entradas defectuosas; si tras descartarlos sigue fallando, trátalo como un problema de «generación del proveedor».
En resumen: los 4xx de la fase de envío son problemas de solicitud o autenticación, y solo el fail del estado final puede implicar descarga o generación del proveedor; en cualquier caso, no te fíes del "message":"success" externo: todo depende de data.status.
El nombre del campo de entrada de imágenes varía según el modelo
La siguiente tabla se ha verificado con pruebas contra el input schema actual de cada modelo (asegúrate siempre de comprobarlo en la página del modelo; los campos varían según la familia):
| model id (ruta de imagen a imagen) | Campo de entrada de imagen | Tipo |
|---|---|---|
gpt-image-2/image-to-image |
input_urls |
array de strings |
seedream-5.0-pro/image-to-image |
image_urls |
array de strings |
nano-banana-pro |
image_input |
array de strings |
El campo debe ir dentro del objeto input; la mayoría de los modelos de imagen de referencia requieren un array (aunque solo haya una imagen).
Pasos para corregirlo
- Aloja la imagen en una URL HTTP(S) accesible públicamente. Súbela a cualquier almacenamiento de objetos / CDN (Cloudflare R2, S3, GCS, etc.) y marca el objeto como de lectura pública, o usa una URL prefirmada que siga siendo válida.
- Confirma que se puede acceder sin autenticación. En una sesión limpia (o desde una máquina que no sea la tuya) ejecuta
curl -sI "<tuURL>"; debería devolver200con content-typeimage/*. Si requiere cookies, headers o VPN, el servidor no podrá acceder. - Usa el model id de imagen a imagen, no el id básico. Para editar, llama a
gpt-image-2/image-to-image(o la ruta i2i correspondiente a tu modelo), no agpt-image-2. - Usa el nombre de campo que indique la documentación de ese modelo (
input_urls/image_urls/image_input) dentro deinput. - Nunca envíes base64. Si solo tienes los bytes, súbelos primero y pasa la URL obtenida.
- Primero envía y luego consulta el estado.
GET /v1/tasks/<taskId>hasta quedata.statusseasuccessofail. Si falla, leedata.error.message: si aparece "could not be downloaded" es un problema de la URL, no de tu prompt.
Ejemplo mínimo de verificación
Haz primero una comprobación de conectividad sin coste: listar modelos no crea ninguna tarea ni gasta dinero.
curl -s https://api.hiapi.ai/v1/models \
-H "Authorization: Bearer $HIAPI_API_KEY"
Si devuelve 200 con un array data, tu clave funciona. Una clave incorrecta devolverá 401 + {"error":{"code":"permission_denied", ... ,"type":"hiapi_error"}}: eso es un problema de autenticación, no de entrada. Después, envía una solicitud de imagen a imagen correcta: pon en el campo del modelo una URL accesible públicamente.
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"]
}
}'
Sustituye input_urls por la URL de tu propia imagen accesible. Si el envío es correcto, devolverá data.taskId; luego consulta GET https://api.hiapi.ai/v1/tasks/<taskId> hasta que data.status sea success y obtén el resultado de data.output[0].url (esa URL tiene periodo de validez; descárgala o guárdala cuanto antes, no la enlaces en caliente).
Enlaces relacionados
- HiAPI 400 Bad Request: cómo corregir errores de parámetros: explicación detallada de nombres de campo o model id incorrectos que se rechazan con un 400 en la fase de envío antes de que la tarea llegue a ejecutarse.
- ¿Se cobran las solicitudes fallidas de HiAPI?: reglas de facturación cuando una tarea falla después de haber sido aceptada.
- Verificar campos: página del modelo gpt-image-2 y página del modelo Nano Banana Pro.
- Precios de la API y ve a la consola para obtener tu API Key.
- Documentación de la API: crear tarea, consultar detalle de la tarea, autenticación.
Preguntas frecuentes
¿Se puede enviar base64 a los modelos de imagen a imagen de HiAPI?
No. El campo de imagen requiere una URL HTTP(S) pública que el servidor pueda descargar. Las cadenas data:image/...;base64,... se aceptan en la fase de envío de algunos modelos, pero después la tarea termina con status: fail y el código de error TASK_FAILED / task failed. Sube los bytes a una ubicación pública y pasa la URL.
Mi POST /v1/tasks devolvió 200, pero la tarea falló, ¿por qué?
El 200 de la fase de envío solo significa que la solicitud se aceptó. La descarga de la imagen y la generación ocurren después. Consulta GET /v1/tasks/<taskId>; una entrada de imagen defectuosa se revelará allí con data.status: fail, con error.code INVALID_REQUEST ("The image URL could not be downloaded…") o TASK_FAILED.
¿En qué campo hay que poner la URL de la imagen?
Depende del modelo. gpt-image-2/image-to-image usa input_urls, seedream-5.0-pro/image-to-image usa image_urls y nano-banana-pro usa image_input (todos son arrays). Antes de enviar la solicitud, comprueba en la página del modelo su schema actual.
¿Sirve localhost o una URL privada?
No. HiAPI descarga la imagen desde sus propios servidores, así que localhost, 127.0.0.1, direcciones de red interna, enlaces visibles solo tras iniciar sesión y URL prefirmadas caducadas fallarán todos con "The image URL could not be downloaded.". Usa una URL que se resuelva públicamente y no requiera autenticación.
¿Qué significa el error additional properties 'input_urls' not allowed?
Que has pasado el campo de imagen a un modelo que no lo define; normalmente porque usaste el id básico de texto a imagen (gpt-image-2) en lugar de la ruta de imagen a imagen (gpt-image-2/image-to-image), o porque usaste el nombre de campo de otro modelo. Es un 400 de la fase de envío; consulta la guía de 400 Bad Request de arriba.
¿Se cobran las tareas de imagen fallidas?
Las solicitudes rechazadas con 400 en la fase de envío no se facturan; pero una vez aceptada (200 + taskId), una tarea que falla después puede facturarse; consulta «¿Se cobran las solicitudes fallidas?» más arriba. Por eso, antes de reintentar, corrige primero la URL.
Artículos relacionados
Ver todos los artículos →-
Tutorial
Cómo llamar a hailuo-2.3-fast/image-to-video a través de la API de HiAPI: práctica con curl y Python
La primera solicitud ejecutable del nivel rápido y de bajo coste de imagen a vídeo: del ID del modelo a la descarga del MP4
-
Tutorial
Cómo llamar a hailuo-2.3/text-to-video mediante la API de HiAPI: curl, Python y ejemplos de solicitud ejecutables
-
Tutorial
Uso de Kandinsky 6.0 Pro texto a video en HiAPI: tutorial con curl y Python
Demostración práctica centrada en la solicitud: construir la llamada de prompt a clip de video, enviar la solicitud, sondear el estado de finalización y descargar el resultado