How to use the gpt-image-2.5 API (Flare and Sunburst) with curl, Python, and Node

Call the gpt-image-2.5 API (Flare and Sunburst) with curl, Python, and Node: generations, multipart edits with a reference image, streaming, and real cost.

INEZA Felin-Michel

INEZA Felin-Michel

9 September 2026

How to use the gpt-image-2.5 API (Flare and Sunburst) with curl, Python, and Node

Apidog for Enterprise

On-Premises Deploy

SSO & RBAC

SOC 2 Compliant

Explore Apidog Enterprise

OpenAI shipped ChatGPT Images 2.5 on September 8, 2026, with two new API models: gpt-image-2.5-flare and gpt-image-2.5-sunburst. Both sit behind the same endpoints as gpt-image-2, so if you followed our gpt-image-2 API guide, most of your code survives a model ID swap. What changed is the quality ladder and how the Responses API lets you pick a model per tool call.

This guide covers the developer path only: generations, multipart edits with a reference image and mask, the Responses API tool, streaming, and reading usage for real cost. For what the release means for ChatGPT users, read our ChatGPT Images 2.5 overview; the OpenAI launch post has the product framing. Every number below comes from OpenAI’s docs, pricing page, or calculator as read on September 9, 2026.

gpt-image-2.5 API at a glance

Item Value (OpenAI docs)
Model IDs gpt-image-2.5-flare, gpt-image-2.5-sunburst (snapshots -2026-09-08)
Endpoints POST /v1/images/generations, POST /v1/images/edits, Responses API image_generation tool
Input / output Text and image in, image only out
Quality low, medium, high, xhigh, max, auto (default). xhigh and max are new
Sizes 1024x1024, 1536x1024, 1024x1536 recommended; custom sizes in multiples of 16, aspect 1:3 to 3:1, up to 4K total pixels
Output data[].b64_json; output_format png, jpeg, webp; background: "transparent" needs png or webp
Streaming partial_images 0-3, each partial costs 100 extra output tokens
Price (both models) $30 per 1M image output tokens, $8 per 1M image input tokens, $5 per 1M text input tokens

Per-token rates match gpt-image-2; per-image cost still moves because token counts per quality level changed.

Prerequisites

Export the key once:

export OPENAI_API_KEY="sk-proj-..."

Generate an image with curl

Use Flare first; OpenAI’s model page calls it “the default choice for most applications”.

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-flare",
    "prompt": "Product photo of a matte black mechanical keyboard, studio lighting, no text",
    "size": "1536x1024",
    "quality": "medium",
    "output_format": "webp",
    "background": "transparent"
  }'

The response holds a data array with one b64_json per image, plus a usage object with input_tokens and output_tokens. Keep usage; it’s the only accurate cost signal you get. Parameter notes from the image generation guide: output_format defaults to png and OpenAI says “Using jpeg is faster than png”; output_compression (0-100) applies to jpeg and webp only; background: "transparent" fails on jpeg.

Python: generate, then edit with a reference image

The SDK call mirrors the curl body. Decode b64_json and write the bytes.

import base64
from openai import OpenAI

client = OpenAI()

gen = client.images.generate(
    model="gpt-image-2.5-flare",
    prompt="Clean API analytics dashboard mockup, dark theme, latency chart top right",
    size="1536x1024",
    quality="high",
    output_format="png",
)
open("dashboard.png", "wb").write(base64.b64decode(gen.data[0].b64_json))
print(gen.usage.output_tokens, "output tokens")

Edits are where the 2.5 models earn their keep; the launch post says they are “better at editing only what you’ve asked for, while keeping the rest of the details the same”, and OpenAI positions Sunburst for “tighter control across edits”. The edits endpoint is multipart: a reference image, an optional mask, and a prompt. Where the mask is transparent, the model repaints; everywhere else it keeps the original.

edit = client.images.edit(
    model="gpt-image-2.5-sunburst",
    image=open("dashboard.png", "rb"),
    mask=open("chart-area-mask.png", "rb"),
    prompt="Replace the latency chart with a bar chart of error rates per endpoint; keep everything else",
    size="1536x1024",
    quality="high",
)
open("dashboard-v2.png", "wb").write(base64.b64decode(edit.data[0].b64_json))
print(edit.usage.input_tokens, "input tokens (includes the reference image)")

