Which model should you test first?

OpenAI describes Flare as the speed-oriented model for everyday image generation and Sunburst as its most capable image model, with an emphasis on editing precision. Both accept text and image inputs. These descriptions help you choose the first candidate; your own acceptance rate determines whether it is useful.

Your bottleneckFirst candidateWhat the test must establish
GPT Image 2 already produces usable images, but users wait too longFlareThe same cases remain acceptable and complete sooner.
A local edit changes product labels, geometry, faces, or surrounding objectsSunburstThe requested change succeeds without a disallowed change elsewhere.
Exact wording, dense layouts, or a final campaign image fails reviewSunburstThe complete image meets the written brief at its intended display size.
Sunburst already meets every requirementFlare on the same casesA speed or accepted-cost improvement survives the same review.
You need several different kinds of image workEvaluate each kind separatelyA good result on draft concepts does not conceal failures on packaging or localized text.

A comparison in the ChatGPT interface needs a different label if that interface does not expose the served model ID. Save it as an interface test with an unknown model. You can still use the case briefs and visual checklist, but you cannot attribute the result to Flare or Sunburst from its appearance or response time. A named-model comparison requires the API with an explicit model selection.

Define the job before collecting images

Write down what the image will be used for, which details can change, and which defects make it unusable. A concept sketch can tolerate an approximate label. A photograph used to represent a specific product cannot silently change its capacity, packaging, or shape. Those jobs need separate cases even when they use the same reference photo.

For a product background edit, a workable brief is: keep the bottle and its printed label; replace only the background; deliver a landscape PNG for a product card. List the protected details individually, including the cap, silhouette, label wording, and reflections. State whether a contact shadow is allowed. Save the intended product-card crop so the reviewer can check whether the edit still fits.

Set the retry allowance, acceptance target, latency budget, and critical-failure rule before running requests. Use limits from the actual service requirement. If a wrong product label is unacceptable, reject that output regardless of how attractive it looks. If occasional draft failures are tolerable, define how many retries the workflow can afford. Do not change that allowance after seeing which model struggles.

Retain current-model examples as a baseline when migrating an existing workflow. They show what you need to preserve and why a change is worth making. Record their original model and settings; a previous image with an unknown model is useful as a test input, but it cannot supply a measured baseline for a named model.

Start with one exact-text case

You can learn the process with six planned requests before committing to the full 18-attempt kit. The following is a practice brief, not a completed model test. It uses the template's CASE-02 text-only graphic so you do not need a reference photo.

Save this wording as case-02-prompt.txt:

Create a landscape workshop poster on a pale cream background.
Place the exact heading "Workshop registration" once at the top.
Place the exact sentence "Bring a notebook" once below the heading.
Add a simple illustration of a closed notebook below the text.
Keep the two text blocks separate, with no overlap or clipped characters.
Use dark, clearly readable lettering. Add no other words, logos, or badges.
  1. Copy the scorecard and keep only its six CASE-02 rows before making requests. The other cases remain available in the original template for later tests. Keep high, 1536x1024, PNG, opaque background, and one image per request for both models.
  2. Write the review checklist before running the prompt: both strings appear exactly once; wording and punctuation match; neither line overlaps or clips; the notebook is present; no extra text appears. Inspect the original image and a preview 800 pixels wide. Set your own delivery-time and spend limits for the six attempts.
  3. Run the hash example below with references = [] and this prompt filename. Copy the two digests into all six planned rows. Save a small settings file recording Image API, n=1, max_retries=0, a 180-second client timeout, and sequential execution.
  4. Use the generation example below for run 1 of each model. Then run pairs 2 and 3, alternating which model goes first. Use a distinct filename for every attempt. Keep the same prompt; a correction after seeing an image belongs in a new comparison version.
  5. Review images under neutral names. Put wording defects in text_accuracy, missing elements or unreadable layout in instruction_following, and extra badges or words in unwanted_changes. Use NA for preservation and transparency, with a note that this case has no input image and requires an opaque output. Fill timing, output hash, reviewer, verdict, and confirmed charge from the saved records.
  6. Run the checker on the six-row copy. Record how many images each model produced and how many passed. If a request fails or a charge is unknown, retain that fact; do not fill an invented zero or rerun silently. Use the failure and cost instructions below before interpreting the comparison.

