Change the price on an ad banner for each market: an edit loop
One banner, three markets: a Python loop that sends one edit per price with an Idempotency-Key, so a retry never pays for the same banner twice.

To change one number on an ad banner for several markets, send one edit call per market: the original banner as a reference, a prompt that names the exact old and new text, and aspect_ratio: "auto" so the output keeps the banner's shape. Give each call its own Idempotency-Key, so a retry after a timeout reuses the same job.
Text replacement that keeps layout is the headline feature of Ideogram 4.5 on Higgsfield, listed 2026-09-30 (Higgsfield changelog, read 2026-10-02). On Sume the same task runs on a listed model: ChatGPT Image 2.5 takes up to 16 references.
What does one edit call look like?
The reference goes in input_references as a public HTTPS URL. On edit calls Sume's docs say to prefer aspect_ratio: "auto" to match the reference, and note that omitting the field is not the same as auto.
The loop below sends three markets. mode: "async" returns a job envelope, so a slow edit never blocks the loop.
import os
import requests
URL = "https://api.sume.com/v1/images"
HEADERS = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
BANNER = "https://example.com/banner-us.png"
PRICES = {"us": "$49", "uk": "GBP 39", "de": "EUR 45"}
for market, price in PRICES.items():
body = {
"model": "openai/gpt-image-2.5",
"prompt": f"Replace the price text '$49' with '{price}'. "
"Change nothing else: same layout, fonts, colours.",
"input_references": [{"type": "image_url",
"image_url": {"url": BANNER}}],
"aspect_ratio": "auto",
"mode": "async",
}
headers = {**HEADERS, "Idempotency-Key": f"banner-v3-{market}"}
r = requests.post(URL, headers=headers, json=body, timeout=60)
print(market, r.status_code, r.json().get("status_url"))Why one call per market?
Each market is a separate paid job with its own result, so one failure does not take the others down. Sume bills image generation all-or-nothing: a completed generation is billed in full, and a failed or cancelled one is not billed.
Reuse an idempotency key only for an exact retry; the docs say to reuse a key only for the same operation and payload, so a changed price gets a new key.
| Situation | What Sume does |
|---|---|
| Same key, same payload | Exact retry of the same operation |
| Same key, different payload | Not a retry; use a new key |
| Failed generation | Not billed |
| Completed generation | Billed in full |
How do I check the result?
Read each job's result for data[].url or result.artifacts[], then check the dimensions and the text by eye. A model can still drift on a small number, so a human glance per market is the cheap safeguard; the QA check post covers the dimension test.
Sources
Related posts
More in Use cases
- Bedtime story audio: slow narrator and lullaby bed on Sume
Make a bedtime story track: slow TTS narration, an instrumental lullaby from Music, mixed with Timeline ducking, then an mp3. Steps and cost.
- beehiiv audio block: make the MP3 from a video issue
beehiiv posts take mp3, wav, ogg, flac, aac and webm audio. Pull a 128 kbps MP3 out of your video issue with Sume's audio detach, $0.01 a job.
- Black Friday audio ad read: a TTS voice over a music bed
Produce a 30-second Black Friday ad read: write to character count, generate with Sume TTS, add a short music bed and mix. Costs and limits included.
- Blind-test AI music models with one brief: Sume Music Router ids
New music models launch monthly (Suno v6, ElevenLabs Music v2.5). A simple blind test with one brief, and the three routable ids Sume's router accepts.
Written by Sume