# OpenAI画像生成APIの使い方：Images APIとResponsesの使い分け

> 単発の生成・編集はImages API、会話で直しを重ねるならResponses APIの画像生成ツール。どちらもモデルIDを明示し、base64で受け取ります。

- Source: https://www.aifreeapi.com/ja/posts/openai-image-api-tutorial
- Language: ja
- Published: 2026-03-22
- Updated: 2026-09-25
- Publisher: AI Free API (https://www.aifreeapi.com)

2026年9月25日時点の答えはシンプルです。**1つのプロンプトから画像を1枚生成する、または1回で編集するだけならImages API**（`client.images.generate`に`model="gpt-image-2.5-flare"`などを直接指定）。**チャットの流れの中で「もう少し明るく」と何度も直したい、あるいは文章生成や他のツールと組み合わせたいならResponses API**の`image_generation`ツールを使います。OpenAIの[画像生成ガイド](https://developers.openai.com/api/docs/guides/image-generation#choosing-the-right-api)も同じ基準で使い分けを示しています。

どちらを選んでも、次の3点は共通です。

- **モデルIDは必ず書く。** Images APIで`model`を省くと既定値は削除済みの`dall-e-2`、Responses APIのツールで`model`を省くと既定値は2026年10月23日に停止する`gpt-image-1`です。
- **結果はbase64で返る。** GPT Image系のモデルは画像URLを返しません。Images APIなら`data[0].b64_json`、Responses APIなら`output`内の`image_generation_call`の`result`をデコードして保存します。
- **新規の組み込みはGPT Image 2.5から。** 日常の生成は`gpt-image-2.5-flare`、編集の精度を重視するなら`gpt-image-2.5-sunburst`です。

以下のコードは2026年9月25日時点のOpenAIのガイドとAPIリファレンスに沿った書き方で、実行結果として検証したものではありません。動かすときは、レスポンスの中身と`usage`を自分の環境で確認してください。

## Images APIとResponses API、どちらを使うか

判断の分かれ目は「画像生成そのものが機能なのか、会話や処理の一部なのか」です。よくあるケースに当てはめると次のようになります。

| やりたいこと | 使うAPI | 理由 |
|---|---|---|
| プロンプトから1枚作って保存する（記事のサムネイル、商品画像の下書きなど） | Images API | 画像モデルを直接指定でき、結果の場所も1か所で済む |
| 同じプロンプトで複数枚をまとめて作る | Images API | `n`で1〜10枚を指定できる。Responsesのツールには`n`がない |
| 手元の画像を1回で編集・合成する | Images API（`/v1/images/edits`） | 1プロンプトで完結する編集はImages APIの担当 |
| Batch APIで大量に処理したい | `gpt-image-2`をBatch API経由で | 現行モデルでBatchに対応するのは`gpt-image-2`だけ。GPT Image 2.5は非対応 |
| チャットで生成した画像を、会話を続けながら何度も直す | Responses API | `previous_response_id`や画像IDで前の画像を引き継げる |
| 文章の回答と画像を1つの応答で返す、画像を作るかどうかをモデルに任せる | Responses API | 画像生成は組み込みツールとして他の処理と並ぶ |
| 今のコードがChat Completionsベース | Images APIを別に呼ぶ | Chat CompletionsではOpenAIがホストするツールをそのまま使えない |

迷ったときはImages APIから始めるのが近道です。リクエストに書くモデルが画像モデル1つだけで、結果の取り出し方も決まっており、失敗したときの原因を切り分けやすいからです。会話で直しを重ねる体験が必要になった時点でResponses APIに移っても、プロンプトやサイズ・品質の設定はほぼそのまま使えます。

Files APIにアップロード済みの画像をFile IDで渡せる点は、OpenAIがResponses API側の追加機能として挙げています。ただしImages APIの編集エンドポイントもJSON形式なら`file_id`で画像を受け付けるので、File IDを使いたいというだけならResponsesに移る理由にはなりません。Chat CompletionsとResponses APIのテキスト面での違いは「[Chat Completions と Responses API の違い：URL変更では終わらない](/ja/posts/chat-completions-vs-responses-api)」を参照してください。

## 2つのAPIの違い：モデルの書き場所、結果、課金

コードを書く前に押さえておきたい違いを表にまとめます。Responses APIは「会話を担当するテキストモデル」と「画像を描くモデル」を別々に指定する点が、Images APIとのいちばん大きな違いです。

![Images APIはトップレベルのmodelに画像モデルを書いてb64_jsonで受け取り、Responses APIはトップレベルに会話用モデル、ツールの中に画像モデルを書いてimage_generation_callのresultで受け取ることを示す図](https://www.aifreeapi.com/posts/ja/openai-image-api-tutorial/img/model-and-result.webp)

| 項目 | Images API | Responses APIの`image_generation`ツール |
|---|---|---|
| エンドポイント | `POST /v1/images/generations`、`POST /v1/images/edits` | `POST /v1/responses` |
| 画像モデルの書き場所 | トップレベルの`model` | `tools`内の`{"type": "image_generation", "model": ...}` |
| トップレベルの`model` | 画像モデル | 会話を担当するテキストモデル（画像モデルは置けない） |
| `model`を省いたとき | `dall-e-2`が既定（GPT Image専用パラメータを使う場合を除く）。`dall-e-2`は削除済み | ツールの既定は`gpt-image-1`（2026年10月23日停止） |
| 結果の場所 | `data[0].b64_json` | `output`のうち`type`が`image_generation_call`の項目の`result` |
| 1回で複数枚 | `n`で1〜10枚 | `n`はない |
| 画像生成を確実に実行させる | ツールの選択がなく、リクエストがそのまま画像生成になる | `tool_choice={"type": "image_generation"}`で強制する |
| 続きの編集 | 編集エンドポイントに画像を渡し直す | `previous_response_id`、または`image_generation_call`のID |
| 課金 | 画像モデルのトークン | 画像モデルのトークン＋会話側モデルのトークン |

根拠はOpenAIの[画像生成ガイド](https://developers.openai.com/api/docs/guides/image-generation)、[画像生成ツールのガイド](https://developers.openai.com/api/docs/guides/tools-image-generation)、[Responses APIリファレンス](https://developers.openai.com/api/reference/resources/responses/methods/create#responses-create-tools)、[Images APIリファレンス](https://developers.openai.com/api/reference/python/resources/images/methods/generate)です。OpenAIのガイドでは「Image API」とも表記されますが、同じものを指します。

「edit」という言葉は2か所に出てくるので注意してください。Images APIの`/v1/images/edits`は編集用のエンドポイントで、Responses APIの`action: "edit"`はツールに「会話中の画像を編集させる」指定です。名前は似ていても呼び方もパラメータも別物です。

## 使うモデルIDと停止日

2026年9月25日時点で、画像モデルの状況は次のとおりです（[OpenAIの非推奨・停止一覧](https://developers.openai.com/api/docs/deprecations)と画像生成ガイドより）。

| モデルID | 状態 | 使いどころ・注意点 |
|---|---|---|
| `gpt-image-2.5-flare` | 現行 | 高速で高品質な日常の生成向け。スナップショットは`gpt-image-2.5-flare-2026-09-08` |
| `gpt-image-2.5-sunburst` | 現行 | 編集の精度を重視するワークフロー向け。スナップショットは`gpt-image-2.5-sunburst-2026-09-08` |
| `gpt-image-2` | 以前のモデル（非推奨ではない） | 既存の組み込みを維持したいとき、Batchを使いたいとき。品質は`high`まで |
| `gpt-image-1` | **2026年10月23日に停止** | 置き換え先として一覧には`gpt-image-2`が挙がっている |
| `gpt-image-1.5`、`gpt-image-1-mini`、`chatgpt-image-latest` | **2026年12月1日に停止** | 同上 |
| `dall-e-2`、`dall-e-3` | 2026年5月12日に削除済み | 呼び出せない |

`gpt-image-2.5`という末尾のない素のIDはありません。停止一覧は置き換え先として`gpt-image-2`を挙げていますが、画像生成ガイドは新規の組み込みにGPT Image 2.5の2モデルを勧めています。どちらを選んでも停止の影響は受けません。FlareとSunburstの選び方は「[GPT Image 2.5の使い方：Flare・Sunburstの違い、料金とAPI実装](/ja/posts/gpt-image-2-5)」で詳しく比べています。

手元のコードが停止の影響を受けるかは、リポジトリを検索すればすぐに分かります。

```bash
grep -rnE "gpt-image-1|chatgpt-image-latest|dall-e-[23]" --include="*.py" --include="*.js" --include="*.ts" .
grep -rn '"image_generation"' --include="*.py" --include="*.js" --include="*.ts" .
```

2つ目のコマンドで見つかったResponses APIのツール定義に`model`が書かれていなければ、そのコードは`gpt-image-1`を使っています。2026年10月23日以降にツールの`model`を省いた場合にエラーになるのか、別のモデルに切り替わるのかは公開ドキュメントに記載がありません。挙動に頼らず、今のうちに明示しておくのが確実です。OpenAIの画像生成ツールのガイドにあるJavaとRubyのサンプルにも、ツールの`model`を書いていない例があるので、コピーするときは気をつけてください。

![Images APIとツールのmodel省略、gpt-image-1.5などの旧モデルID、画像URLの取得という4つの書き方を、gpt-image-2.5-flareの明示とb64_jsonの取得に置き換える対応を示す図](https://www.aifreeapi.com/posts/ja/openai-image-api-tutorial/img/code-fixes.webp)

## Images APIで最初の1枚を生成する

### 準備

- OpenAIのAPIキーを発行し、環境変数`OPENAI_API_KEY`に設定します。ChatGPTの有料プランとAPIの課金は別の仕組みなので、APIの請求設定も必要です。
- SDKを入れます。Pythonは`pip install openai`、Node.jsは`npm install openai`です。
- GPT Image系のモデルは、組織認証（API Organization Verification）を済ませないと使えない場合があります。403エラーで認証を求められたら「[組織認証エラーの確認手順](/ja/posts/openai-image-generation-api-verification)」を、認証なしで進めたい場合は「[GPT Image 2は組織認証なしで使える？APIの選び方と認証の対処法](/ja/posts/gpt-image-2-without-organization-verification)」を参照してください。

### Python（Images API）

```python
import base64
from openai import OpenAI

client = OpenAI()  # 環境変数 OPENAI_API_KEY を読み込む

result = client.images.generate(
    model="gpt-image-2.5-flare",  # 省略しない
    prompt="白い背景に置かれた陶器のマグカップ。柔らかい自然光の商品写真",
    size="1024x1024",
    quality="medium",
)

image_b64 = result.data[0].b64_json
with open("mug.png", "wb") as f:
    f.write(base64.b64decode(image_b64))

print(result.usage)  # 消費トークンの確認用
```

### Node.js（Images API）

```js
// ESM形式（.mjs、または package.json に "type": "module"）で実行
import fs from "node:fs";
import OpenAI from "openai";

const client = new OpenAI(); // 環境変数 OPENAI_API_KEY を読み込む

const result = await client.images.generate({
  model: "gpt-image-2.5-flare",
  prompt: "白い背景に置かれた陶器のマグカップ。柔らかい自然光の商品写真",
  size: "1024x1024",
  quality: "medium",
});

const imageB64 = result.data?.[0]?.b64_json;
if (!imageB64) throw new Error("画像データが返っていません");
fs.writeFileSync("mug.png", Buffer.from(imageB64, "base64"));
console.log(result.usage);
```

### curl

```bash
curl -s https://api.openai.com/v1/images/generations \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "gpt-image-2.5-flare", "prompt": "A ceramic mug on a white background, soft natural light", "size": "1024x1024", "quality": "medium"}' \
  | jq -r '.data[0].b64_json' | base64 --decode > mug.png
```

`mug.png`が1024×1024の画像として開ければ成功です。形式を指定しなければPNGで返ります。

### 古いコードから直すところ

- **`model`を書く。** 省略時の既定は`dall-e-2`で、このモデルはすでに削除されています。GPT Image専用のパラメータを付けたときだけ既定が変わるという条件付きの仕様なので、頼らないほうが安全です。
- **`response_format`と`data[0].url`を使わない。** GPT Image系は常にbase64を返し、`response_format`には対応していません。「URLは60分で失効する」という説明はDALL·E時代のもので、GPT Image系には当てはまりません。
- **複数枚は`n`で指定する。** 1〜10枚まで1リクエストで作れます。

### うまくいかないとき

- 複雑なプロンプトでは処理に最大2分ほどかかることがあります。HTTPクライアントのタイムアウトを短くしすぎないでください。
- レート制限やサーバーエラーは間隔を空けて再試行して構いません。一方、`error.type`が`image_generation_user_error`のエラー（`error.code`が`moderation_blocked`の場合を含む）は、プロンプトや入力画像を直さないまま自動で再試行しないでください。
- 問い合わせや調査に備えて、エラー時はリクエストIDをログに残しておきます。
- サイズ指定でエラーになる場合は「[GPT Image 2で1024×576がinvalid sizeになる理由と直し方](/ja/posts/gpt-image-2-invalid-size)」、透過画像を作りたい場合は「[GPT Image 2で透過PNG・WebPを作る：APIの生成・編集と保存方法](/ja/posts/gpt-image-2-transparent-background)」が次の一歩になります。

既存画像の編集（マスク、複数の参照画像、variationsからの移行）は「[GPT Image 2の画像編集API：variations移行とdall-e-2エラーの対処](/ja/posts/openai-image-editing-api)」を参照してください。

## Responses APIで画像生成ツールを使う

Responses APIでは、トップレベルの`model`に会話を担当するテキストモデルを、`tools`の中に画像モデルを書きます。下の例のトップレベルの`gpt-6-astra`は、OpenAIのガイドのサンプルで使われているモデルです。別のモデルを使う場合は、[モデルの詳細ページ](https://developers.openai.com/api/docs/models)で画像生成ツールに対応しているかを確認してください。ツールのガイドに載っている対応モデル一覧は、同じガイドのサンプルが使う`gpt-6-astra`を含んでおらず、最新とは限りません。

### Python（Responses API）

```python
import base64
from openai import OpenAI

client = OpenAI()

response = client.responses.create(
    model="gpt-6-astra",  # 会話を担当するテキストモデル
    input="白い背景に置かれた陶器のマグカップの商品写真を作ってください",
    tools=[{
        "type": "image_generation",
        "model": "gpt-image-2.5-flare",  # 省略すると gpt-image-1 が使われる
        "size": "1024x1024",
        "quality": "medium",
    }],
    tool_choice={"type": "image_generation"},  # 必ず画像生成ツールを呼ばせる
)

calls = [item for item in response.output if item.type == "image_generation_call"]
if not calls:
    raise RuntimeError("image_generation_call がありません（テキストだけの応答）")

for i, call in enumerate(calls):
    if not call.result:
        raise RuntimeError(f"画像が空です（status={call.status}）")
    with open(f"mug_{i}.png", "wb") as f:
        f.write(base64.b64decode(call.result))
    print(call.id, call.revised_prompt)
```

### Node.js（Responses API）

```js
import fs from "node:fs";
import OpenAI from "openai";

const client = new OpenAI();

const response = await client.responses.create({
  model: "gpt-6-astra",
  input: "白い背景に置かれた陶器のマグカップの商品写真を作ってください",
  tools: [
    {
      type: "image_generation",
      model: "gpt-image-2.5-flare",
      size: "1024x1024",
      quality: "medium",
    },
  ],
  tool_choice: { type: "image_generation" },
});

const calls = response.output.filter((item) => item.type === "image_generation_call");
if (calls.length === 0) throw new Error("image_generation_call がありません");

calls.forEach((call, i) => {
  if (!call.result) throw new Error(`画像が空です（status=${call.status}）`);
  fs.writeFileSync(`mug_${i}.png`, Buffer.from(call.result, "base64"));
  console.log(call.id, call.revised_prompt);
});
```

### 取り出し方で押さえること

- **`tool_choice`を付けないと、画像が返らないことがある。** 画像生成ツールを渡しただけでは、ツールを呼ぶかどうかは会話側のモデルが判断します。画像が必ず必要な処理では`tool_choice: {"type": "image_generation"}`で強制します。
- **`image_generation_call`の有無と`result`の中身を確かめる。** `result`はbase64文字列か`null`で、`status`は`in_progress`・`generating`・`completed`・`failed`のいずれかです。`output[0]`をいきなりデコードするコードは、テキストの項目や空の結果に当たると壊れます。
- **1件だけとは決め打ちしない。** ツールに枚数を指定するパラメータはなく、1回の応答に何件の`image_generation_call`が入るかはドキュメントで保証されていません。上の例のように全件をループで処理しておくと安全です。決まった枚数が必要ならImages APIの`n`を使います。
- **プロンプトは書き換えられる。** 会話側のモデルがプロンプトを自動で調整するので、実際に使われた文は`revised_prompt`で確認できます。

### ツールで指定できる主なオプション

| パラメータ | 値 | メモ |
|---|---|---|
| `model` | `gpt-image-2.5-flare`、`gpt-image-2.5-sunburst`、`gpt-image-2`など | 既定は`gpt-image-1`なので必ず指定 |
| `action` | `auto`（既定）、`generate`、`edit` | 会話中に画像がないのに`edit`を強制するとエラー |
| `size` | `1024x1024`、`1536x1024`、`1024x1536`、`auto`、16の倍数の任意サイズ | 縦横比は1:3〜3:1、最大3840×2160。2560×1440を超えるサイズは試験的 |
| `quality` | `low`、`medium`、`high`、`auto`（既定） | GPT Image 2.5は`xhigh`、`max`も使える |
| `output_format` | `png`（既定）、`webp`、`jpeg` | `jpeg`はPNGより速い |
| `output_compression` | 0〜100 | `webp`と`jpeg`のとき |
| `background` | `auto`、`opaque`、`transparent` | 透過は`png`か`webp`で。`gpt-image-2`の透過はプレビュー扱い |
| `partial_images` | 0〜3 | ストリーミングで途中経過の画像を受け取る |
| `moderation` | `auto`（既定）、`low` | フィルタの強さ |
| `input_image_mask` | `file_id`または`image_url` | 編集範囲を指定するマスク |

`size`、`quality`、`output_format`、`output_compression`、`background`、`partial_images`、`moderation`はImages APIでも同じ名前で指定できます。`input_fidelity`はリファレンスに残っていますが、GPT Image 2.5での扱いは公開ドキュメントに明記がないため、2.5では渡さずに試すのが無難です。

## 会話の続きで画像を直す

Responses APIを選ぶいちばんの理由が、生成した画像を会話の流れで直していけることです。前の画像を引き継ぐ方法は2通りあります。

### previous_response_idでつなぐ

```python
followup = client.responses.create(
    model="gpt-6-astra",
    previous_response_id=response.id,
    input="背景を木のテーブルに変えて、朝の光にしてください",
    tools=[{"type": "image_generation", "model": "gpt-image-2.5-sunburst"}],
)
```

前の応答全体を文脈として引き継ぐ方法です。続きのリクエストでもツールの`model`を毎回書きます。この例では、細かい修正に向くSunburstに切り替えています。

### 画像のIDを入力に含める

```python
followup = client.responses.create(
    model="gpt-6-astra",
    input=[
        {"role": "user", "content": [
            {"type": "input_text", "text": "背景を木のテーブルに変えてください"},
        ]},
        {"type": "image_generation_call", "id": calls[0].id},
    ],
    tools=[{"type": "image_generation", "model": "gpt-image-2.5-sunburst"}],
)
```

前の応答のうち、画像だけを指定して引き継ぐ方法です。どちらの場合も、結果の取り出し方は最初のリクエストと同じです。

画像を直すのか新しく作るのかは、`action`で固定できます。既定の`auto`ではモデルが判断し、`"edit"`にすると会話中の画像の編集を、`"generate"`にすると新規生成を強制します。

続けて使う前に知っておきたい点が2つあります。

- **会話を重ねるほど入力トークンが増える。** `previous_response_id`を使っても、チェーン内の過去の入力トークンはすべて入力として課金されます。何往復も直す設計では、この分も費用に入れて見積もってください。
- **応答は既定で保存される。** Responses APIの応答は既定で保存され、アプリケーションの状態として30日間保持されます。保存したくない場合は`store: false`を指定します。

`referenced_image_ids`というパラメータ名を見かけることがありますが、2026年9月25日時点の画像生成ガイド、ツールのガイド、Responses APIリファレンスのいずれにもこの名前は出てきません。前の画像を参照するときは、上の`previous_response_id`か`image_generation_call`のIDを使ってください。

## GPT Image 2.5の料金：1024×1024でlow約$0.006、medium約$0.013

GPT Image 2.5の2モデルと`gpt-image-2`は、[OpenAIの料金ページ](https://developers.openai.com/api/docs/pricing#image-generation)で同じトークン単価です。

| 区分 | 100万トークンあたり |
|---|---|
| 画像出力 | $30 |
| 画像入力 | $8（キャッシュ時$2） |
| テキスト入力 | $5（キャッシュ時$1.25） |

単価が同じでも、1枚あたりのトークン数はモデルと品質で変わります。OpenAIの計算ツールによる、出力のみ・1024×1024の目安は次のとおりです（2026年9月25日時点）。

| モデル | low | medium | high |
|---|---|---|---|
| GPT Image 2.5 | $0.00588 | $0.01317 | $0.05268 |
| `gpt-image-2` | $0.00588 | $0.05268 | $0.21072 |

同じ`medium`でも、GPT Image 2.5は`gpt-image-2`よりかなり安く、2.5の`high`が`gpt-image-2`の`medium`と同じ額です。品質の名前だけで比べないようにしてください。2.5の`xhigh`は$0.09366、`max`は$0.21072です。

APIごとの違いは次の2点です。

- **Responses APIは会話側モデルの料金が加わる。** OpenAIのガイドは「Responses APIのリクエストには、画像生成の費用に加えて会話側モデルのトークン使用量が含まれる」と説明しています。料金ページには画像生成ツールの呼び出し1回あたりの料金は載っておらず、費用はトークンで計算されます。
- **途中経過の画像にも費用がかかる。** `partial_images`で受け取る途中画像は1枚につき画像出力トークンが100増えます。$30×100÷1,000,000で、1枚あたり$0.003です。

実際の消費はレスポンスの`usage`で確認できます。月の予算の立て方や1枚あたりの計算は「[GPT Image 2のAPI料金はいくら？1枚の目安と制作費の計算方法](/ja/posts/openai-image-generation-api-pricing)」を参照してください。

## OpenAI互換サービス経由で使う場合

基本はOpenAIのAPIを直接使う形で問題ありません。支払い方法や請求の単位を変えたいなどの理由で、OpenAI互換のサービスを検討する場合もあるでしょう。たとえばlaozhang.aiは、`https://api.laozhang.ai/v1`をbase URLとして`gpt-image-2.5-flare`と`gpt-image-2.5-sunburst`を呼び出すルートを[同社のドキュメント](https://docs.laozhang.ai/api-capabilities/gpt-image-2-5)で公開しており、トークン課金と1回ごとの課金を選べるとしています。

ただし、laozhang.aiはOpenAIそのものではありません。同社のドキュメントに記載されているのはImages API形式での生成と`/v1/images/edits`での編集で、Responses APIの`image_generation`ツールへの対応やSLAには触れていません。使うとしても、Images APIのルートに限った選択肢と考えてください。価格や仕様は提供元の最新のドキュメントで確認が必要です。

## よくある質問

### ChatGPTの有料プランでAPIの画像生成も使えますか？

ChatGPTの契約とAPIの課金は別の仕組みなので、ChatGPTのプランにAPIの利用料は含まれません。APIの画像生成はAPI側の従量課金で、1024×1024・出力のみの目安ではGPT Image 2.5の`low`が約$0.006、`medium`が約$0.013です（上の料金表を参照）。

### 画像をURLで受け取ることはできますか？

OpenAIのAPIでGPT Image系を使う限り、できません。常にbase64で返るので、自分でファイルに保存するか、ストレージにアップロードしてURLを発行します。60分で失効するURLが返っていたのはDALL·Eのころの仕様です。

### Responses APIで1回に4枚作れますか？

画像生成ツールには枚数を指定する`n`がなく、1回の応答で何枚返るかはドキュメントで保証されていません。決まった枚数が必要な処理は、Images APIで`n`を指定するのが確実です。

### gpt-image-1で書いたコードはいつまで動きますか？

`gpt-image-1`は2026年10月23日、`gpt-image-1.5`・`gpt-image-1-mini`・`chatgpt-image-latest`は2026年12月1日に停止します。Responses APIのツールで`model`を書いていないコードも`gpt-image-1`を使っているため、同じく2026年10月23日までに`gpt-image-2.5-flare`などを明示しておく必要があります。