The result applies to this simple poster brief. A successful case does not establish performance on dense diagrams, product labels, translation, or editing. Add representative cases from your actual work before changing a production workflow.

Build cases around the failures your work can encounter

The downloadable scorecard starts with a precise edit, an exact-text graphic, and a transparent asset. Each has three runs per model, for 18 planned attempts. Replace the placeholders with your own files and prompts. The seven situations below are proposed test designs, not reported model outcomes; use the ones your workflow needs.

A local object edit with protected surroundings

Use a reference in which the target touches other objects or casts a visible shadow. Request one change, such as replacing the material of a chair, while preserving its position, camera angle, neighboring furniture, and room lighting. An isolated object on a blank background will not test whether the edit damages nearby details.

Review both the changed region and named protected regions. Record a concrete failure such as "table leg removed beside the edited chair" or "wall sign changed." If the protected area must remain pixel-identical, plan to composite the approved edit onto the original. OpenAI's prompting guidance warns that repeated edits can alter details and recommends compositing for that requirement.

A product image with a label and fixed geometry

Choose a reference that includes the actual label, cap, seams, and proportions. Test a background replacement before trying a new viewing angle, because a new angle introduces visibility and perspective changes. Compare the silhouette and packaging details at full resolution, then check the destination crop.

A label that looks plausible can still be wrong. Transcribe its required wording before generation and compare each word afterward. Reject a changed quantity, invented badge, or altered logo when those features are part of the product brief. If generated labels keep failing, test a workflow that retains the original product cutout and generates only its surroundings. Measure that workflow's compositing and review effort separately.

Exact text in a poster or information graphic

Prepare an approved text file containing every phrase, number, unit, and punctuation mark. Include short headings and the smallest copy you will actually publish. Specify the number of occurrences of each phrase and which text belongs to which part of the layout. For a diagram, also provide the relationships that arrows must express.

Check spelling at full resolution and readability at the intended display size. Correct text in the wrong place can still fail: a caption next to the wrong diagram component changes the meaning. OCR can help locate a discrepancy, but a reviewer must inspect placement, punctuation, and the rendered characters. If exact typesetting remains unreliable, compare generating the artwork without text and adding the approved copy in a layout editor as a separate production method.

A transparent cutout with difficult edges

Include a subject with fine boundaries, such as hair, fabric fringe, or a translucent component. Request background="transparent" and PNG or WebP output. Both model pages document transparent output; JPEG cannot carry the alpha channel this case needs.

Inspect the decoded alpha channel, then place the cutout on white, black, and the actual destination background. Look for opaque rectangles, painted checkerboards, clipped strands, light halos, and shadows you did not request. A file can contain an alpha channel and still have poor edges. A preview that happens to look white proves neither transparency nor acceptable extraction. The separate PNG transparency guide covers file-level checks after download.

A recurring person or character across a sequence

Save an authorized reference and list the visible traits that define the subject. Test a change of setting or pose, then a later edit with a different requirement. Compare facial proportions, clothing details, and distinctive accessories at every step. Background similarity does not compensate for a changed face.

Use two experiments. For a single-step comparison, both models receive the identical original input. For a sequence comparison, each model receives its own preceding output, with the same sequence of instructions. The sequence then measures accumulated drift; its later inputs are deliberately different. Keep it outside the starter checker's fixed-input matrix and log every step and input hash in a separate sequence record.

Translation that preserves a finished layout

Provide approved translated wording beside the original strings so the test can focus on rendering and preservation. Compare accents, line breaks, remaining source-language words, and whether longer phrases overlap artwork. Ask someone who reads the target language to review the result.