Drop mask and the model decides what to change from the prompt alone. The reference image bills as image input tokens at $8 per 1M; OpenAI doesn’t publish a per-image input token count, so read usage.input_tokens.

Node and TypeScript: write b64_json to disk

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

const client = new OpenAI();

const res = await client.images.generate({
  model: "gpt-image-2.5-flare",
  prompt: "Hero image for API docs: floating JSON cards over a teal gradient, no text",
  size: "1536x1024",
  quality: "medium",
  output_format: "jpeg",
  output_compression: 80,
});

const b64 = res.data?.[0]?.b64_json;
if (!b64) throw new Error("no image returned");
await fs.writeFile("hero.jpg", Buffer.from(b64, "base64"));

Pin gpt-image-2.5-flare-2026-09-08 in production to keep output stable while the alias moves.

Responses API: image generation as a tool

Here a mainline model reads your prompt, revises it, and calls the image_generation tool. You pick the image model by setting model inside the tool definition; the top-level model must be a mainline model, and OpenAI’s tool docs use gpt-6-astra. Our Responses API guide covers the request shape. The action field takes auto (default), generate, or edit; set edit when you pass a reference image and want it modified, not reinterpreted.

import base64

with open("product.png", "rb") as f:
    ref = base64.b64encode(f.read()).decode()

first = client.responses.create(
    model="gpt-6-astra",
    input=[{"role": "user", "content": [
        {"type": "input_text", "text": "Put this bottle on a white marble surface with soft daylight"},
        {"type": "input_image", "image_url": f"data:image/png;base64,{ref}"},
    ]}],
    tools=[{"type": "image_generation", "model": "gpt-image-2.5-sunburst", "action": "edit"}],
)
calls = [o for o in first.output if o.type == "image_generation_call"]
open("bottle-marble.png", "wb").write(base64.b64decode(calls[0].result))

second = client.responses.create(
    model="gpt-6-astra",
    previous_response_id=first.id,
    input="Same scene, but add a second bottle behind it, slightly out of focus",
    tools=[{"type": "image_generation", "model": "gpt-image-2.5-sunburst", "action": "edit"}],
)

The previous_response_id follow-up keeps the first image in context, so “same scene” resolves without re-uploading the file. Mainline model tokens are billed on top of image tokens, and the prompt rewrite means you can’t reproduce output from prompt text alone.

Streaming partial images

Both APIs accept partial_images (0 to 3). Each partial costs 100 extra output tokens, so three add 300 tokens, or $0.009 per image. Worth it for a UI that shows progress; wasted in a batch job.

stream = client.images.generate(
    model="gpt-image-2.5-flare",
    prompt="Isometric illustration of an API gateway routing requests to three services",
    size="1024x1024",
    quality="medium",
    stream=True,
    partial_images=2,
)
for event in stream:
    if event.type.endswith("partial_image"):
        open(f"gateway-partial-{event.partial_image_index}.png", "wb").write(
            base64.b64decode(event.b64_json))
    elif event.type.endswith("completed"):
        open("gateway.png", "wb").write(base64.b64decode(event.b64_json))

The exact event type strings are in the image generation guide; the suffix check keeps the loop working across both API variants. To inspect streamed events outside code, see our guide to testing SSE responses from AI APIs.

Read usage and turn tokens into dollars

OpenAI’s own caveat: “Equal token rates don’t mean equal cost per image: token consumption can differ by model and quality setting.” The calculator in the image generation guide gives these estimates for image output tokens alone, at the $30 per 1M rate on the pricing page:

Quality 1024x1024 1536x1024
low 196 tokens, $0.0059 158 tokens, $0.0047
medium 439 tokens, $0.0132 343 tokens, $0.0103
high 1,756 tokens, $0.0527 1,372 tokens, $0.0412
xhigh 3,122 tokens, $0.0937 2,459 tokens, $0.0738
max 7,024 tokens, $0.2107 5,488 tokens, $0.1646

Notice the relabel. high on 2.5 uses 1,756 tokens, the old medium budget on gpt-image-2; max uses 7,024 tokens, the old high budget. Keep quality: "high" through a migration and each image gets about 4x cheaper at the old medium budget; for the old high budget, move to max. Our Flare vs Sunburst vs gpt-image-2 comparison runs the full monthly math.

