Tool setup

Generate and edit images with GPT Image 2.5 Flare and Sunburst

GPT Image 2.5 on apiToken.sale is two Images HTTP ids — gpt-image-2.5-flare for faster everyday work and gpt-image-2.5-sunburst for higher-precision edits — on the same POST /v1/images/generations and /v1/images/edits routes, Bearer key and prepaid balance as GPT Image 2. Official token rates match Image 2. This guide documents the live-proved conversion, not official xhigh/max/2K/4K.

·

The generation route in one request

GPT Image 2.5 Flare and Sunburst are image models you call over the OpenAI-compatible surface: send a prompt to /v1/images/generations with model gpt-image-2.5-flare or gpt-image-2.5-sunburst and an Authorization: Bearer header, and you get back one PNG. No separate image plan, no second key — the same sk-pool credential and prepaid balance that cover GPT, Claude and Gemini calls settle image usage too. Flare is the faster everyday id; Sunburst is slower and aimed at higher-precision edits. Official token rates match GPT Image 2.

curl https://router.apitoken.sale/v1/images/generations \
  -H "Authorization: Bearer $APITOKEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2.5-flare",
    "prompt": "A precise technical cutaway of a lunar rover",
    "quality": "low"
  }'

Official GPT Image fields are accepted and converted onto this ChatGPT pool. Extra keys (user, stream, moderation, style) are ignored, not 400. quality medium/high/xhigh/max/auto still generate at the pool's low tier on a clean prompt. output_format jpeg or webp transcodes the native PNG locally; omit or png keeps PNG. response_format=url is ignored — the body is always b64_json. n may be 1–10; each extra image is another native turn on the same home. background=auto is opaque; transparent prepends a cutout sentence and asks for a real PNG alpha channel — inspect the file; a missing alpha is still HTTP 200, not 502. JSON background=transparent is not an alpha lock. size selects a proportion, not a pixel lock. 2048x2048 and 3840x2160 map to 1:1 and 16:9; the PNG stays around 1.57 megapixels and the response size field is the real IHDR.

sizeProportionSteer target (inspect the PNG)
omitted or autono size steertypically ~1254×1254; not a lock
1024x1024, 1:1, 2048x20481:11254×1254
1536x1024 or 3:23:2 landscape1536×1024
1024x1536 or 2:32:3 portrait1024×1536
4:34:31448×1086
16:9, 2048x1152, 3840x216016:91672×941
9:16, 2160x38409:16944×1665

1024x1024 is the square bucket, not a 1024-pixel lock. Native explicit WIDTHxHEIGHT still lands near 1.57 MP. The table is the customer aspect-prefix target. If the PNG header does not match the bucket, the API still returns HTTP 200 and the PNG — put IHDR and alpha checks in your acceptance gate, not in an assumption that the route will 502.