Separate translation quality from layout quality. If the model must also produce the translation, score wording against an independently approved translation and record any disagreement. A visually clean graphic with an incorrect phrase fails the language requirement. A correct translation that pushes a label onto the wrong component fails the layout requirement.

Draft concepts and final images at different sizes

For draft concepts, test whether the subject, composition, and usable crop are present. For final images, add the small details that production review will inspect. Save those as separate cases. Do not average them together and conclude that one model is suitable for both.

Include the actual output dimensions and destination resize. A large image that looks convincing when reduced may reveal broken small text at full size, while a detailed image may become unreadable in a small card. Test 4K only when the job needs it. OpenAI treats output above 3,686,400 pixels as experimental, so a successful standard-size test does not establish the same behavior at 4K.

Freeze the request, then change the model

Pin the dated snapshots listed on the model pages: gpt-image-2.5-flare-2026-09-08 and gpt-image-2.5-sunburst-2026-09-08. In the scorecard, model_id holds the undated family name and model_snapshot holds the identifier you send. Recheck available snapshots before executing a later test.

ControlWhat to freezeWhat can invalidate the pair
PromptThe exact submitted UTF-8 text and its SHA-256Adding preservation instructions for only one model.
ReferencesOriginal file bytes, input order, and assigned rolesRe-encoding an image or swapping the subject and style references.
Output settingsExplicit quality, size, format, background, and image countComparing one model's automatic defaults with the other's explicit settings.
ReviewRubric version, required dimensions, and destination cropAccepting a defect for one model that would reject the other.
ExecutionAPI route, retry policy, concurrency, and timeoutComparing sequential requests with a heavily queued batch.

Both models support low, medium, high, xhigh, max, and auto quality. Select an explicit shared setting for the first test. The same label does not promise equal output quality or latency. For a small starting comparison, the kit uses high; that is a test setting, not a claim that it is best for every job.

For custom dimensions, both edges must be multiples of 16 and no longer than 3,840 pixels. The longer-to-shorter ratio cannot exceed 3:1, and total pixels must be between 655,360 and 8,294,400. For example, 1536x864 fits those rules; 1920x500 exceeds the aspect-ratio limit. Follow the current parameter constraints in the official prompting guide.

Save an input manifest with each reference's filename, role, position, and SHA-256. Preserve array order and save the manifest bytes once. Use an empty manifest for text-only generation. The checker compares the manifest hash, but you must retain the manifest and verify that the submitted files match it. Save additional request controls in a small JSON file alongside the CSV; this is the settings sidecar. Start a new comparison version if a control changes.

This local example hashes a prompt and one reference without making a request. For text-only generation, change the prompt filename and set references = []. For several inputs, list them in the order you will submit them and identify each role.

import hashlib
import json
from pathlib import Path

def sha256_file(filename):
    return hashlib.sha256(Path(filename).read_bytes()).hexdigest()

references = [{"file": "reference.png", "role": "source", "position": 1}]
manifest = [dict(item, sha256=sha256_file(item["file"])) for item in references]
Path("input-manifest.json").write_text(
    json.dumps(manifest, sort_keys=True, separators=(",", ":")),
    encoding="utf-8",
)
prompt = Path("case-01-prompt.txt").read_bytes().decode("utf-8")
print("prompt_sha256:", hashlib.sha256(prompt.encode("utf-8")).hexdigest())
print("input_manifest_sha256:", sha256_file("input-manifest.json"))

Hash the exact text passed as prompt. These examples decode UTF-8 file bytes directly so reading the file does not change its line endings. If your application trims whitespace, substitutes variables, or otherwise edits the text, hash and save the final submitted string after those changes.

Make generation and editing requests explicitly

The Image API lets you select the image model directly. In the Responses API, the top-level model is a supported mainline model and the image model belongs in the image-generation tool configuration. Keep the API route fixed across a pair because a conversational workflow introduces more context and orchestration to measure.

