# GPT Image 2 on SeedRouter

> Generate images, edit references, and apply masks through one asynchronous image endpoint.

Model ID: `gpt-image-2-official`, `gpt-image-2`. [Playground and pricing](https://seedrouter.ai/models/gpt-image-2).
Use an API key from https://seedrouter.ai/apikeys as Authorization: Bearer $SEEDROUTER_API_KEY. Store the key on your server.

## Current pricing and worked estimates

Rates use the same source and one-minute refresh interval as the model page. All amounts are in USD.

GPT Image 2 is sold on 2 channels. Every model ID in a channel has the same price, and all IDs accept the same parameters; pick the ID whose billing suits the request.

| Channel | Model IDs | Billed by | Current rate (USD) |
| --- | --- | --- | --- |
| Official | `gpt-image-2-official` | Tokens each render reports (text input + image output) | $3.75 per 1M input tokens; $22.5 per 1M output tokens |
| Standard | `gpt-image-2` | Flat price per delivered image, at any size or quality | $0.0315 per delivered image |

Token rates are the published first-tier rates; usage in a different tier may be charged differently.

### Cost of one 1024x1024 image by quality

Token counts are measured samples on the Official channel, with 18 input tokens for the prompt. Actual usage varies with the prompt, dimensions, references, and image count, so token-billed figures are estimates, not fixed prices. Flat-priced channels charge the same at every quality.

| Quality | Sample output tokens | Official USD | Standard USD |
| --- | --- | --- | --- |
| low | 196 | $0.0044775 | $0.0315 |
| medium | 1756 | $0.0395775 | $0.0315 |
| high | 7024 | $0.1581075 | $0.0315 |
| auto | 186 | $0.0042525 | $0.0315 |

Formula (Official): (input tokens × 3.75 + output tokens × 22.5) / 1,000,000 USD.
A request for n images is billed for the images delivered. Final charges are available in account usage history. Failed requests are not charged.

## API reference

GPT Image 2 accepts a text prompt and optional reference images. Submit once, keep the returned task ID, and check that task for the finished images. It is sold on two channels, each with its own model ID; both read the same parameters.

## Model IDs

| Model ID               | Channel  | Billing                                                      |
| ---------------------- | -------- | ------------------------------------------------------------ |
| `gpt-image-2`          | Standard | One flat price per delivered image, at any size or quality   |
| `gpt-image-2-official` | Official | The tokens each render reports (text input and image output) |

Both IDs accept the same parameters and support every mode; only billing differs. See the [model page](https://seedrouter.ai/models/gpt-image-2#pricing) for current prices. The examples below use `gpt-image-2`; replace it with `gpt-image-2-official` to bill by tokens.

## Quick example

```bash
curl https://api.seedrouter.ai/v1/images/generations \
  -H "Authorization: Bearer $SEEDROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "An amber glass bottle on a cream background, studio lighting",
    "size": "1024x1024",
    "quality": "low"
  }'
```

```python
import os
import requests

response = requests.post(
    "https://api.seedrouter.ai/v1/images/generations",
    headers={"Authorization": f"Bearer {os.environ['SEEDROUTER_API_KEY']}"},
    json={
        "model": "gpt-image-2",
        "prompt": "An amber glass bottle on a cream background, studio lighting",
        "size": "1024x1024",
        "quality": "low",
    },
    timeout=60,
)
response.raise_for_status()
task_id = response.json()["id"]
```

```javascript
const response = await fetch('https://api.seedrouter.ai/v1/images/generations', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.SEEDROUTER_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'gpt-image-2',
    prompt: 'An amber glass bottle on a cream background, studio lighting',
    size: '1024x1024',
    quality: 'low',
  }),
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const { id: taskId } = await response.json();
```

```go
package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "os"
    "strings"
    "time"
)

func main() {
    body := strings.NewReader(`{
      "model": "gpt-image-2",
      "prompt": "An amber glass bottle on a cream background, studio lighting",
      "size": "1024x1024",
      "quality": "low"
    }`)
    req, err := http.NewRequest("POST", "https://api.seedrouter.ai/v1/images/generations", body)
    if err != nil { panic(err) }
    req.Header.Set("Authorization", "Bearer " + os.Getenv("SEEDROUTER_API_KEY"))
    req.Header.Set("Content-Type", "application/json")
    client := &http.Client{Timeout: 60 * time.Second}
    res, err := client.Do(req)
    if err != nil { panic(err) }
    defer res.Body.Close()
    if res.StatusCode != http.StatusOK { panic(res.Status) }
    var task struct { ID string `json:"id"` }
    if err := json.NewDecoder(res.Body).Decode(&task); err != nil { panic(err) }
    fmt.Println(task.ID)
}
```

## Endpoint

```text
POST https://api.seedrouter.ai/v1/images/generations
```

| Header        | Value                 |
| ------------- | --------------------- |
| Authorization | `Bearer YOUR_API_KEY` |
| Content-Type  | `application/json`    |

The same endpoint handles generation, reference edits, and masked edits. The response contains a task ID, not the finished image. Keep API keys in server-side code.

## Parameters

| Name                 | Type      | Required | Default        | Notes                                                                                |
| -------------------- | --------- | -------- | -------------- | ------------------------------------------------------------------------------------ |
| `model`              | string    | Yes      | —              | `gpt-image-2` or `gpt-image-2-official`                                              |
| `prompt`             | string    | Yes      | —              | Nonblank; up to 32,000 characters.                                                   |
| `images`             | object\[] | No       | —              | 1–16 objects shaped as `{"image_url":"https://..."}`; adding images selects editing. |
| `mask`               | object    | No       | —              | `{"image_url":"https://..."}`; requires `images`.                                    |
| `size`               | string    | No       | `auto`         | `auto` or `WIDTHxHEIGHT`, subject to the rules below.                                |
| `quality`            | enum      | No       | `auto`         | `auto`, `low`, `medium`, `high`.                                                     |
| `background`         | enum      | No       | `auto`         | `auto`, `opaque`, `transparent`.                                                     |
| `output_format`      | enum      | No       | `png`          | `png`, `jpeg`.                                                                       |
| `output_compression` | integer   | No       | `100` for JPEG | 0–100; send only with `jpeg`. Zero is valid.                                         |
| `n`                  | integer   | No       | `1`            | 1–10 images.                                                                         |
| `moderation`         | enum      | No       | `auto`         | `auto`, `low`.                                                                       |
| `user`               | string    | No       | —              | Optional application end-user identifier. Avoid personal information.                |

### Size rules

Common choices are `1024x1024`, `1536x1024`, and `1024x1536`. Custom dimensions must satisfy every rule:

* Width and height are multiples of 16.
* Neither edge exceeds 3840 pixels.
* The aspect ratio is between 1:3 and 3:1.
* Total area is between 655,360 and 8,294,400 pixels, inclusive.

`auto` leaves the output dimensions to the model. Do not send aspect ratios such as `16:9` as `size`.

The Playground offers Auto, Ratio and Custom controls. Ratio mode combines an aspect ratio with a 1K, 2K or 4K pixel-budget preset, then sends only the resulting `size`. These are UI presets, not separate API parameters: do not send `resolution` or `aspect_ratio`. For example, 16:9 + 4K sends `size: "3840x2160"`; 9:16 + 4K sends `"2160x3840"`; 1:1 + 2K sends `"2048x2048"`. Rounding and the edge limit can reduce the pixel count for a selected tier. The exact dimensions are shown before submission.

OpenAI describes resolutions above 2560×1440 as experimental. They are accepted within the limits above; higher resolution is not a guarantee of better detail.

### Quality tiers

Use `low` for drafts and compare results before choosing a higher tier. `auto` lets the model choose; it does not guarantee a particular tier or cost.

### Transparent backgrounds

Transparency is in preview for GPT Image 2. For a transparent background, set `background: "transparent"` and use PNG. JPEG does not support transparency. Compression applies only to JPEG.

`user` is available for API integrations but is not shown or automatically populated in the Playground.

Optional scalar settings (`n`, `size`, `quality`, `background`, `output_format`, `output_compression`, `moderation`) accept `null` as omission. Unknown fields are rejected. `input_fidelity` is not configurable for GPT Image 2; reference inputs always use high fidelity. `style` and `response_format` belong to other image models and are not accepted here.

## Modes

There is no separate mode parameter or editing endpoint to choose.

| Operation      | Parameters                   |
| -------------- | ---------------------------- |
| Text to image  | `prompt`                     |
| Reference edit | `prompt` + `images`          |
| Masked edit    | `prompt` + `images` + `mask` |

### Edit reference images

```bash
curl https://api.seedrouter.ai/v1/images/generations \
  -H "Authorization: Bearer $SEEDROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "Make the bottle blue. Preserve the composition and lighting.",
    "images": [{"image_url": "https://example.com/reference.png"}],
    "mask": {"image_url": "https://example.com/mask.png"},
    "output_format": "jpeg",
    "output_compression": 90
  }'
```

Replace both example URLs with your own accessible images. Omit `mask` for a reference edit without a selected region.

## Media inputs

This API accepts URL references only. OpenAI Files IDs, base64 data URLs, and multipart uploads are not accepted. The Playground uploads selected files to storage before submitting their URLs.

Reference images must be public HTTP(S) URLs pointing to PNG, JPEG, or WebP files smaller than 50 MB each. A mask must be a PNG smaller than 4 MB, with the same dimensions as the first reference image; its transparent area marks what to edit. A mask guides the model and does not guarantee pixel-perfect boundaries. For multiple references, the mask applies to the first image. URL media is validated during processing; invalid or inaccessible media can produce a failed task.

The Playground uploads selected files and submits their URLs. API requests use JSON URL objects: do not send file bytes, base64, `data:` URLs, `blob:` URLs, or multipart form data.

## Pricing dimensions

Check the [model pricing section](https://seedrouter.ai/models/gpt-image-2#pricing) for current rates. `gpt-image-2` (Standard) charges one flat price per delivered image, whatever the quality, size, or prompt. On `gpt-image-2-official` (Official), the final cost depends on input and output usage: quality, output dimensions, reference images, prompt length, and image count can all affect it.

The Playground estimate uses a measured sample and current rates; it is not a guaranteed quote. View final charges in your account usage history. Failed tasks are not charged.

## Output schema

Submission returns a task reference:

```json
{
  "id": "task_...",
  "model": "gpt-image-2",
  "status": "processing",
  "created_at": 1789970508
}
```

### Poll the task

```bash
curl https://api.seedrouter.ai/v1/tasks/YOUR_TASK_ID \
  -H "Authorization: Bearer $SEEDROUTER_API_KEY"
```

Poll at a modest interval, such as every three seconds, until `status` is `completed` or `failed`. A network timeout while polling does not mean generation failed: keep the task ID and resume checking it. Do not create another task to check progress.

### Complete polling example

Run this after the Python submission example above. It uses the returned `task_id` and waits up to ten minutes. Reaching this local deadline stops polling only; retain the ID and resume querying the same task.

```python
import time

print(f"Task ID: {task_id}")
deadline = time.monotonic() + 600
while time.monotonic() < deadline:
    result = requests.get(
        f"https://api.seedrouter.ai/v1/tasks/{task_id}",
        headers={"Authorization": f"Bearer {os.environ['SEEDROUTER_API_KEY']}"},
        timeout=30,
    )
    result.raise_for_status()
    task = result.json()
    if task["status"] == "completed":
        for image in task["output"]["data"]:
            print(image["url"])
        break
    if task["status"] == "failed":
        raise RuntimeError(task["error"]["message"])
    time.sleep(3)
else:
    raise TimeoutError(f"Still waiting. Resume polling task {task_id}.")
```

### Completed task

A completed task returns hosted image URLs and usage:

```json
{
  "id": "task_...",
  "model": "gpt-image-2",
  "status": "completed",
  "created_at": 1789970508,
  "finished_at": 1789970538,
  "output": {
    "created": 1789970532,
    "data": [{"url": "https://static.seedrouter.ai/media/tasks/task_example/0.png"}],
    "usage": {
      "input_tokens": 29,
      "output_tokens": 196,
      "total_tokens": 225
    }
  }
}
```

| Field                       | Meaning                                                                                       |
| --------------------------- | --------------------------------------------------------------------------------------------- |
| `id`                        | Keep this ID for subsequent queries.                                                          |
| `status`                    | `processing`, `completed`, or `failed`.                                                       |
| `created_at`, `finished_at` | Unix timestamps in seconds; completion time is unset or zero while processing.                |
| `output.data[].url`         | Generated image URLs, available on completion.                                                |
| `output.size`               | Actual output dimensions, when reported.                                                      |
| `output.quality`            | Actual quality tier, when reported.                                                           |
| `output.background`         | Actual background, when reported.                                                             |
| `output.output_format`      | Actual image format, when reported.                                                           |
| `output.usage`              | Reported token usage, when available. Detail objects may contain text and image token counts. |
| `error`                     | Structured error on a failed task.                                                            |

This API uses asynchronous task delivery. It is not a synchronous Images SDK replacement; `stream` and `partial_images` are not supported.

## Errors

Requests rejected before a task is created return an HTTP error with an `error` object. A task that fails after acceptance returns HTTP 200 when queried, with `status: "failed"` and an `error` object.

See the [shared error catalog](https://seedrouter.ai/docs/api/errors) for codes, HTTP statuses, and retry guidance. All model APIs use the same error envelope.

```json
{
  "id": "task_...",
  "status": "failed",
  "error": {
    "code": 60002,
    "message": "Generation could not be completed. Please try again."
  }
}
```

If submission itself times out, check your task history before submitting again: the first request may have been accepted.

## Tips

* Describe materials, composition, and lighting in the prompt.
* For an edit, specify both the change and what should remain unchanged.
* Use a mask when only a selected area should change.
* Save returned images to your own storage when you need a durable copy.

## Related

* [GPT Image 2 Playground and pricing](https://seedrouter.ai/models/gpt-image-2)
* [Download OpenAPI](https://seedrouter.ai/docs/gpt-image-2.openapi.json)
* [Copyable Markdown](https://seedrouter.ai/docs/gpt-image-2.md)

## More resources

- [Claude Fable 5, Fable 5.1 and Opus 5.5 API pricing: cost per million tokens](https://seedrouter.ai/blog/claude-api-pricing.md): Claude Fable 5.1, Fable 5 and Opus 5.5 API pricing per million tokens: input, output and prompt-cache rates, how a request is billed, and API vs Claude plans. (HTML: https://seedrouter.ai/blog/claude-api-pricing)
- [How to use the Claude Fable 5.1 API: model ID, API key and your first request](https://seedrouter.ai/blog/claude-fable-5-1-api.md): Call the Claude Fable 5.1 API: get an API key, use the claude-fable-5-1 model ID, send a first request in Python or Node.js, and switch to Opus 5.5. (HTML: https://seedrouter.ai/blog/claude-fable-5-1-api)
- [Use Claude Fable 5.1 and Opus 5.5 in Claude Code with an API key](https://seedrouter.ai/blog/claude-fable-5-1-claude-code.md): Run Claude Fable 5.1, Fable 5 or Opus 5.5 in Claude Code with a SeedRouter API key: the environment variables, model selection, and what each session costs. (HTML: https://seedrouter.ai/blog/claude-fable-5-1-claude-code)
- [Claude Fable 5.1 vs Fable 5 vs Opus 5.5: which Claude model to use](https://seedrouter.ai/blog/claude-fable-5-1-vs-fable-5-vs-opus-5-5.md): Claude Fable 5.1 vs Fable 5 vs Opus 5.5 compared: specs, prices, official benchmark scores, what changed from Fable 5 and Opus 5, and which model to pick. (HTML: https://seedrouter.ai/blog/claude-fable-5-1-vs-fable-5-vs-opus-5-5)
- [Is Claude Fable 5 still available? The suspension, the return, and what it means for API users](https://seedrouter.ai/blog/is-claude-fable-5-available.md): Is Claude Fable 5 still available? Why it was suspended on June 12, 2026, when it came back, its status today, and how to call it through the API right now. (HTML: https://seedrouter.ai/blog/is-claude-fable-5-available)
- [Is Claude Fable 5 free? Free plans, trial credit and paid API options](https://seedrouter.ai/blog/is-claude-fable-5-free.md): Is Claude Fable 5 free? What the Claude Free, Pro and Max plans include, whether a free Fable 5 API key exists, and how to test it with free sign-up credit. (HTML: https://seedrouter.ai/blog/is-claude-fable-5-free)
- [Is Nano Banana free? What you get without paying](https://seedrouter.ai/blog/is-nano-banana-free.md): Is Nano Banana free? What the Gemini app and the Gemini API include for Nano Banana 2 and Nano Banana Pro without paying, and when you start paying. (HTML: https://seedrouter.ai/blog/is-nano-banana-free)
- [Is Seedance free? What the free options include](https://seedrouter.ai/blog/is-seedance-free.md): Is Seedance free? Where ByteDance offers Seedance 2.0 and 2.5 with free credits, why the API is paid, and what free unlimited Seedance sites really are. (HTML: https://seedrouter.ai/blog/is-seedance-free)
- [How to use the Nano Banana 2 API: key, request and result](https://seedrouter.ai/blog/nano-banana-2-api.md): Use the Nano Banana 2 API step by step: create a key, send a generateContent request, poll the task, add reference images, and let a coding agent run it. (HTML: https://seedrouter.ai/blog/nano-banana-2-api)
- [Nano Banana 2 vs Nano Banana Pro vs Nano Banana 2 Lite: which one to use](https://seedrouter.ai/blog/nano-banana-2-vs-pro-vs-lite.md): Compare Nano Banana 2, Nano Banana Pro and Nano Banana 2 Lite on image size, aspect ratios, references, thinking and billing, and pick one per job. (HTML: https://seedrouter.ai/blog/nano-banana-2-vs-pro-vs-lite)
- [Nano Banana API pricing: cost per image by resolution](https://seedrouter.ai/blog/nano-banana-api-pricing.md): Current Nano Banana API pricing for Nano Banana 2, Pro and 2 Lite: flat per-image and token billing, cost by resolution, and when each billing fits. (HTML: https://seedrouter.ai/blog/nano-banana-api-pricing)
- [Seedance 2.0 vs Seedance 2.0 Fast vs Seedance 2.0 Mini: which one to use](https://seedrouter.ai/blog/seedance-2-0-vs-fast-vs-mini.md): Compare Seedance 2.0, Seedance 2.0 Fast and Seedance 2.0 Mini on resolution, price per second, render time and inputs, and pick the right one for each job. (HTML: https://seedrouter.ai/blog/seedance-2-0-vs-fast-vs-mini)
- [Seedance 2.5 vs Seedance 2.0: what changed and when to upgrade](https://seedrouter.ai/blog/seedance-2-5-vs-2-0.md): Seedance 2.5 vs Seedance 2.0 compared: clip length, references, editing, resolution, price and release dates, and when the upgrade is worth it. (HTML: https://seedrouter.ai/blog/seedance-2-5-vs-2-0)
- [How to use the Seedance API: key, request, polling and references](https://seedrouter.ai/blog/seedance-api.md): Use the Seedance API step by step: create a key, send a video task, poll it for the video URL, add image, video and audio references, and hand it to an agent. (HTML: https://seedrouter.ai/blog/seedance-api)
- [Seedance API pricing: cost per second for every model and resolution](https://seedrouter.ai/blog/seedance-api-pricing.md): Current Seedance API pricing for Seedance 2.0, 2.0 Fast, 2.0 Mini and 2.5: price per second at each resolution, how video tokens are counted, and what is free. (HTML: https://seedrouter.ai/blog/seedance-api-pricing)
- [GPT Image 2.5 API pricing: what one image costs](https://seedrouter.ai/blog/gpt-image-2-5-api-pricing.md): See current GPT Image 2.5 API pricing per image for Flare and Sunburst, compare flat and token billing, and estimate a monthly budget from real rates. (HTML: https://seedrouter.ai/blog/gpt-image-2-5-api-pricing)
- [GPT Image 2.5 API in Python: a working example](https://seedrouter.ai/blog/gpt-image-2-5-api-python.md): Call the GPT Image 2.5 API from Python and JavaScript, poll the task for image URLs, edit with references, and fix model ID and parameter errors. (HTML: https://seedrouter.ai/blog/gpt-image-2-5-api-python)
- [GPT Image 2.5 Flare vs Sunburst: which one should you use?](https://seedrouter.ai/blog/gpt-image-2-5-flare-vs-sunburst.md): Compare GPT Image 2.5 Flare and Sunburst on speed, edit control, parameters and cost, and pick the right model ID for each kind of image job. (HTML: https://seedrouter.ai/blog/gpt-image-2-5-flare-vs-sunburst)
- [GPT Image 2.5 prompting guide: prompts, edits and quality steps](https://seedrouter.ai/blog/gpt-image-2-5-prompting-guide.md): Write GPT Image 2.5 prompts that hold up across revisions, describe reference edits and masks clearly, and use the six quality steps without wasted renders. (HTML: https://seedrouter.ai/blog/gpt-image-2-5-prompting-guide)
- [GPT Image 2 API key: how to get access and make a first request](https://seedrouter.ai/blog/gpt-image-2-api-key.md): Get a GPT Image 2 API key, store it safely, add credits, and make a first request with curl, Python or JavaScript, plus the errors a new key most often hits. (HTML: https://seedrouter.ai/blog/gpt-image-2-api-key)
- [GPT Image 2 API parameters: size, resolution, aspect ratio and quality](https://seedrouter.ai/blog/gpt-image-2-api-parameters.md): The GPT Image 2 API parameters that shape the image: model name, size and resolution, aspect ratios, 4K limits, quality, formats and the errors they return. (HTML: https://seedrouter.ai/blog/gpt-image-2-api-parameters)
- [GPT Image 2 API in Python: a complete example](https://seedrouter.ai/blog/gpt-image-2-api-python.md): A complete GPT Image 2 API example in Python: submit a request, poll the task, download the images to disk, edit with references and handle errors safely. (HTML: https://seedrouter.ai/blog/gpt-image-2-api-python)
- [Use GPT Image 2 in Codex, Claude Code and other coding agents](https://seedrouter.ai/blog/gpt-image-2-codex-claude-code.md): Let Codex, Claude Code or another coding agent make images with GPT Image 2 through your API key, with a reusable prompt that asks before every paid request. (HTML: https://seedrouter.ai/blog/gpt-image-2-codex-claude-code)
- [Batch GPT Image 2 requests without losing track of tasks](https://seedrouter.ai/blog/gpt-image-2-batch-generation.md): Submit a set of GPT Image 2 prompts, save task IDs, resume polling after interruptions, and download completed images without resubmitting them. (HTML: https://seedrouter.ai/blog/gpt-image-2-batch-generation)
- [How much does GPT Image 2 cost?](https://seedrouter.ai/blog/gpt-image-2-pricing.md): Estimate GPT Image 2 costs from current SeedRouter rates, understand sample token usage, and budget for drafts, revisions, and final images. (HTML: https://seedrouter.ai/blog/gpt-image-2-pricing)
- [GPT Image 2 prompts that are easier to revise](https://seedrouter.ai/blog/gpt-image-2-prompting.md): Write clearer GPT Image 2 prompts, specify exact text, preserve details in reference edits, and revise one visual constraint at a time. (HTML: https://seedrouter.ai/blog/gpt-image-2-prompting)
- [Move an image integration to SeedRouter](https://seedrouter.ai/blog/migrate-image-api-to-seedrouter.md): Migrate a GPT Image 2 integration to SeedRouter by mapping request fields, handling asynchronous tasks, and validating URL-based image delivery. (HTML: https://seedrouter.ai/blog/migrate-image-api-to-seedrouter)
- [OpenAPI request and response schemas](https://seedrouter.ai/docs/gpt-image-2.openapi.json)
- [API reference as Markdown](https://seedrouter.ai/docs/gpt-image-2.md)
- [Task lifecycle](https://seedrouter.ai/docs/api/tasks.md)
- [Error catalog and retry guidance](https://seedrouter.ai/docs/api/errors.md)
- [Account usage](https://seedrouter.ai/usage)
- [All model guides](https://seedrouter.ai/llms.txt)
- [Documentation index](https://seedrouter.ai/docs/llms.txt)
