HiAPI
ブログ

チュートリアル

hiapi API で gpt-image-2/text-to-image を使う方法:パラメータ、コード、実行可能なサンプル

Jun 25, 2026
hiapi API で gpt-image-2/text-to-image を使う方法:パラメータ、コード、実行可能なサンプル

このチュートリアルでは、hiapi の統合タスク API を使って gpt-image-2/text-to-image で画像を生成するために必要な最小限のコードを示し、その後、各パラメータと、コードが動作した後に採用すべき本番向けのパターン(コールバック、冪等性、エラーハンドリング)を一つずつ解説します。

前提条件

API キーが必要です。hiapi コンソールの API キーページで作成してください。キーは sk- で始まります。gpt-image-2/text-to-image のモデルページには現在の 1 枚あたりの価格が記載されています。詳細は料金ページをご覧ください。

このガイドのすべての呼び出しは、統合された非同期タスクエンドポイントに送信されます:

  • POST https://api.hiapi.ai/v1/tasks — 生成タスクを作成
  • GET https://api.hiapi.ai/v1/tasks/{taskId} — タスクのステータスをポーリング

プラットフォーム共通のリファレンスドキュメントは hiapi API ドキュメントにあります。

最小限の実行可能なサンプル(curl)

1 回の生成は 2 ステップのやり取りです。まずタスクを作成し、次に完了を待ちます。

# 1. Create the task
curl -s -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2/text-to-image",
    "input": {
      "prompt": "a calico cat curled up on a sunlit windowsill, soft focus background",
      "aspect_ratio": "1:1",
      "resolution": "1K"
    }
  }'
# => {"code":200,"data":{"taskId":"tk-hiapi-01KVY...."},"message":"success"}

# 2. Poll until status == "success"
TASK_ID="tk-hiapi-01KVY...."
curl -s "https://api.hiapi.ai/v1/tasks/$TASK_ID" \
  -H "Authorization: Bearer sk-YOUR_KEY"
# => {"code":200,"data":{"status":"success","output":[{"url":"https://..."}], ...}}

画像の URL は data.output[0].url にあります。output[0].expireAt は非常に短いため、すぐにダウンロードしてください。この URL は取得用であり、恒久的な埋め込み用ではありません。

Python:作成 + ポーリング + ディスクへの保存

import os
import time
import urllib.request
import requests  # pip install requests

API_BASE = "https://api.hiapi.ai/v1/tasks"
TOKEN = os.environ["HIAPI_API_KEY"]  # sk-...

def create_task(prompt: str, aspect_ratio: str = "1:1", resolution: str = "1K") -> str:
    payload = {
        "model": "gpt-image-2/text-to-image",
        "input": {
            "prompt": prompt,
            "aspect_ratio": aspect_ratio,
            "resolution": resolution,
        },
    }
    r = requests.post(API_BASE, json=payload,
                      headers={"Authorization": f"Bearer {TOKEN}"},
                      timeout=60)
    r.raise_for_status()
    body = r.json()
    if body.get("error"):
        raise RuntimeError(f"create failed: {body['error']}")
    return body["data"]["taskId"]

def wait_task(task_id: str, timeout_s: int = 600, poll_s: int = 5) -> dict:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        r = requests.get(f"{API_BASE}/{task_id}",
                         headers={"Authorization": f"Bearer {TOKEN}"},
                         timeout=30)
        r.raise_for_status()
        task = r.json().get("data") or {}
        status = task.get("status")
        if status == "success":
            return task
        if status == "fail":
            raise RuntimeError(f"task failed: {task.get('error')}")
        time.sleep(poll_s)
    raise TimeoutError(f"task {task_id} did not finish in {timeout_s}s")

if __name__ == "__main__":
    task_id = create_task(
        "a calico cat curled up on a sunlit windowsill, soft focus background",
        aspect_ratio="3:2",
        resolution="1K",
    )
    task = wait_task(task_id)
    url = task["output"][0]["url"]
    urllib.request.urlretrieve(url, "cat.png")
    print(f"saved cat.png from task {task_id}")

Node.js:fetch を使った同じフロー

