live
MODEL IDopenai:gpt-image@2.5-flare

GPT-Image-2.5 Flare

OpenAI
by

GPT-Image-2.5 Flare is OpenAI's fastest model for high-quality image generation and editing, delivering higher-quality images than GPT Image 2 at 50% lower latency. It improves natural lighting, texture detail, reference-subject preservation, localized editing, and consistency across iterative edits, while handling complex layouts and transparent backgrounds. It is designed for creator content, product experiences, visual search, rapid prototyping, and high-volume generation.

GPT-Image-2.5 Flare

Iterative editing

How to run a chain of edits with GPT-Image-2.5 Flare: feeding each result back as the next source, what accumulates across passes, and when to restate instead of chain.

Introduction

Art direction does not arrive as one instruction. A shot gets a colour change, then a prop, then a different wall, then a note about the light, and each round is judged before the next one is asked for. Every round is a separate call to the model, and each one has to start from the version that was approved, not from the original.

Flare is built for that loop. OpenAI's stated improvement here is that earlier edits stay put as later ones are applied, and that quality holds instead of softening a little more on each pass. The four passes below were run in order, each one taking the previous result as its source.

A floor lamp with a natural linen shade standing in the corner of a living room beside a small walnut side table, against a plain white wall
The same floor lamp in the same corner with its shade changed from natural linen to matte black

Change only the natural linen lampshade to a matte black one. Preserve its shape, its proportions and the way it sits on the stand. Keep the lamp base, the side table, the wall, the floor, the framing and the lighting unchanged.

The same corner with the matte black lampshade and the wall repainted deep forest green

Change only the wall colour to a deep forest green. Preserve the lamp, its matte black shade, the side table, the floor, the framing and the lighting unchanged.

The same corner with the matte black shade and green wall, now with a stack of three hardback books lying on the side table

Add a stack of three hardback books lying flat on the side table, next to the lamp base. Keep the lamp, its matte black shade, the green wall, the table, the floor, the framing and the lighting unchanged.

The same corner with the lamp switched on, warm light falling down the green wall and across the side table and the stack of books

Switch the lamp on so it casts a warm pool of light down the green wall and across the side table and the books. Keep the lamp, its matte black shade, the wall colour, the table, the books, the floor and the framing unchanged.

Step through them. The black shade from pass 1 is still black in pass 4, and the books added in pass 3 are the ones the lamp lights up.

This guide covers the loop itself, what holds across passes and what accumulates, chaining against restating, and when to throw the chain away.

The loop

Each turn is an ordinary edit. The only thing that makes it a chain is where the source comes from: the image the previous turn returned.

Try in Playground
import { createClient } from '@runware/sdk'

const client = await createClient({ apiKey: process.env.RUNWARE_API_KEY })
await client.connect()

const [result] = await client.run({
  model: 'openai:gpt-image@2.5-flare',
  positivePrompt: 'Change only the wall colour to a deep forest green. Preserve the lamp, its matte black shade, the side table, the floor, the framing and the lighting unchanged.',
  inputs: {
    referenceImages: [
      '8f3d1a5c-7b20-4e69-a4d1-0c6e2f8a3b57'
    ]
  },
  width: 1536,
  height: 1024
})
import asyncio
import os

from runware import Runware


async def main():
    async with Runware(api_key=os.environ["RUNWARE_API_KEY"]) as client:
        results = await client.run({
            "model": "openai:gpt-image@2.5-flare",
            "positivePrompt": "Change only the wall colour to a deep forest green. Preserve the lamp, its matte black shade, the side table, the floor, the framing and the lighting unchanged.",
            "inputs": {
                "referenceImages": [
                    "8f3d1a5c-7b20-4e69-a4d1-0c6e2f8a3b57"
                ]
            },
            "width": 1536,
            "height": 1024
        })


asyncio.run(main())
curl https://api.runware.ai/v1 \
  -H "Authorization: Bearer $RUNWARE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "taskType": "imageInference",
      "taskUUID": "e2a7c4b1-9d38-4506-8f1a-3b7c2d5e9068",
      "model": "openai:gpt-image@2.5-flare",
      "positivePrompt": "Change only the wall colour to a deep forest green. Preserve the lamp, its matte black shade, the side table, the floor, the framing and the lighting unchanged.",
      "inputs": {
        "referenceImages": [
          "8f3d1a5c-7b20-4e69-a4d1-0c6e2f8a3b57"
        ]
      },
      "width": 1536,
      "height": 1024
    }
  ]'
