HiAPI
博客

教程

HiAPI 图片输入报错:传可公开访问的 URL,别传 Base64

2026年10月22日
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 对象里;多数参考图模型要求传数组(哪怕只有一张图)。

修复步骤

  1. 把图片托管到公网可访问的 HTTP(S) URL。 上传到任意对象存储 / CDN(Cloudflare R2、S3、GCS 等)并把对象设为公开读,或用一个仍然有效的预签名 URL。
  2. 确认无需鉴权即可访问。 在干净会话里(或换一台不是你本机的机器)跑 curl -sI "<你的URL>",应当回 200 且 content-type 为 image/*。如果它需要 cookie、header 或 VPN,服务端就抓不到。
  3. 用图生图的 model id,别用裸 id。 做编辑要调 gpt-image-2/image-to-image(或你那个模型对应的 i2i 路由),不要调 gpt-image-2。
  4. 用该模型文档里的字段名(input_urls / image_urls / image_input),放进 input 里。
  5. 绝不传 base64。 如果手上只有字节,先上传、再把拿到的 URL 传进去。
  6. 先提交,再轮询。 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 图生图模型传 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 修对。

立即开始构建持久 AI 产物

获取 API 密钥,通过一个基于任务(task)的 API 调用图像、视频和音频模型。

阅读 API 文档