These Python examples make one paid request each when you run them. Install the OpenAI SDK with pip install openai and set OPENAI_API_KEY in your environment. The Python SDK normally retries certain errors twice; max_retries=0 makes individual attempts visible during this test. Log any retry you initiate as another attempt.

Confirm that your API project can access both models and has enough budget for the planned requests. Read the returned error before repeating a failure. OpenAI's error guide distinguishes authentication errors from throttling and billing limits: a 429 can mean a rate limit or exhausted credits. Pacing requests can help throttling; it cannot restore exhausted credits. Record these setup or service failures without treating them as poor visual quality.

A text-only generation request

Save your approved prompt as case-02-prompt.txt, or use the practice brief above. This example follows the generation request reference. It saves one original PNG and the response JSON; add the timing statements in the next section before making a measured request.

import base64
from pathlib import Path
from openai import OpenAI

client = OpenAI(max_retries=0, timeout=180.0)
model = "gpt-image-2.5-flare-2026-09-08"
prompt = Path("case-02-prompt.txt").read_bytes().decode("utf-8")

result = client.images.generate(
    model=model,
    prompt=prompt,
    quality="high",
    size="1536x1024",
    output_format="png",
    background="opaque",
    n=1,
)
image_bytes = base64.b64decode(result.data[0].b64_json)
Path("case-02-flare-run-1.png").write_bytes(image_bytes)
Path("case-02-flare-run-1-response.json").write_text(
    result.model_dump_json(), encoding="utf-8"
)

For its Sunburst pair, change the model to gpt-image-2.5-sunburst-2026-09-08 and use a distinct output filename. Keep the prompt and settings identical. Give each later run its own filename and retain the original bytes. The response JSON preserves the returned fields; it does not replace the review, timing, and charge record.

An edit request with a reference image

Save a prompt that identifies the edited object and every protected detail as case-01-prompt.txt, and keep the original reference as reference.png. The Python edit reference documents the file input used here. Keep the same reference for both models and every run of this single-step case.

import base64
from pathlib import Path
from openai import OpenAI

client = OpenAI(max_retries=0, timeout=180.0)
prompt = Path("case-01-prompt.txt").read_bytes().decode("utf-8")

with Path("reference.png").open("rb") as reference:
    result = client.images.edit(
        model="gpt-image-2.5-flare-2026-09-08",
        image=reference,
        prompt=prompt,
        quality="high",
        size="1536x1024",
        output_format="png",
        background="opaque",
        n=1,
    )
Path("case-01-flare-run-1.png").write_bytes(
    base64.b64decode(result.data[0].b64_json)
)
Path("case-01-flare-run-1-response.json").write_text(
    result.model_dump_json(), encoding="utf-8"
)

For the transparent-asset case, freeze a new prompt and set background="transparent" for both models. Keep PNG output. Do not mix transparent and opaque requests under the same case ID. Check parameter support before copying controls from older image models.

Review each result against observable requirements

Hide model names during the first visual review and assign neutral image IDs. Review the full-resolution file beside the input, then inspect the destination crop or composite. Write a short defect note that another reviewer can locate. "Poor quality" gives you less to fix than "the second line says notebooks instead of notebook."

Scorecard dimensionA usable checkExample reason to fail
instruction_followingRequested subject, change, composition, and placement are present.The background changes, but the requested object replacement is missing.
preservationNamed protected identity, shape, labels, and regions remain acceptable.The product cap or person's distinctive accessory changes.
text_accuracyRequired strings are correct, readable, and attached to the right elements.A unit changes or the heading appears twice.
unwanted_changesNo prohibited addition, removal, or restyling appears.The model adds a badge to packaging or removes a neighboring object.
transparencyDecoded alpha and composited edges meet the destination requirement.A checkerboard is painted into an opaque image.

Use NA only for a dimension the case does not require, and explain it in notes. For example, a landscape scene without required wording can have text_accuracy=NA. A poster with misspelled required copy cannot. In this checker, any dimension marked FAIL requires human_verdict=FAIL.

