# OpenAI Image Generation API Endpoint: Which One to Use, and Why gen_id Isn't One

> Two live OpenAI image endpoints, /v1/images/generations and /v1/images/edits, on gpt-image-2.5. No endpoint takes a ChatGPT gen_id; here is where the image is.

- Source: https://www.aifreeapi.com/en/posts/openai-image-generation-api-endpoint
- Language: en
- Published: 2026-03-23
- Updated: 2026-10-09
- Publisher: AI Free API (https://www.aifreeapi.com)

Two different questions lead here, so both answers come first.

**If you are building with the OpenAI API**, the public Images API has exactly two live endpoints as of October 9, 2026: **`POST https://api.openai.com/v1/images/generations`** for an image from a prompt and **`POST https://api.openai.com/v1/images/edits`** for changing or extending images you already have. `POST /v1/images/variations` is retired. The third route, the **`image_generation` tool inside the Responses API**, is for conversations and multi-step flows where a text model decides when to draw. The current model IDs are `gpt-image-2.5-sunburst` (editing precision) and `gpt-image-2.5-flare` (fast everyday generation); `gpt-image-1` shuts down on October 23, 2026 and `gpt-image-1.5` on December 1, 2026.

**If what you have is a ChatGPT `gen_id`** (or `parent_gen_id`, `referenced_image_ids`, or a `file-service://` `asset_pointer`) and you are looking for the endpoint that downloads or retrieves that image: there is none. Those are fields of ChatGPT's internal `image_gen` tool, no public API endpoint accepts them, and the API itself never hands out an id you could fetch bytes with later, because GPT Image models return every image inline as base64. The image you want is in one of three places: the ChatGPT conversation or Library (download button), a ChatGPT data export, or a fresh API generation that you store yourself. The [gen_id section](#chatgpt-gen_id-download-or-retrieve-endpoint-there-is-none) below walks through each.

![Route map showing when to use OpenAI's direct Images API endpoints and when to switch to the Responses image_generation tool.](https://www.aifreeapi.com/posts/en/openai-image-generation-api-endpoint/img/cover.webp)

## Which OpenAI image endpoint to call: the current map

![Routing board comparing direct OpenAI image endpoints with the Responses image_generation tool and showing the Images API as the default start.](https://www.aifreeapi.com/posts/en/openai-image-generation-api-endpoint/img/route-choice-matrix.webp)

The [image generation guide](https://developers.openai.com/api/docs/guides/image-generation) describes "two main ways" to generate or edit images and recommends the Image API when you only need a single image from one prompt. The [Images API reference](https://developers.openai.com/api/reference/resources/images) lists the raw endpoints. Put together, the routing looks like this:

| Job | Route | Raw path or SDK call | What goes in `model` | Pick it when... | Mistake to avoid |
| --- | --- | --- | --- | --- | --- |
| Generate one image from a prompt | Images API | `POST https://api.openai.com/v1/images/generations`, `client.images.generate()` | `gpt-image-2.5-sunburst` or `gpt-image-2.5-flare` (required, no default) | You want the shortest path to a working request | Leaving `model` empty, or sending a retired id such as `dall-e-3` |
| Edit, combine or extend images you already have | Images API | `POST https://api.openai.com/v1/images/edits`, `client.images.edit()` | Same two IDs; `gpt-image-2.5-sunburst` is the default here | You have input images, up to 16 for GPT Image models, optionally a `mask` | Looking for `/v1/images/variations`; it is retired, edits with a prompt replaces it |
| Generate images inside a conversation or agent flow | Responses API with the `image_generation` tool | `client.responses.create()` with `tools: [{ type: "image_generation", model: "gpt-image-2.5-sunburst" }]` | Top level: a current mainline text model (gpt-5 family or newer per the guide); image model goes in the tool object | The same request may return text and images, or edits chain across turns | Putting `gpt-image-2.5-sunburst` in the top-level `model` field |
| Fetch an image generated earlier by its id | None | — | — | — | Expecting a `GET /v1/images/{id}`; the reference has no retrieval endpoint, and ChatGPT's `gen_id` is not an API id |

The last row is the common surprise. Both API routes return the image **inline**, so storing the bytes is your job and happens at the moment of the response. The next section covers what that means when the image was made in ChatGPT instead of through your own code.

## ChatGPT gen_id download or retrieve endpoint: there is none

No public endpoint accepts a `gen_id` and returns an image, not under `https://api.openai.com/v1/images/...`, not in the Responses API, and not anywhere else in the [API reference](https://developers.openai.com/api/reference/resources/images). That is not a missing docs page. It follows from how the two systems work:

- **`gen_id` is a ChatGPT product field, not an API field.** When ChatGPT draws, it calls an internal tool named `image_gen`. The tool call carries metadata such as `gen_id`, `parent_gen_id` (the generation this one was edited from) and `referenced_image_ids` (images the new generation should use as references). In Reddit threads from late 2023 and 2024, the DALL·E 3 era, users asked ChatGPT for an image's `gen_id` and pasted it into later prompts for consistency, which is why the field feels like an identifier you should be able to call. It only has meaning inside ChatGPT.
- **The API never issues a fetchable id either.** On `/v1/images/generations` and `/v1/images/edits`, GPT Image models return the image as `data[].b64_json`; the `url` response format is "Unsupported for GPT image models, which always return base64-encoded images" ([reference](https://developers.openai.com/api/reference/resources/images)). There is nothing to retrieve later because the bytes were already in the response.
- **Asset pointers are storage internals.** Third-party write-ups of ChatGPT exports describe images stored behind `file-service://file-...` asset pointers, with `gen_id` as metadata next to them, and image links on `backend-api` / `files.oaiusercontent.com` as temporary signed URLs that return 422 when query fields are dropped and 404 once they expire. OpenAI does not document any of this, so treat it as a description of behavior, not a contract.

Here is where the image actually is on each surface, and what you can do from there:

| Surface | Where the image bytes are | What identifier exists | What you can do with it |
| --- | --- | --- | --- |
| ChatGPT conversation and Library (web, desktop, mobile) | Rendered in the chat; served through links that expire (reports) | `gen_id`, `parent_gen_id`, `referenced_image_ids`, `asset_pointer` inside the `image_gen` call | Download from the UI; reference it in the same chat; nothing callable from code |
| ChatGPT data export ZIP | Reports: image files in the archive, matched by the `file-...` id in `conversations.json` (`image_asset_pointer`); the help page itself only promises "chat history and other relevant account data" | Same ids as above, now in JSON you can parse offline | Match pointers to files with a script; one-time bulk recovery |
| Images API response (`/v1/images/generations`, `/v1/images/edits`) | Inline, `data[].b64_json` | None you can query later; `created` timestamp and `usage` counters only | Decode, store, and assign your own id at response time |
| Responses API output | Inline, `result` (base64) on an `image_generation_call` item | The item `id` (`ig_...`) and the response id | Chain edits with `previous_response_id`; still store the bytes yourself |

### Download it from the ChatGPT conversation or Library

If the chat still exists, this is the ordinary route: open the conversation or the Library view, select the image, and use the download control. That is the supported way to get a single ChatGPT-generated image out of ChatGPT. Copying the image URL out of the browser's network panel is not a substitute; those links are the expiring signed URLs described above, and nothing you can store will keep working.

### Pull it from a ChatGPT data export

For many images, or when the chat is hard to find, request a data export. Per the [help center](https://help.openai.com/en/articles/7260999-exporting-your-chatgpt-history-and-data): Settings → Data controls → Export data (or the Privacy Portal); available on Free, Go, Plus, Pro and eligible Edu accounts but not Business, Enterprise or Healthcare workspaces; the export "can take up to 7 days"; the download link expires 24 hours after you receive it; deleted chats cannot be restored. OpenAI's text says the ZIP "includes your chat history and other relevant account data" and does not list image files explicitly. Third-party accounts of real exports report that `conversations.json` contains `image_asset_pointer` entries whose `file-...` id matches asset files shipped in the archive, which is what makes a bulk recovery script possible. Plan for that but verify against your own archive, since the official page does not promise it.

### Regenerate through the API and store the bytes yourself

If the image is gone, or you wanted a programmatic pipeline in the first place, the fix is not to find a hidden endpoint but to move the work to the API, where storage is explicit. A minimal Node example that generates one image and keeps it under an id you control:

```js
import fs from "node:fs/promises";
import { randomUUID } from "node:crypto";
import OpenAI from "openai";

const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

const result = await client.images.generate({
  model: "gpt-image-2.5-flare",
  prompt: "A flat-color icon of a paper airplane on a white background",
  size: "1024x1024",
  quality: "medium",
  output_format: "webp",
});

// The API gives you bytes, not a retrievable id. Assign your own.
const imageId = `img_${result.created}_${randomUUID()}`;
await fs.writeFile(`./images/${imageId}.webp`, Buffer.from(result.data[0].b64_json, "base64"));
console.log(imageId, result.usage); // keep prompt + usage next to the file for later edits
```

Store the prompt and the file together; that pair is what lets you do later the thing `referenced_image_ids` does in ChatGPT.

## `backend-api` gen_id endpoints are ChatGPT's private interface, not an API

The `backend-api` paths that show up in a browser's network panel next to a ChatGPT image, and in `gen_id` discussions, are the paths the ChatGPT web client calls behind the scenes. They are not part of the OpenAI API, are not documented, and are not covered by API keys, terms or stability guarantees; they change without notice, and their image links are the short-lived signed URLs described above. Nothing built on them can be relied on, which is why there is no "backend-api gen_id endpoint" to recommend. The supported equivalents are the three routes above: UI download, data export, or the public API.

## referenced_image_ids, parent_gen_id and gen_id mapped to API fields

If you went looking for `referenced_image_ids` image editing docs in the OpenAI API documentation, there is no page to find: `referenced_image_ids` is a ChatGPT tool field, not an API parameter. The capability exists in the API under different names. Use this mapping to translate a ChatGPT workflow into API calls:

| ChatGPT field or name | What it means inside ChatGPT | Closest API mechanism |
| --- | --- | --- |
| `gen_id` | Identifier of one generated image within the `image_gen` tool call | Responses API: the `id` on the `image_generation_call` output item (placeholder `ig_123` in the docs). Images API: none; assign your own at response time |
| `parent_gen_id` | The generation the current image was edited from (a chain of edits) | `previous_response_id` on the next `responses.create` call, or pass the earlier `image_generation_call` item (`{"type":"image_generation_call","id": ...}`) as an input item |
| `referenced_image_ids` (also written `reference_image_ids`) | Earlier images the tool should use as references for a new picture | `POST /v1/images/edits` with those images in `image` (up to 16, as base64 or file IDs, optional `mask`); or Responses multi-turn with the image already in context and `action: "edit"` |
| `asset_pointer` (`file-service://file-...`) | Internal storage pointer to the file | The bytes themselves: `data[].b64_json` (Images API) or `result` (Responses) that you store |
| `image_gen` | ChatGPT's internal tool name | Tool type `image_generation` in Responses; the two Images API endpoints for direct calls |
| `backend-api` | Private web client interface | Public endpoints under `https://api.openai.com/v1/` |

Two documentation pages hold everything on the right-hand side: the [Images API reference](https://developers.openai.com/api/reference/resources/images) for `/v1/images/edits` parameters and the [image generation tool guide](https://developers.openai.com/api/docs/guides/tools-image-generation) for `previous_response_id`, `action` and the `image_generation_call` item. If you were hoping for "ChatGPT API" image editing, [ChatGPT API Generate Image: Use OpenAI Images API](/en/posts/chatgpt-api-generate-image) explains why that product does not exist as a separate endpoint.

## Start with `POST /v1/images/generations` for one-shot image output

For a fresh integration this is the right first proof that the key, project and payload shape work. The [Images API reference](https://developers.openai.com/api/reference/resources/images) lists `POST /images/generations`, which you call as **`https://api.openai.com/v1/images/generations`** from your backend. The reference says to specify a model explicitly; there is no default on this endpoint. As of October 9, 2026 the guide names two current models: `gpt-image-2.5-sunburst` when editing precision matters most and `gpt-image-2.5-flare` for fast everyday generation.

```bash
curl https://api.openai.com/v1/images/generations \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2.5-sunburst",
    "prompt": "Clean editorial illustration of a robot camera operator in a bright studio",
    "size": "1024x1024",
    "quality": "medium",
    "output_format": "png"
  }'
```

Parameters that matter on the first call, per the reference: `size` is `auto`, `1024x1024`, `1536x1024` or `1024x1536` (the gpt-image-2 family also accepts a free `WIDTHxHEIGHT`); `quality` is `low`, `medium`, `high` or `auto`, with `xhigh` and `max` only on the gpt-image-2.5 models; `output_format` is `png` (default), `jpeg` or `webp`, with `output_compression` 0–100 for the latter two; `background: "transparent"` needs png or webp; `n` is 1–10; `partial_images` 0–3 with `stream`; `moderation` is `auto` or `low`; the prompt can be up to 32,000 characters. GPT Image models do not return `revised_prompt` on this endpoint.

The response carries `data[].b64_json`, plus `usage` (`input_tokens`, `output_tokens`, `input_tokens_details.image_tokens` / `text_tokens`, `total_tokens`) and the resolved `background`, `output_format`, `quality` and `size`. A successful first test therefore means more than a 200: your code decoded the base64 and wrote a file you can open. Copy-ready request bodies for both endpoints are in [OpenAI Image Generation API cURL: Current Generate and Edit Requests](/en/posts/openai-image-generation-api-curl); the same calls in Python and JavaScript are in [OpenAI Image Generation API Example: Current JavaScript, Python, and cURL](/en/posts/openai-image-generation-api-example).

## Use `POST /v1/images/edits` when you already have source images

![Direct Images API board showing that edits, fidelity, transparency, format, compression, size, and quality stay on the same endpoint family.](https://www.aifreeapi.com/posts/en/openai-image-generation-api-endpoint/img/output-controls-cheatsheet.webp)

Many jobs that start as "generate an image" turn out to be edit jobs: a product shot to restage, a reference character to keep consistent, a canvas to extend. That stays on the direct Images API, on the edit branch. The [reference](https://developers.openai.com/api/reference/resources/images) lists `POST /images/edits` with `gpt-image-2.5-sunburst` as the default model, up to 16 input images for GPT Image models, an optional `mask` given as `image_url` or `file_id`, and input images supplied as file IDs or base64.

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

const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

const result = await client.images.edit({
  model: "gpt-image-2.5-sunburst",
  image: [fs.createReadStream("product-shot.png"), fs.createReadStream("shelf-reference.png")],
  prompt: "Keep the product shape and label; place it on the shelf from the second image with warm lighting",
  input_fidelity: "high",
});
```

Three details from the reference and guide decide whether this request behaves:

- `input_fidelity` is `high` or `low`; `gpt-image-1-mini` only supports `low`, and for `gpt-image-2` you should omit it, because that model always runs at high fidelity (and reference-image edits may therefore use more input tokens).
- `gpt-image-2` sizes are bounded: longest edge 3,840 px, both edges multiples of 16, aspect ratio no wider than 3:1, total pixels between 655,360 and 8,294,400. The guide excerpt does not restate these for the 2.5 models, so check the model page before relying on them there.
- Variations are gone. If an old snippet calls `/v1/images/variations`, the reference now says "This endpoint is retired and no longer available"; send the source image to edits with a prompt describing the variation you want.

In ChatGPT terms, the `image` array is your `referenced_image_ids`. For the fidelity-versus-cost question and multi-image compositing patterns, see [OpenAI Image Editing API: GPT Image 2 Edits and Variations](/en/posts/openai-image-editing-api).

## Only move to Responses when image generation is one part of a larger flow

Responses is the right route when the image step is not the whole product: a model reads instructions, maybe inspects context or calls other tools, and sometimes draws. The [image generation tool guide](https://developers.openai.com/api/docs/guides/tools-image-generation) adds `{"type": "image_generation", "model": "gpt-image-2.5-sunburst"}` to `tools`, and the top-level `model` is a mainline text model. The guide says the tool requires "gpt-5 or a newer model"; the tool page lists a wider set of mainline models, so use a current gpt-5-or-newer model and confirm support on its model page rather than assuming an older one works.

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

const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

const first = await client.responses.create({
  model: "gpt-5.5", // mainline text model; the image model lives in the tool object
  input: "Draw a sticker-style icon of a paper airplane for a travel app",
  tools: [{ type: "image_generation", model: "gpt-image-2.5-sunburst" }],
});

const call = first.output.find((item) => item.type === "image_generation_call");
await fs.writeFile("airplane.png", Buffer.from(call.result, "base64"));
console.log(call.id); // ig_... — the only API-side "generation id"

// Edit in the next turn: this is what parent_gen_id does in ChatGPT
const second = await client.responses.create({
  model: "gpt-5.5",
  previous_response_id: first.id,
  input: "Same icon, but make the airplane red and add motion lines",
  tools: [{ type: "image_generation", model: "gpt-image-2.5-sunburst", action: "edit" }],
});
```

What the tool gives you that the direct endpoints do not: a `revised_prompt` on the output item, `action` (`auto` / `generate` / `edit`; `edit` with no image in context errors), streaming of 1–3 `partial_images` through `response.image_generation_call.partial_image` events, `tool_choice: {"type": "image_generation"}` to force a draw, and the `ig_` item id you can pass back as an input item instead of `previous_response_id`. What it costs you: the mainline model's tokens are billed on top of the image tokens, and debugging goes through tool output parsing. If orchestration is not the job yet, the direct endpoints remain the better first move; the broader walkthrough is [OpenAI Image API Tutorial: Images API vs Responses API](/en/posts/openai-image-api-tutorial).

## Model IDs to use now, and the gpt-image-1 and gpt-image-1.5 shutdown dates

The reference's model enum still lists every id the endpoints have ever accepted, including ones that no longer run, so "it's in the enum" is not the same as "it works." The [deprecations page](https://developers.openai.com/api/docs/deprecations), as of October 9, 2026:

| Model ID | Status | Shutdown date | Recommended replacement |
| --- | --- | --- | --- |
| `gpt-image-2.5-sunburst`, `gpt-image-2.5-flare` (and `-2026-09-08` snapshots) | Current | — | — |
| `gpt-image-2` (`gpt-image-2-2026-04-21`) | Available, not listed as deprecated | — | — |
| `gpt-image-1` | Deprecated (announced April 22, 2026) | October 23, 2026 | `gpt-image-2.5-sunburst` or `gpt-image-2.5-flare` |
| `gpt-image-1.5`, `gpt-image-1-mini`, `chatgpt-image-latest` | Deprecated (announced June 2, 2026) | December 1, 2026 | `gpt-image-2.5-sunburst` or `gpt-image-2.5-flare` |
| `dall-e-2`, `dall-e-3` | Shut down | May 12, 2026 | gpt-image family |

Two notes on that table. `chatgpt-image-latest` is described on its [model page](https://developers.openai.com/api/docs/models/chatgpt-image-latest) as the "Previous image model used in ChatGPT", and the page recommends GPT-Image-2.5 Sunburst for API use; if you were choosing it to match what ChatGPT draws, it no longer does that, and it stops on December 1, 2026 anyway. And earlier GPT Image models cap `quality` at `high`; `xhigh` and `max` exist only on the 2.5 models, so a payload tuned for 2.5 can fail on an older id for a reason that has nothing to do with the endpoint.

When a correct endpoint still returns an error, check in this order before touching the URL:

1. **Model id**: retired (`dall-e-3`), about to retire (`gpt-image-1`), or placed on the wrong surface (an image model in the top-level Responses `model`).
2. **`moderation_blocked`**: the error code for refused content, with `moderation_details.categories` and `moderation_stage` (`input` or `output`). Rewording the prompt fixes this; switching endpoints does not.
3. **Parameters the model does not accept**: `xhigh` / `max` on a pre-2.5 model, `input_fidelity` on `gpt-image-2`, a free-form size on a model that only takes the fixed set.
4. **Account state**: if the error text is about organization verification, see [Fix GPT Image 2's 'Your organization must be verified' Error](/en/posts/openai-image-generation-api-verification).

Model-by-model trade-offs are in [OpenAI Image Generation API Models: Which One Should You Use in 2026?](/en/posts/openai-image-generation-api-models); if the failure is on the ChatGPT side rather than the API, [ChatGPT Image Generation Not Working? Check Status, Fix the Right Branch, and Stop Wasting Retries](/en/posts/chat-gpt-image-generator-not-working) covers that branch.

## GPT Image 2.5 cost per call: token rates, not a flat price

Both routes bill the same image tokens, but the totals differ. Per the [image generation guide](https://developers.openai.com/api/docs/guides/image-generation), GPT Image 2.5 is priced at $8 per million image input tokens, $2 per million cached image input tokens, $30 per million image output tokens, $5 per million text input tokens and $1.25 per million cached text input tokens, and the guide warns that "Equal token rates don't mean equal cost per image." Three consequences for endpoint choice:

- **Cached input pricing applies only through the Responses tool.** A direct `/v1/images/edits` call that re-sends the same reference images pays full input price every time; a Responses conversation that carries the image in context can hit the cached rate. Responses also bills the mainline model's tokens, so it is not automatically cheaper.
- **Output tokens scale with quality.** The guide gives 272, 1,056 and 4,160 output tokens for a 1024×1024 image at `low`, `medium` and `high` on earlier GPT Image models; those are the earlier models' figures, so measure `usage.output_tokens` on your own 2.5 calls before budgeting.
- **Streaming adds cost.** Each `partial_images` frame adds 100 output tokens.

For a fixed per-image reference point while it lasts, `chatgpt-image-latest` lists $0.009 (low), $0.034 (medium) and $0.133 (high) per 1024×1024 image on its [model page](https://developers.openai.com/api/docs/models/chatgpt-image-latest), but it shuts down on December 1, 2026. Per-image budgeting for the current models, with worked examples, is in [GPT Image 2 API Pricing: Cost per Image and Project Budget](/en/posts/openai-image-generation-api-pricing).

## FAQ: gen_id, referenced_image_ids and endpoint errors

**Can I download a ChatGPT image through the OpenAI API if I have its gen_id?**

No. `gen_id` belongs to ChatGPT's internal `image_gen` tool, and no public endpoint accepts it. The API also never returns an id you could fetch bytes with later; `/v1/images/generations` and `/v1/images/edits` return the image inline as `b64_json`. Download the image from the ChatGPT conversation or Library, request a data export, or regenerate it through the API and store the result yourself.

**Where are the referenced_image_ids image editing docs?**

There is no API documentation page for `referenced_image_ids` because it is not an API parameter. The equivalent is the `image` array on `POST /v1/images/edits` (up to 16 images, base64 or file IDs, optional mask), documented in the [Images API reference](https://developers.openai.com/api/reference/resources/images), or a Responses multi-turn edit with `previous_response_id`, documented in the [image generation tool guide](https://developers.openai.com/api/docs/guides/tools-image-generation).

**Does parent_gen_id have an API equivalent?**

Yes, in the Responses API: pass `previous_response_id` from the response that produced the image, or include the earlier `image_generation_call` item id as an input item, and set the tool's `action` to `edit`. On the direct Images API the chain is yours to keep: store each output with your own id and send it back as an input image for the next edit.

**Do I need Responses for ordinary image editing?**

No. `POST /v1/images/edits` with `gpt-image-2.5-sunburst` (the default there) handles edits, multi-image composites and masked changes directly. Responses is the better fit only when the image step sits inside a conversation or agent flow.

**Should I still send gpt-image-1 or gpt-image-1.5?**

Only until their shutdown dates. The deprecations page lists `gpt-image-1` for October 23, 2026 and `gpt-image-1.5`, `gpt-image-1-mini` and `chatgpt-image-latest` for December 1, 2026, with `gpt-image-2.5-sunburst` or `gpt-image-2.5-flare` as the replacement. Switch the `model` string now; the endpoints and request shape stay the same.

**Why can a correct endpoint still fail?**

Because the model id, the parameters and the content are checked separately from the path. A retired id, `xhigh` on a pre-2.5 model, `input_fidelity` on `gpt-image-2`, or a `moderation_blocked` refusal all fail on a perfectly correct `https://api.openai.com/v1/images/generations` call. Fix the payload or prompt; changing endpoints is rarely the answer.