runware run openai:gpt-image@2.5-flare \
  positivePrompt="Change only the wall colour to a deep forest green. Preserve the lamp, its matte black shade, the side table, the floor, the framing and the lighting unchanged." \
  inputs.referenceImages.0=8f3d1a5c-7b20-4e69-a4d1-0c6e2f8a3b57 \
  width=1536 \
  height=1024
{
  "taskType": "imageInference",
  "taskUUID": "e2a7c4b1-9d38-4506-8f1a-3b7c2d5e9068",
  "model": "openai:gpt-image@2.5-flare",
  "positivePrompt": "Change only the wall colour to a deep forest green. Preserve the lamp, its matte black shade, the side table, the floor, the framing and the lighting unchanged.",
  "inputs": {
    "referenceImages": [
      "8f3d1a5c-7b20-4e69-a4d1-0c6e2f8a3b57"
    ]
  },
  "width": 1536,
  "height": 1024
}
Response
[
  {
    "taskType": "imageInference",
    "taskUUID": "e2a7c4b1-9d38-4506-8f1a-3b7c2d5e9068",
    "imageUUID": "b1c9e4f7-2a58-4d03-9e6b-5f8a0c2d7e31",
    "imageURL": "https://im.runware.ai/image/os/a14d18/ws/2/ii/b1c9e4f7-2a58-4d03-9e6b-5f8a0c2d7e31.jpg"
  }
]

The reference is a bare UUID rather than a URL. Image inputs accept a UUID, a URL, a data URI or base64, and the imageUUID that came back from the previous turn is the cheapest of the four to pass along: no download, no re-upload, no storage of your own between rounds.

let current = firstResult.imageUUID

for (const instruction of rounds) {
  const [result] = await client.run({
    model: 'openai:gpt-image@2.5-flare',
    positivePrompt: instruction,
    inputs: { referenceImages: [current] },
    width: 1536,
    height: 1024,
  })

  current = result.imageUUID
}

Keep width and height fixed for the whole chain. Changing them mid-run makes the model recompose rather than edit, and the passes stop lining up against each other.

What holds and what accumulates

Two different things travel down a chain, and only one of them is wanted.

Your changes hold. Each instruction names what it is changing and what it is preserving, and the preserved half comes through the next pass intact. That is the property the whole workflow rests on, and it is what the four passes above demonstrate.

Small drift accumulates. Every pass is a fresh render, not a patch applied to pixels, so the parts of the frame nobody mentioned are reproduced rather than copied. Reproduced is close, and close compounds. Fine texture is where it shows first, so check grain, fabric weave and small type against the original rather than against the previous pass.

The side table was never mentioned in any of the four instructions, which makes it the honest place to look. Compare its grain across the two, not the parts that were deliberately changed.

Keep every intermediate. Each pass returns its own imageUUID, and holding on to them means a bad fourth pass costs you one call from the third rather than a rebuild from the original. Storing the chain is also what lets you show a client the round they approved.

Chaining or restating

There are two ways to reach the same finished image, and they are not interchangeable.

Chaining runs one change per call, each on the previous result. Restating goes back to the original source and asks for every change in a single instruction. The image below is the second route: one call on the untouched source, carrying all four changes at once.

Restating is one call instead of four and it starts from an image that has been through nothing, so it carries no accumulated drift. What it costs you is the checkpoints: one result to accept or reject, with no way to keep the wall colour and re-ask for the books.

The rule that falls out of it: chain while a human is still judging each round, and restate once the full list of changes is settled. A chain is for the art-direction conversation, a restatement is for the final render, and rebuilding a settled chain as one instruction is worth doing before you generate the asset you actually ship.

When to start over

A chain has a point past which it stops paying, and it is easier to see than to define. Three signs, and any one of them is enough.

An instruction stops landing. You ask for the same change twice and get the same wrong result, which usually means the model is reconciling your new instruction against something it inferred several passes ago.

Detail has gone soft somewhere nobody asked about. Once texture has drifted, no later instruction restores it, because each pass only knows the image it was handed.

The list of things to preserve has grown longer than the change. When an instruction spends four clauses protecting earlier passes to make one small change, restating from the original is both shorter and safer.

Tips

  1. Pass the imageUUID, not the URL. The previous response already contains everything the next call needs.

  2. Hold width and height constant. A size change mid-chain turns an edit into a recomposition.

  3. Keep every intermediate. A rejected pass should cost one call, not the whole chain.

  4. Name the earlier changes in later instructions. "Keep the matte black shade" in pass 3 is cheap insurance and costs you nothing when it was going to hold anyway.

  5. Audit texture against the original. Drift is invisible pass to pass and obvious end to end, so compare the current result with where you started.

  6. Restate the settled chain before you ship. Once the changes are agreed, one instruction on the untouched source gives you the same image without the accumulated passes.