# GPT Image 2.5 on SeedRouter

> Generate and edit images with GPT Image 2.5 Flare or Sunburst through one asynchronous image endpoint, with six quality steps up to max.

Model ID: `gpt-image-2.5-flare`, `gpt-image-2.5-sunburst`, `gpt-image-2.5-flare-official`, `gpt-image-2.5-sunburst-official`. [Playground and pricing](https://seedrouter.ai/models/gpt-image-2-5).
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.5 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) |
| --- | --- | --- | --- |
| Standard | `gpt-image-2.5-flare`, `gpt-image-2.5-sunburst` | Flat price per delivered image, at any size or quality | $0.03 per delivered image |
| Official | `gpt-image-2.5-flare-official`, `gpt-image-2.5-sunburst-official` | Tokens each render reports (text input + image output) | $3.75 per 1M input tokens; $22.5 per 1M output tokens |

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 | Standard USD | Official USD |
| --- | --- | --- | --- |
| low | 196 | $0.03 | $0.0044775 |
| medium | 439 | $0.03 | $0.009945 |
| high | 1756 | $0.03 | $0.0395775 |
| xhigh | 3122 | $0.03 | $0.0703125 |
| max | 7024 | $0.03 | $0.1581075 |
| auto | 229 | $0.03 | $0.00522 |

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.5 accepts a text prompt and optional reference images. Submit once, keep the returned task ID, and check that task for the finished images. It ships as two models that read the same parameters: **Flare** for everyday work and **Sunburst** when edit precision matters most.

## Model IDs

| Model ID                          | Tier                                                         | Channel  |
| --------------------------------- | ------------------------------------------------------------ | -------- |
| `gpt-image-2.5-flare`             | Flare: the default choice for most applications              | Standard |
| `gpt-image-2.5-sunburst`          | Sunburst: most capable, tighter control across edits, slower | Standard |
| `gpt-image-2.5-flare-official`    | Flare                                                        | Official |
| `gpt-image-2.5-sunburst-official` | Sunburst                                                     | Official |

All four IDs accept the same parameters. The channels differ in billing; see the [model page](https://seedrouter.ai/models/gpt-image-2-5#pricing) for current prices.

## 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.5-flare",
    "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.5-flare",
        "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.5-flare',
    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.5-flare",
      "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      | —              | One of the four model IDs above.                                                     |
| `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`, `xhigh`, `max`.                                     |
| `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

`xhigh` and `max` are new in GPT Image 2.5; GPT Image 2 stops at `high`. Higher tiers take longer to render and, on token-billed IDs, consume more output tokens. Measured at 1024x1024, one render reported 196, 439, 1,756, 3,122 and 7,024 output tokens for `low`, `medium`, `high`, `xhigh` and `max`. These are observed samples, not guarantees: usage also depends on size and content.

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 supported for GPT Image 2.5. 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 a GPT Image 2.5 parameter. `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.5-flare",
    "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-5#pricing) for current rates. Standard IDs charge one flat price per delivered image, whatever the quality, size, or prompt. On Official IDs, 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.5-flare",
  "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.5-flare",
  "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.5 Playground and pricing](https://seedrouter.ai/models/gpt-image-2-5)
* [Download OpenAPI](https://seedrouter.ai/docs/gpt-image-2-5.openapi.json)
* [Copyable Markdown](https://seedrouter.ai/docs/gpt-image-2-5.md)

## More resources

- [OpenAPI request and response schemas](https://seedrouter.ai/docs/gpt-image-2-5.openapi.json)
- [API reference as Markdown](https://seedrouter.ai/docs/gpt-image-2-5.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)
