One layout reference, twenty posters: GPT Image 2.5 on Sume
ChatGPT Images 2.5 ships poster templates. On the API, reuse one layout image as a reference and change only the headline: 20 calls.

OpenAI's Images 2.5 thread lists pre-designed formats for posters and merchandise that make customising faster (OpenAI Developer Community, read 2026-10-04). Those templates live inside ChatGPT. If you need your own template over an API, a single reference image can do the same job.
The recipe
ChatGPT Image 2.5 accepts up to 16 reference images on Sume, and edits with no size keep the source geometry (Sume Image API). Build one approved poster layout, host it at a public HTTPS URL, and send it as the reference with a prompt that changes only the text.
- Image 1 is the layout. Keep its grid, type size and logo position.
- Put the new headline in quotes and say how many times it appears.
- Say nothing about style beyond "same as the layout", so the model has less to change.
- Use
aspect_ratio: "auto"so the output matches the layout's shape.
Cost of twenty
The catalog lists ChatGPT Image 2.5 at a high-quality 1024 px rate of about $0.0659 after Sume's margin, but it bills by tokens, so a larger poster at higher quality costs more. At the catalog figure twenty posters are about $1.32. Read usage.cost on each response and total it rather than trusting the estimate.
| Posters | Per image (catalog) | Total (catalog) | What can raise it |
|---|---|---|---|
| 20 | about $0.066 | about $1.32 | Quality xhigh or max, larger size |
The loop
Check each result for a misspelt or doubled headline before it ships.
import os
import requests
h = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
LAYOUT = "https://example.com/poster-layout.png"
headlines = ["Autumn Sale", "Winter Market"]
total = 0.0
for text in headlines:
body = {
"model": "openai/gpt-image-2.5",
"prompt": f'Keep the layout of Image 1 exactly. Change the headline to "{text}", shown once.',
"input_references": [{"type": "image_url", "image_url": {"url": LAYOUT}}],
"aspect_ratio": "auto",
}
r = requests.post("https://api.sume.com/v1/images", headers=h, json=body, timeout=90)
if r.status_code == 200:
total += r.json()["usage"]["cost"]
print(text, r.json()["data"][0]["url"])
else:
print(text, r.status_code, "read the job envelope")
print("billed", total)
Sources
Related posts
More in Use cases
- One video in three languages: per-language voiceover tracks on Sume
Render scene lines in each language with TTS, join each language into one track with timeline audio concat, then re-base scene starts from segments[].
- Online course trailer in 30 seconds with Seedance 2.5: beats and cost
A 30-second course trailer in one Seedance 2.5 request: beats for hook, promise and call to action, authored captions on top, about $17.33 at 720p on Sume.
- Out-of-office video message with an AI avatar: 15 seconds on Sume
Make a 15-second out-of-office video from a script: return date, contact, captions on. $2.76 on Standard plus a $0.20 caption add-on; Plus and Max too.
- Parent-teacher conference reminder in English and Spanish for $0.63
A conference reminder from one slide image in two languages: TTS, a Timeline render and captions per version. $0.6333 for both on Sume, from docs.
Written by Sume