// Node 18+ has global fetch
const API_BASE = "https://api.hiapi.ai/v1/tasks";
const TOKEN = process.env.HIAPI_API_KEY;

async function createTask(prompt, aspectRatio = "1:1", resolution = "1K") {
  const res = await fetch(API_BASE, {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "gpt-image-2/text-to-image",
      input: { prompt, aspect_ratio: aspectRatio, resolution },
    }),
  });
  const body = await res.json();
  if (body.error) throw new Error(`create failed: ${body.error.code} ${body.error.message}`);
  return body.data.taskId;
}

async function waitTask(taskId, { timeoutMs = 600_000, pollMs = 5_000 } = {}) {
  const deadline = Date.now() + timeoutMs;
  while (Date.now() < deadline) {
    const res = await fetch(`${API_BASE}/${taskId}`, {
      headers: { "Authorization": `Bearer ${TOKEN}` },
    });
    const task = (await res.json()).data || {};
    if (task.status === "success") return task;
    if (task.status === "fail") throw new Error(`task failed: ${JSON.stringify(task.error)}`);
    await new Promise(r => setTimeout(r, pollMs));
  }
  throw new Error(`task ${taskId} timed out`);
}

(async () => {
  const id = await createTask(
    "a calico cat curled up on a sunlit windowsill, soft focus background",
    "16:9",
    "1K",
  );
  const task = await waitTask(id);
  const url = task.output[0].url;
  const img = await fetch(url).then(r => r.arrayBuffer());
  const { writeFileSync } = await import("node:fs");
  writeFileSync("cat.png", Buffer.from(img));
  console.log(`saved cat.png from task ${id}`);
})();

パラメータリファレンス

リクエストボディには常に 2 つのトップレベルフィールドが含まれます:model(文字列、裸のモデル ID gpt-image-2/text-to-image)と input(モデル固有のパラメータオブジェクト)です。

input フィールド 必須 型 説明
prompt はい string 生成したい画像のテキストによる説明。
aspect_ratio はい string 次のいずれか:1:1、3:2、2:3、4:3、3:4、5:4、4:5、16:9、9:16、21:9、または auto。
resolution いいえ string 1K(デフォルト)、2K、または 4K。ピクセルサイズは選択したアスペクト比に応じてスケールします。
callback いいえ object { "url": "https://yours.example/hook", "when": "final" } — 次のセクションを参照。

作成に成功すると {"code":200, "data":{"taskId":"tk-hiapi-..."}, "message":"success"} が返されます。GET /v1/tasks/{taskId} が返す data.status は handling、success、fail のいずれかです。成功時、data.output は配列で、その最初の要素に画像の url と expireAt タイムスタンプが含まれます。

他の hiapi 画像モデル(例:z-image、qwen-image)は若干異なる input フィールドを使用します。aspect_ratio は gpt-image-2/text-to-image が採用する規約です。モデルを切り替える際は、モデルページで正確な input 構造を確認してください。

本番向けパターン

ポーリングの代わりにコールバックを使う

5 秒ごとのポーリングはプロトタイプ開発では問題ありませんが、本番トラフィックでは、hiapi が完了したタスクをプッシュしてくれるようにすることで、ワーカーを解放できます。input に callback ブロックを追加します:

{
  "model": "gpt-image-2/text-to-image",
  "input": {
    "prompt": "an astronaut sketching the moon",
    "aspect_ratio": "3:2",
    "resolution": "1K",
    "callback": {
      "url": "https://your-app.example.com/webhooks/hiapi",
      "when": "final"
    }
  }
}

when: "final" はタスクが終端状態(success または fail)に達したときに 1 回だけトリガーされます。エンドポイントが受け取るペイロードの構造は GET /v1/tasks/{id} と同じであるため、ハンドラはポーリング用の解析ロジックを再利用できます。taskId をタスク作成時に保存した taskId と照合することで、そのコールバックがどのリクエストのものかを把握できます。

作成操作を冪等にする

