HiAPI
ブログ

チュートリアル

HiAPI 画像入力エラー:公開アクセス可能な URL を渡し、Base64 は渡さない

Oct 22, 2026
HiAPI 画像入力エラー:公開アクセス可能な URL を渡し、Base64 は渡さない

HiAPI の image-to-image と参照画像モデルは、インターネットからアクセス可能な HTTP(S) URL から元画像を取得します——base64 のバイト列は受け付けず、プライベートアドレスも取得できません。最もハマりやすい罠は、不正な画像入力が成功したように見えることです——POST /v1/tasks が 200 と taskId を返し、実際の失敗はタスクをポーリングしたときに初めて現れます。実際に目にする失敗は次の 2 種類です:

{ "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" } } }

1 つ目は到達不能な URL の戻り値です。2 つ目は 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。編集には image-to-image のルート id:gpt-image-2/image-to-image を使ってください。

エラーコードの読み方:「入力の問題」か「上流の問題」かを特定する

戻り値を送信時(POST /v1/tasks の直接のレスポンス)と終態(ポーリング GET /v1/tasks/<taskId> で得られる data.status)の 2 段階に分けて見てください:

  • 送信時の 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(image-to-image ルート) 画像入力フィールド 型
gpt-image-2/image-to-image input_urls 文字列配列
seedream-5.0-pro/image-to-image image_urls 文字列配列
nano-banana-pro image_input 文字列配列

フィールドは input オブジェクトの中に置きます。多くの参照画像モデルは配列を要求します(画像が 1 枚だけでも)。

修正手順

  1. 画像をインターネットからアクセス可能な HTTP(S) URL にホストする。 任意のオブジェクトストレージ / CDN(Cloudflare R2、S3、GCS など)にアップロードし、オブジェクトを公開読み取りに設定するか、まだ有効な署名付き URL を使用します。
  2. 認証なしでアクセスできることを確認する。 クリーンなセッションで(または自分のマシンではない別のマシンで)curl -sI "<あなたのURL>" を実行し、200 かつ content-type が image/* になることを確認します。cookie、header、VPN が必要な場合、サーバー側は取得できません。
  3. image-to-image の 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 の問題であり、プロンプトの問題ではありません。

最小検証の例

まずゼロコストの疎通確認を行います。モデル一覧はタスクを一切作成せず、費用もかかりません。

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"}} を返します——それは認証の問題であり、入力の問題ではありません。続いて正しい image-to-image リクエストを送ります:モデルフィールドにインターネットから到達可能な 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 の image-to-image モデルに 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 というエラーはどういう意味ですか? 画像フィールドを、それを定義していないモデルに渡したということです——通常は image-to-image ルート(gpt-image-2/image-to-image)ではなくベアのテキストから画像の生成 id(gpt-image-2)を使ったか、別モデルのフィールド名を使ったかのどちらかです。これは送信時の 400 です。上記の 400 Bad Request ガイドを参照してください。

失敗した画像タスクは課金されますか? 送信時に 400 で拒否されたリクエストは課金されません。しかし、一度受け付けられ(200 + taskId)、その後に失敗したタスクは課金される可能性があります——詳細は上記の「失敗リクエストは課金される?」を参照してください。ですから再実行する前に、まず URL を正しく修正してください。

永続的なAIアーティファクトで開発を始める

APIキーを取得して、タスクベースの1つのAPIで画像・動画・音声モデルを呼び出せます。

APIドキュメントを読む