Change only one thing in an AI image edit: prompt template and mask

How to edit one detail of an image without the rest drifting: a keep-and-change prompt template for GPT Image 2.5, then a mask_url fallback. Code and prices.

5 min readSume
All posts

To change only one thing in an image, send the image as an input_references entry, name the single change, and list what must stay identical. If the prompt alone still shifts other parts, add a mask_url so only the masked region can change. Both are GPT Image 2.5 features on Sume.

The failure to avoid is a vague edit like "make it nicer". The model has no way to know which parts you like, so it may redraw them all.

A template that holds

Write three short sentences. First the change: "Change the bicycle color from red to teal." Second the keep list: "Keep the person, the street, the lighting, the framing and every shadow exactly as they are." Third the guard: "Do not add or remove any object." Order matters little, but the keep list must be explicit.

The fal Sunburst page describes the variant as built for editing precision and scoped edits, so move to openai/gpt-image-2.5-sunburst when Flare still drifts. Set aspect_ratio to auto so the output keeps the source frame.

One-change edit levers on Sume (read 2026-10-05)
LeverFieldWhen
Keep list in promptpromptAlways
Edit-tuned variantmodel: openai/gpt-image-2.5-sunburstFlare drifts
Region maskmask_urlPrompt still moves other parts
Source frameaspect_ratio: autoKeep the original shape
Lossless sourcePNG referenceChained edits

Request

Reference URLs must be public HTTPS, and Sume answers 400 input_media_unreachable when it cannot download one. A file on your laptop needs a public upload first, for example through the assets upload flow.

import os, requests
H = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}

def generate(body):
    r = requests.post("https://api.sume.com/v1/images", headers=H, json=body, timeout=60)
    if r.status_code != 200:  # 202 = still running, read data.status_url
        raise SystemExit(f"{r.status_code}: {r.text[:300]}")
    return r.json()["data"][0]["url"]
from io import BytesIO
from PIL import Image

url = generate({
    "model": "openai/gpt-image-2.5-sunburst",
    "prompt": "Change the bicycle color from red to teal. Keep the person, street, lighting, framing and every shadow exactly as they are. Do not add or remove any object.",
    "input_references": [{"type": "image_url", "image_url": {"url": "https://example.com/street.png"}}],
    "aspect_ratio": "auto",
    "quality": "high",
})
Image.open(BytesIO(requests.get(url, timeout=60).content)).save("edited.png")
print("saved edited.png")

Cost of an edit

GPT Image 2.5 is billed on tokens. The fal pages list $30 per million output image tokens, $8 per million image input tokens and $5 per million text input tokens. Sume bills the provider list price times 1.25. The table is output-only, so reference and prompt tokens add a little on top of it.

Output-only price at 1024x1024 by quality (read 2026-10-05)
QualityProvider listSume at list x 1.25
medium$0.0132$0.0165
high$0.0527$0.0658

Mask fallback

When the prompt is not enough, create a mask image the same size as the source, host it at a public HTTPS URL and add it as mask_url. Keep the prompt focused on the masked area. With several references, check which image the mask applies to before you ship, as the related mask post explains.

If the call returns 202

POST /v1/images waits up to 30 seconds and returns 200 with the images. A slow job falls back to a 202 job envelope, and you read the images from GET /v1/jobs/{id}/result. The code above exits on any non-200 so you notice, and a failed synchronous job returns 502 and is not billed.

Check what moved

Put the source and the result side by side and flip between them at 100 percent. Look at the edges of the changed object first, then at faces, text and shadows, which drift most. If something else moved, add it to the keep list by name and run again at low quality to save cost. Save each accepted result as a PNG, because a JPEG in the middle of a chain adds compression you cannot undo.

Sources

Related posts

More in Use cases

All Use cases posts

Written by Sume