教程
HiAPI 图片输入报错:传可公开访问的 URL,别传 Base64
HiAPI 上的图生图(image-to-image)和参考图模型,是从公网可访问的 HTTP(S) URL 去取你的源图——不收 base64 字节串,也抓不到私有地址。最容易踩的坑是:错误的图片输入看起来像成功了——POST /v1/tasks 返回 200 带一个 taskId,真正的失败要等你去轮询任务时才冒出来。你实际会看到的两种失败是这样的:
{ "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" } } }
第一种是不可达 URL 的返回;第二种是把 base64 data URI 当图片传时拿到的通用结果——没有任何提示,只有一句 task failed,这也是最让人卡住的地方。注意外层那句 "message": "success" 只代表这次轮询请求本身成功了,真正的结果在 data.status 里。
常见原因(按命中概率从高到低)
你把 base64 粘进了图片字段——一串
data:image/...;base64,...。这个字段要的是服务端能去抓取的 URL,不是内联字节。在gpt-image-2/image-to-image上,data URI 在提交期会被接受,随后任务终态status: fail,错误码TASK_FAILED/task failed。URL 不是公网可达。
http://localhost、127.0.0.1、内网 IP、需要登录才能看的文件、已过期的预签名链接,都会以INVALID_REQUEST失败——"The image URL could not be downloaded…"。字段名用错了(各家不一样,见下表)。图片输入字段跨模型家族并不统一。名字写错会在提交期就被 HTTP
400挡掉,例如在gpt-image-2/image-to-image上误用image_url:{ "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" }你用了裸 model id 去做编辑。裸 id(比如
gpt-image-2)是纯文生图,根本没定义图片字段,所以图片字段会被拒:400 invalid input: <root>: additional properties 'input_urls' not allowed。做编辑要用图生图的路由 id:gpt-image-2/image-to-image。
怎么读错误码:定位是「输入问题」还是「上游问题」
把返回分成提交期(POST /v1/tasks 的直接响应)和终态(轮询 GET /v1/tasks/<taskId> 拿到的 data.status)两段来看:
- 提交期 HTTP 400,扁平信封
{"code":400,"data":null,"error_code":"INVALID_REQUEST","message":"invalid input: ..."}→ 你的请求结构/字段有问题(输入问题)。任务还没建,不计费。改字段名或 model id 即可。 - 提交期 HTTP 401,嵌套信封
{"error":{"code":"permission_denied","type":"hiapi_error","request_id":"..."}}→ 这是鉴权问题(key 不对或没权限),不是输入问题。 - 提交期 HTTP 200 +
taskId,但轮询时data.status: "fail":看data.error.code——INVALID_REQUEST且 message 为 "could not be downloaded" → 图片 URL 抓不到(仍是你的输入问题:把图换成公网可达的 URL)。TASK_FAILED且 message 为 "task failed" → 通用失败、没有提示。先排除 base64 / 坏输入;排除后仍失败,才按「上游生成」问题处理。
一句话:提交期的 4xx 是请求 / 鉴权层面的问题,终态的 fail 才可能牵涉下载或上游生成;而无论哪种,都别被外层的 "message":"success" 骗了,一切以 data.status 为准。
图片输入字段名因模型而异
下面这张表按各模型当前 input schema 实测核对(务必再以模型页为准,字段随家族不同):
| 模型 id(图生图路由) | 图片输入字段 | 类型 |
|---|---|---|
gpt-image-2/image-to-image |
input_urls |
字符串数组 |
seedream-5.0-pro/image-to-image |
image_urls |
字符串数组 |
nano-banana-pro |
image_input |
字符串数组 |
字段要放在 input 对象里;多数参考图模型要求传数组(哪怕只有一张图)。
修复步骤
- 把图片托管到公网可访问的 HTTP(S) URL。 上传到任意对象存储 / CDN(Cloudflare R2、S3、GCS 等)并把对象设为公开读,或用一个仍然有效的预签名 URL。
- 确认无需鉴权即可访问。 在干净会话里(或换一台不是你本机的机器)跑
curl -sI "<你的URL>",应当回200且 content-type 为image/*。如果它需要 cookie、header 或 VPN,服务端就抓不到。 - 用图生图的 model id,别用裸 id。 做编辑要调
gpt-image-2/image-to-image(或你那个模型对应的 i2i 路由),不要调gpt-image-2。 - 用该模型文档里的字段名(
input_urls/image_urls/image_input),放进input里。 - 绝不传 base64。 如果手上只有字节,先上传、再把拿到的 URL 传进去。
- 先提交,再轮询。
GET /v1/tasks/<taskId>直到data.status为success或fail。失败时读data.error.message——出现 "could not be downloaded" 就是 URL 的问题,不是你的 prompt。
最小验证示例
先做一个零成本的连通性检查:列模型不创建任何任务、不花钱。
curl -s https://api.hiapi.ai/v1/models \
-H "Authorization: Bearer $HIAPI_API_KEY"
返回 200 带一个 data 数组,说明你的 key 是通的。坏 key 会回 401 + {"error":{"code":"permission_denied", ... ,"type":"hiapi_error"}}——那是鉴权问题,不是输入问题。接着发一个正确的图生图请求:模型字段里放一个公网可达的 URL。
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"]
}
}'
把 input_urls 换成你自己可达的图片 URL。提交成功会返回 data.taskId;然后轮询 GET https://api.hiapi.ai/v1/tasks/<taskId> 直到 data.status 为 success,再从 data.output[0].url 取结果(该 URL 带有效期,拿到后尽快下载或转存,别存热链)。
相关链接
- HiAPI 400 Bad Request:如何修复参数错误——字段名或 model id 写错、在任务跑起来之前就被提交期 400 挡掉的详解。
- HiAPI 失败请求会扣费吗?——任务被接收后才失败时的计费规则。
- 核对字段:gpt-image-2 模型页 与 Nano Banana Pro 模型页。
- API 定价,以及去控制台拿 API Key。
- API 文档:创建任务、查询任务详情、鉴权。
常见问题
能给 HiAPI 图生图模型传 base64 吗?
不能。图片字段要的是服务端能下载的公网 HTTP(S) URL。data:image/...;base64,... 字符串在部分模型的提交期会被接受,但任务随后终态 status: fail,错误码 TASK_FAILED / task failed。把字节上传到公开位置、传 URL 进去。
我的 POST /v1/tasks 返回了 200,但任务失败了,为什么?
提交期的 200 只代表请求被接收。图片下载和生成都发生在之后。去轮询 GET /v1/tasks/<taskId>;坏的图片输入会在那里以 data.status: fail 暴露,error.code 为 INVALID_REQUEST("The image URL could not be downloaded…")或 TASK_FAILED。
图片 URL 到底该放哪个字段?
看模型。gpt-image-2/image-to-image 用 input_urls,seedream-5.0-pro/image-to-image 用 image_urls,nano-banana-pro 用 image_input(都是数组)。发请求前先到模型页核对它当前的 schema。
localhost 或私有 URL 行不行?
不行。HiAPI 是从它自己的服务器去抓图,所以 localhost、127.0.0.1、内网地址、登录后才可见的链接、过期的预签名 URL 全都会以 "The image URL could not be downloaded." 失败。请用一个公网可解析、无需鉴权的 URL。
报 additional properties 'input_urls' not allowed 是什么意思?
你把图片字段传给了一个没有定义它的模型——通常是用了裸文生图 id(gpt-image-2)而不是图生图路由(gpt-image-2/image-to-image),或者用了别的模型的字段名。这是提交期的 400,参见上面的 400 Bad Request 指南。
失败的图片任务会扣费吗?
在提交期就被 400 拒掉的请求不计费;但一旦被接收(200 + taskId)、之后才失败的任务是可能计费的——详见上面的「失败请求会扣费吗?」。所以重跑之前,先把 URL 修对。