The five CSV dimensions do not include a separate visual-quality score. Put your job's visible quality requirements into the rubric before generation: for example, a product image must have intact edges and plausible geometry, while a poster must have legible lettering and no overlapping blocks. A visible defect that makes the output unusable fails instruction_following; describe it in notes. For aesthetic preference among otherwise usable images, keep a separate blind preference record. Do not silently change which images qualify for the cost calculation.

An image verdict and a model decision are separate. Reject an image that violates its brief. Decide whether the model is suitable from the predeclared acceptance and critical-failure rules across that workload. Three clean runs are an exploratory result; they cannot establish that the model will never change a label. Report the number of attempts and observed failures alongside any conclusion.

Record latency, failures, and the cost of accepted images

For the snippets above, record a UTC timestamp immediately before the API call and a second after decoding and saving the complete image. Keep the same timing boundary for both models. The checker requires valid timestamps ending in Z and a latency_ms value equal to their difference, rounded to milliseconds. A streaming preview is a separate measure; it is not the complete image.

Wrap the request and image-save statements with these timestamp statements, then copy the values into the CSV. Hash the saved PNG bytes for result_sha256. Retain the response and timing sidecar under the same case, model, and run identifier.

from datetime import datetime, timezone

started = datetime.now(timezone.utc)
# Place the API call, image decoding, and image save here.
completed = datetime.now(timezone.utc)

started_at_utc = started.isoformat().replace("+00:00", "Z")
completed_at_utc = completed.isoformat().replace("+00:00", "Z")
latency_ms = round((completed - started).total_seconds() * 1000)

If a request returns an error without a reviewable output, use REQUEST_FAILED, record its start and finish, and explain the error in notes. Leave image-hash and review fields blank. A returned image rejected by the reviewer is COMPLETE with human_verdict=FAIL. Keep timeouts in the evidence and label them as timeouts; the time until the client stops waiting is not a completed-image latency.

Record confirmed request charges where available and retain the supporting billing record. If you calculate a provisional cost from returned usage and published token rates, label that calculation as an estimate in a sidecar and reconcile it before filling the checker's confirmed-charge field. Missing cost is unknown, not zero. You can review image quality while cost reconciliation is pending, but you cannot claim a measured cost winner. The checker requires a numeric charge for each attempted request, so a blank charge produces a structural FAIL. Keep the executed status and missing charge in the working record until reconciliation; changing it to NOT_RUN would hide an attempt.

The two current model pages list the same token rates. That does not establish the same request charge: token use and retries still matter. Recheck those pages when you execute the test. For a two-stage workflow that drafts with Flare and finishes with Sunburst, include both stages, rejected drafts, and final-image acceptance in the route's total.

acceptance_rate = accepted_outputs / request_attempts
cost_per_accepted_image = total_confirmed_request_cost / accepted_outputs

If accepted_outputs == 0:
    report NO_ACCEPTED_OUTPUT
    leave cost_per_accepted_image undefined

Consider a hypothetical calculation, not a model result: route A spends $0.60 across six attempts and yields three accepted images, so each accepted image costs $0.20. Route B spends $0.80 across six attempts and yields five accepted images, so each costs $0.16. The smaller total spend produces the higher cost per usable image in this example. If human cleanup is material, report review and repair time beside API cost.

Run the first pairs at the same concurrency and alternate which model goes first. Later, test the concurrency your service will use as a separate experiment. Report acceptance and cost by case before pooling totals. The checker also reports median, p90, and maximum duration across all attempts, including failed requests. Separate successful-image durations in your analysis so fast errors do not look like fast delivery. With only three attempts in a case, nearest-rank p90 is the maximum; treat it as a small-sample observation.

Run the kit and understand its limits

Download the comparison kit and extract the files into one folder. It contains the protocol, editable CSV, checker, and synthetic self-test record. Python 3 can run the checker without the OpenAI SDK, an API key, or a paid request.