Calculator numbers are estimates. Real cost comes from the response:

OUTPUT_RATE = 30 / 1_000_000  # dollars per image output token
usd = gen.usage.output_tokens * OUTPUT_RATE
print(f"{gen.usage.output_tokens} tokens = ${usd:.4f}")

Log it per request; per OpenAI, a larger non-square size can produce fewer tokens than a smaller square one. One open question: the pricing page’s Batch tab lists gpt-image-2 only, so treat Batch API support for 2.5 as unconfirmed.

Errors, rate limits, and timeouts

Test Flare and Sunburst side by side in Apidog

Terminal iteration on image prompts is slow because you can’t see the output, and a wrong quality value costs real money on every send. Apidog is an API client and testing platform: it sends the calls and checks the responses; OpenAI’s servers do the rendering.

  1. Store the key once. Add OPENAI_API_KEY as an environment variable and reference it as Bearer {{OPENAI_API_KEY}} in the Authorization header; the key never lands in a saved request.
  2. Two environments, one request. Create environments named flare and sunburst, each with a MODEL variable, and set "model": "{{MODEL}}" in the body. Switch, resend, and compare images and usage side by side. For edits, use a form-data body with image and mask as file fields.
  3. Decode b64_json in a post-processor. A short script pulls data[0].b64_json, decodes it, and saves the file, so every send yields a viewable image next to the raw JSON.
  4. Assert on cost, then schedule it. Assert that usage.output_tokens stays under a budget, say 2,000 for a high 1536x1024 render, and run the request as a timed regression test. If someone bumps quality to max or a snapshot moves token counts, the test fails before the invoice does.

Download Apidog, point it at your OpenAI key, and you have a shared prompt library with cost guardrails.

FAQ

Do I need to change my gpt-image-2 code to use 2.5? Swap the model ID and re-check quality. Endpoints, auth, and response shape are unchanged, but high now maps to a smaller token budget. The gpt-image-2 API guide still covers the older model.

Flare or Sunburst for the API? Start with Flare. OpenAI positions it as the default with “50% lower latency” than gpt-image-2 at the same per-token price. Move to Sunburst when edit precision matters more than speed, such as product imagery built from reference photos. Both share the same calculator token counts, so the trade is time, not dollars.

Can I use these models in Chat Completions? No. Image generation lives on the Image API and the Responses API image_generation tool. Chat Completions doesn’t expose it.

Is there a free way to try 2.5 through the API? There’s no perpetual free API tier, and image endpoints need Tier 1. The cheapest real path is quality: "low" at 196 tokens, about $0.006 per 1024x1024 image. The consumer app is another matter; see how to use ChatGPT Images 2.5 for free.

Where to go next

Start with the curl call, confirm usage.output_tokens against the calculator table, then move the request into a client where you can see the image. Simon Willison’s write-up shows Sunburst keeping a chart intact while adding a subject; test that edit behavior on your own reference images before you commit.

button

Explore more

How to use ChatGPT Images 2.5 for free (every tier, plus the developer path)

How to use ChatGPT Images 2.5 for free (every tier, plus the developer path)

ChatGPT Images 2.5 is free on every ChatGPT tier. Step-by-step with Sketch, templates, and comments, what Free, Go, Plus, and Pro get, and the honest API path.

9 September 2026

GPT-Image-2.5 Flare vs Sunburst vs gpt-image-2: which to pick, and what each image costs

GPT-Image-2.5 Flare vs Sunburst vs gpt-image-2: which to pick, and what each image costs

gpt-image-2.5 pricing explained: Flare vs Sunburst vs gpt-image-2 per-token rates, per-image cost at all 5 quality levels, the relabeled ladder, and migration.

9 September 2026

GPT-6 Astra can use your computer. Give it your OpenAPI spec instead.

GPT-6 Astra can use your computer. Give it your OpenAPI spec instead.

GPT-6 Astra scores 72.6% on OSWorld at 40 minutes a task. For API teams, handing it the OpenAPI spec is faster, cheaper, and verifiable. When to click, when to call, and how to set it up.

5 September 2026

Practice API Design-first in Apidog

Discover an easier way to build and use APIs

How to use the gpt-image-2.5 API (Flare and Sunburst) with curl, Python, and Node