POST /v1/images/* is non-streaming. n=2..10 runs sequential native turns and returns data[] of that length. For streamed preview frames, use the separate Responses image_generation tool with partial_images (below) — trivial prompts may skip partials. Responses settlement is the text model, not the five-leg image tariff.

See also: Generate and edit images with the GPT Image 2 API

Edit existing images with up to five PNG, JPEG or WebP references

Edits go to a different route and a different content type. POST multipart/form-data to /v1/images/edits with gpt-image-2.5-flare or gpt-image-2.5-sunburst, your prompt, and between one and five PNG, JPEG or WebP reference images (each file ≤50 MB). The references are how you ask for a targeted change — restyle this product shot, swap this background, extend this banner — instead of regenerating from scratch. Pick Sunburst when the edit needs more precision; pick Flare when latency matters more.

curl https://router.apitoken.sale/v1/images/edits \
  -H "Authorization: Bearer $APITOKEN_API_KEY" \
  -F "model=gpt-image-2.5-flare" \
  -F "prompt=Replace the backdrop with a seamless light-gray studio sweep" \
  -F "image=@packshot.png" \
  -F "image=@brand-swatch.png"
  • Repeat the field name image for each file, or send image[]. Multipart mask is ignored on this route — use Responses input_image_mask for inpaint.
  • References are PNG, JPEG or WebP, each at most 50 MB. GIF, HEIC and other types are rejected.
  • The cap is five references per call — pick the few that carry the instruction rather than dumping the whole asset library.
  • Every reference is billed as image input, so edits cost more than a pure-prompt generation of the same output.
  • The response shape matches generation: b64_json plus actual size/background/output_format. jpeg/webp on this route are local transcodes of the native PNG.

Deeper editing workflows: masks, batches and acceptance checks

Region inpaint and Responses image_generation

A multipart mask on /v1/images/edits is ignored so the SDK still gets an edit of the whole image. Native Codex ignores that field. To change only part of a picture — or to run the hosted image_generation tool from a GPT text model — call POST /v1/responses (Chat Completions maps the same hosted tools onto Responses). Put the source PNG in input as input_image when editing, and add tools: [{type:"image_generation", model:"gpt-image-2.5-flare", …}]. For a mask, set input_image_mask.image_url to a PNG data URL. Transparent pixels in the mask are the region to edit; opaque pixels stay. The mask must be the same size as the source. file_id masks are not supported — there is no Files API on this plane — so official OpenAI samples that upload a mask with files.create will not run here.

import base64, os
from pathlib import Path
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["APITOKEN_API_KEY"],
    base_url="https://router.apitoken.sale/v1",
)

def png_url(path):
    return "data:image/png;base64," + base64.b64encode(Path(path).read_bytes()).decode()

response = client.responses.create(
    model="gpt-5.6-sol",
    input=[{
        "role": "user",
        "content": [
            {"type": "input_text", "text": "Change only the masked region."},
            {"type": "input_image", "image_url": png_url("photo.png")},
        ],
    }],
    tools=[{
        "type": "image_generation",
        "model": "gpt-image-2.5-flare",
        "output_format": "webp",
        "partial_images": 2,
        "input_image_mask": {"image_url": png_url("mask.png")},
    }],
)
  • Use a text GPT model on /v1/responses or /v1/chat/completions (for example gpt-5.6-sol), not gpt-image-2.5-flare — that id belongs to the Images routes. Sending an image id to a text lane is 400 naming /v1/images/*, not 404.
  • Both the source and the mask must be data:image/png;base64,… URLs, not https:// and not OpenAI file ids.
  • Responses image_generation forwards output_format jpeg or webp (real file magic) and partial_images 1..=3; SSE emits response.image_generation_call.partial_image when partials arrive.
  • background=transparent is rewritten to opaque and input_fidelity is dropped. Quality/size on the tool still remap; the completed item echoes what ChatGPT returned. Responses image_generation on production generated Flare/Sunburst but stayed RGB in the 2026-09-08 matrix.
  • The mask is not billed as a second reference image; settlement on Responses follows the text model, not the five-leg image tariff. Images HTTP settlement keeps native /images/* usage.
  • POST /v1/images/* can return jpeg/webp by transcoding the native PNG. Real jpeg magic and partial_images SSE remain on Responses image_generation. Do not mix the two contracts.

Call it from the official OpenAI SDK

You can keep the official OpenAI SDK. Set base_url and api_key as for text models. Extra keys such as user, stream and moderation are ignored. response_format=url still returns b64_json. size=2048x2048 is accepted and converted to the square aspect; the PNG is not 2K pixels — read the response size field. The sample below is a typical SDK call.

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["APITOKEN_API_KEY"],
    base_url="https://router.apitoken.sale/v1",
)

result = client.images.generate(
    model="gpt-image-2.5-flare",
    prompt="A clean isometric diagram of a wind turbine",
    quality="low",
    size="3:2",
)

png_bytes = result.data[0].b64_json  # decode base64 and write to disk

For edits, the same client exposes images.edits with the reference files opened in binary mode. Keep the key in a server-side environment variable; image endpoints are exactly as sensitive as chat ones because they draw from the same balance. Swap the model string to gpt-image-2.5-sunburst for the slower higher-precision id.

What a generation actually costs

There is no honest fixed price per picture. GPT Image 2.5 bills per token across four usage legs — text input (your prompt), image input (references on edits), cached input and image output — at the same official rates as GPT Image 2. The request total follows the terminal usage the API reports, not the PNG's byte size or dimensions.

Usage legOfficial per 1M tokensPrice here
Fresh text input$5$2.50
Fresh image input$8$4
Cached text input$1.25$0.625
Cached image input$2$1
Image output$30$15
  • Every leg gets the flat 50% B2C discount; cached text and image input bill at 25% of the normal input rate before the discount applies.
  • Read the usage object on each response and log it next to the asset — it is the billing authority, and it is what the dashboard charge reconciles against.
  • gpt-image-2.5-flare aliases gpt-image-2.5-flare-2026-09-08; gpt-image-2.5-sunburst aliases gpt-image-2.5-sunburst-2026-09-08. Pin the dated ID if you want that guarantee spelled out in code.
  • A production low-quality canary on 2026-09-09 returned HTTP 200, RGB PNG 1254×1254 and 515 image-output tokens for both Flare and Sunburst.

Resist quoting a per-image price on your own pricing page from a handful of test renders. Output usage varies with the asset, and a number derived from three samples will be wrong in production. Sum the legs from real usage over a week, then decide. A cutout/logo prompt can echo medium (~2058 tokens) even when JSON said quality=auto and background=opaque.

GPT Image 2 cost model (same rates)

Limits of the current image surface

Plan around what the Codex pool can actually emit. Official client fields are converted onto that envelope:

  • POST /v1/images/* is non-streaming. n=1..10 runs that many sequential native turns and bills them all. n>10 is capped at 10.
  • Extra JSON keys are ignored. openai/gpt-image-2.5-flare is admitted as gpt-image-2.5-flare. GET /v1/models lists six Images API ids and the image routes.
  • size is a proportion: 2K/4K strings map to 1:1 or 16:9, and the PNG stays ~1.57 megapixels. quality medium/high/xhigh/max/auto still generate at low on a clean prompt. jpeg/webp are local transcodes. background=transparent is a cutout prompt, not an alpha lock.
  • The 200 body includes actual size, background, output_format and usage. Missing usage after a PNG is the only post-success 502 on this route.
  • Edits accept one to five PNG, JPEG or WebP references (each ≤50 MB). image[] matches image. mask is ignored — region inpaint is the Responses image_generation path above.
  • Image usage settles against the same prepaid balance as GPT, Claude and Gemini calls — one pool to watch, not four.

If you need a different image model for comparison, GPT Image 2 uses the same conversion on the same routes, and the Gemini-side image route is documented alongside this one.

Keep image spend contained on a shared balance

Because image output is the expensive leg and batch loops multiply it, give the image worker its own API key with a lifetime spending limit. A runaway render job then stops at its own ceiling instead of draining the balance your chat traffic depends on, and per-key usage in the dashboard tells you exactly which worker spent what.

  1. 01Create a dedicated key in the dashboard for the image pipeline and set its lifetime spending limit to the batch budget.
  2. 02Send one bounded generation request (the curl above) and confirm the returned PNG plus a usage object with the expected legs.
  3. 03Run your real prompt set in a small loop, record terminal usage per asset and reconcile the total against the dashboard charge.
  4. 04Only then scale to full batch volume, keeping the key's limit aligned with the budget you actually approved.

Per-model rates across every supported provider

Frequently asked questions

What endpoint does the GPT Image 2.5 API use?

POST /v1/images/generations for a new image and POST /v1/images/edits for reference-based edits, both on the OpenAI-compatible base URL https://router.apitoken.sale/v1 with an Authorization: Bearer header.

What is the difference between Flare and Sunburst?

gpt-image-2.5-flare is the faster everyday generation/edit id. gpt-image-2.5-sunburst is the higher-precision, slower id. Both use the same Images HTTP conversion, the same five-leg tariff, and the same prepaid balance.

Can GPT Image 2.5 edit an existing image?

Yes. The edits route accepts multipart/form-data with one to five PNG, JPEG or WebP files (each ≤50 MB) plus a prompt. Repeat the field name image, or send image[]. Multipart mask is ignored; use Responses input_image_mask to inpaint a region.

How do I inpaint only part of an image?

Call POST /v1/responses with a GPT text model, the source PNG as input_image, and tools: [{type:"image_generation", model:"gpt-image-2.5-flare", input_image_mask:{image_url:"data:image/png;base64,…"}}]. You can also set output_format jpeg|webp and partial_images 1..=3. Transparent mask pixels are the region to change. Do not send mask to /v1/images/edits, and do not use file_id. Chat Completions maps the same image_generation tool onto Responses.

What is the exact model ID?

Use gpt-image-2.5-flare or gpt-image-2.5-sunburst. They alias the immutable snapshots gpt-image-2.5-flare-2026-09-08 and gpt-image-2.5-sunburst-2026-09-08. Pin the dated ID in code if you want the snapshot spelled out explicitly.

How much does GPT Image 2.5 cost per image?

There is no fixed per-image price: billing follows terminal usage across text input ($5/M official), image input ($8/M), cached input (25% of fresh) and image output ($30/M), with a flat 50% discount on every leg here — $2.50, $4 and $15 per 1M respectively. Rates match GPT Image 2. A production low canary used 515 image-output tokens.

Does GPT Image 2.5 support transparent backgrounds, xhigh quality, or 2K/4K pixels?

On POST /v1/images/*: send background=transparent for a cutout PNG with a real alpha channel; omit, opaque or auto for solid; missing alpha is still HTTP 200. JSON transparent is not an alpha lock — a cutout/logo prompt can produce RGBA even when JSON said opaque. quality xhigh/max/medium/high/auto still generate at low on a clean prompt. size is a proportion, not 2K/4K pixels. stream is ignored.

Does image generation need a separate key or balance?

No. It uses the same Bearer key and prepaid balance as all other supported models — GPT, Claude and Gemini included — though a dedicated key with a lifetime spending limit is sensible for batch image workers.

Create an account with Google or GitHub and test the gateway with $5 of platform bonus credit.