ワーカーが POST /v1/tasks の後、taskId を保存する前にクラッシュすると、同じ画像を 2 回生成してしまう可能性があります。低コストな解決策は、作成レスポンスを受け取った瞬間に、リクエストを送信したのと同じトランザクション内で (your_request_id → taskId) をデータベースに保存することです。ワーカーがリトライした場合、新しいタスクを作成するのではなく、既存の taskId を見つけてポーリングを再開します。

認証エラーを正しく処理する

hiapi の認証失敗は HTTP 200 を返し、レスポンスボディにエラーペイロードを埋め込みます:

{"error":{"code":"permission_denied","message":"This API key cannot use the selected model. ...","type":"hiapi_error"}}

したがって、200 ステータスコードだけでは成功を意味しません。常に最初に body.error を確認してください。存在する場合は、error.code(permission_denied、invalid_request など)と error.message を確認します。メッセージ内の request_id は、サポートが必要なときにサポートチケットに貼り付ける内容です。

すぐにダウンロードし、自前で再ホスティングする

data.output[0].url は短命な URL です。レスポンスには expireAt が含まれます。hiapi の URL を製品の <img src> に直接埋め込まないでください。タスクが成功したらすぐにバイトストリームをダウンロードし、自前のストレージ(S3、R2、Supabase Storage など)にアップロードして、そこから配信してください。

適切なタイムアウトを設定する

妥当なデフォルトは、POST リクエストのタイムアウトが 60 秒(タスク作成は高速です。実際には API が受信を確認するのを待っているだけです)、ポーリングループの総予算が 10 分、ポーリング間隔が 5 秒です。10 分を超えるタスクは、ほぼ常にタスクがこっそり fail 状態になったことを意味するため、無限に待つよりも、タイムアウトして最後のタスクレスポンスボディをログに出力する方が有用です。

よくある質問

gpt-image-2 と gpt-image-2/text-to-image の違いは何ですか?

gpt-image-2 はモデルシリーズです。gpt-image-2/text-to-image は、テキストプロンプトを新しい画像に変換するために呼び出す特定のエンドポイントです。このシリーズの他のバリエーションは異なる input 構造を公開しています(例えば、画像編集は参照画像を受け取ります)。不明な場合は、モデルページに表示されている裸のモデル ID を使用してください。

aspect_ratio: auto は何をしますか?

auto は、プロンプトに基づいてモデルがアスペクト比を決定します。レイアウトに強い要件がない場合に使用します。そうでない場合は、下流のクロップを予測可能にするために、自分で比率を固定してください。

なぜリクエストが HTTP 200 を返すのに permission_denied が付くのですか?

API キーが間違っている(誤字、失効済み、sk- プレフィックスの欠落)か、そのキーのプランに gpt-image-2/text-to-image が含まれていないかのいずれかです。API キーコンソールを開いてキー文字列を確認し、料金ページでプランを確認してください。常に body.error.code を確認し、HTTP ステータスコードだけを信じてはいけません。

1 つのリクエストで複数の画像を生成できますか?

gpt-image-2/text-to-image は 1 タスクにつき 1 枚の画像のみを生成します。data.output は配列ですが、このモデルでは長さが常に 1 です。N 個のバリエーションを生成するには、N 個のタスクを並行して起動し、上記の callback パターンを使用して、N 個のワーカースレッドを待機させ続けないようにしてください。

実行中のタスクをキャンセルするにはどうすればよいですか?

統合タスク API は現在、キャンセルエンドポイントを提供していません。最も簡単な緩和策は、ユーザーが結果を必要としなくなったときにクライアントワーカーがそれを破棄することです。すでに実行された生成には引き続き課金されるため、キャンセルを強制する正しい場所は POST /v1/tasks を呼び出す前です。

他の画像モデルに切り替えるにはどうすればよいですか?

model を新しい裸の ID(例:z-image/text-to-image)に変更し、そのモデルの構造に合わせて input を調整します。モデルごとに構造は完全には同じではありません。size を受け取るもの、aspect_ratio を受け取るもの、resolution を受け取らないものもあります。モデルカタログには利用可能なすべてのモデルが一覧されており、各モデルページにその input フィールドが記載されています。

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

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

APIドキュメントを読む