python3 gpt-image-2-5-comparison-gate.py --self-test
python3 gpt-image-2-5-comparison-gate.py gpt-image-2-5-comparison-scorecard.csv

The first command should report 12 passing tests. The untouched template should report HOLD, 18 NOT_RUN rows, and exit code 2. Fill each row only with retained evidence. Use the exact CSV headers; keep request IDs, input manifests, additional controls, and billing evidence in sidecar files.

Checker resultMeaningNext action
FAILThe CSV violates a structural rule.Correct the record or rerun a mismatched case without discarding its earlier evidence.
HOLDAt least one planned row remains unexecuted.Keep the comparison incomplete.
EVIDENCE_COMPLETEEvery planned attempt is recorded and internally consistent.Apply the human review and workflow decision rules.

The checker validates digest formats, timestamps, matched snapshots, paired runs, and frozen fields. It rejects duplicate result hashes and requires at least three pairs per case. It does not open your images, recompute hashes from saved files, verify the bill, judge visual correctness, or approve a model. Its model summaries pool cases, so review each case separately before using the aggregate.

A retry also needs a record. The matched checker requires one attempt from each model for every run ID, so run another matched pair when adding a retry round to this experiment. Keep asymmetric production retries in a separate operational log instead of inventing a matching request. If two saved outputs truly have identical bytes, retain both and investigate; do not alter a file merely to evade the duplicate-hash check.

The files are also available individually: protocol, scorecard, checker, and synthetic self-test record.

Resolve failures before choosing a production route

Observed problemWhat to checkNext experiment
Both models miss a named requirementIs the wording explicit, and do references have clear roles?Clarify that requirement for both models in a new version.
Text is correct at full size but unreadable after resizingCheck the destination crop, type size, contrast, and layout density.Test a simpler layout or separately typeset copy.
A local edit changes protected detailsInspect the target and each protected region against the original.Test a narrower edit or a compositing route that retains protected pixels.
The PNG has poor transparencyVerify the request background, decoded alpha, and edges on contrasting backgrounds.Fix extraction or edge treatment and rerun the same visual review.
Responses become slow or error-prone under loadInspect concurrency, rate-limit responses, timeout, and retries.Separate service-load testing from the sequential visual comparison.
One model fails only after several editsLocate the first step that changes a protected trait.Test that step from the original reference and test the complete sequence separately.

After the initial matched comparison, tune one setting at a time. If neither model passes at high, test a supported higher setting against the unmet requirement. If both pass, test whether a lower setting preserves acceptance while reducing time or cost. Keep each setting trial in a separate version so you can see which change helped.

Then compare each model's best qualifying configuration for the actual job. Flare at a higher setting and Sunburst at a lower setting may be a useful production comparison if both satisfy the same requirements. Report the different settings and evaluate the complete routes; the result does not isolate a model-only difference. Include extra attempts, compositing, and manual repair needed by either route.

A one-image difference across three runs per model is a reason to investigate. Report counts such as "two accepted out of three," repeat uncertain cases, and expand to representative prompts and references before making a reliability claim. If acceptance changes with the reviewer, resolve the rubric disagreement first. If speed differences vary with request order or time of day, collect additional batches under the same controls before promising an operational gain.

Choose a route for each workload. When one candidate meets its requirements and the other fails, use the passing candidate only if it also meets the service's operational limits. When both qualify, compare confirmed cost per accepted image and delivery time within the declared budget. If neither qualifies, use the revised or composited workflow and evaluate it before rollout.

Move a small share of production work to the selected route and keep recording the same measures. Write down the condition that triggers rollback, such as a protected-label failure or acceptance dropping below the declared target. Keep the previous supported route available and expand only after the production inputs continue to meet the requirement.

For prompt construction and reference roles, use the GPT Image 2.5 prompt guide. The real-photo editing guide provides retained editing cases you can adapt as fixtures. Preserve their original evidence labels: outputs with an unknown served model cannot be relabeled as Flare or Sunburst results.