Product photo variants in one call: the n parameter on Sume Images
Ask for several product photo variants in one POST /v1/images with n, read each model's ceiling from the catalog, and keep the cost predictable.

Send n on POST /v1/images to get several variants from one request. The Sume docs allow up to 10 per call, but each model has a lower ceiling, so read the n range descriptor from GET /v1/images/models before you pin a number. Slow settings such as 4K, high quality and a large n are the most likely to return a 202 job envelope instead of an immediate 200.
Variants are how a seller picks a main image: five backgrounds, three crops, two moods. With ChatGPT's new shopping experience showing items in context on a shopper's own photo (read 2026-10-03, OpenAI help page), a store's own product photos have to hold up next to them, and choosing among variants is the cheapest way to improve them.
The request and the response
A request with input_references and n: 4 edits the first reference and returns up to four images in data. Each entry has a Sume-hosted url on media.sume.com and a media_type. The usage.cost field is the total, so divide by the number of images you received to get the per-image figure.
| Field | Value | Note |
|---|---|---|
n | 1 to 10 per docs | Per-model ceiling is lower; read the catalog |
quality | auto, low, medium, high, xhigh, max | Catalog-gated |
aspect_ratio | auto on edits | Matches the reference |
input_references | Product photo | Public HTTPS only |
| Status | 200 or 202 | Branch on status code, not body shape |
import os, requests
r = requests.post(
"https://api.sume.com/v1/images",
headers={"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"},
json={
"model": "openai/gpt-image-2.5",
"prompt": "Keep the product exactly as shown. Place it on a pale oak table by a window, soft morning light.",
"n": 4,
"quality": "medium",
"aspect_ratio": "auto",
"input_references": [
{"type": "image_url", "image_url": {"url": "https://cdn.example.com/sku/mug.jpg"}}
],
},
timeout=120,
)
if r.status_code == 200:
for d in r.json()["data"]:
print(d["url"])
else:
print(r.status_code, r.json())Choosing the winner
Look at the product before the background: label text, handle shape, colour. A variant with a prettier scene and a wrong logo is worse than a plain one with the right logo. Then compare the five that pass at a thumbnail size, since that is how a shopper will meet them.
If every variant has the same flaw, the prompt is the cause, so change the prompt rather than raising n. Raising n buys more draws of the same mistake. For a flaw in one place, such as a cropped handle, name it in the next prompt.
A 202 means the work is a job now; poll it and read the images when it finishes. Failed or cancelled generations are not billed. Keep the Idempotency-Key discipline you would use for video, so a retry after a timeout does not run the batch twice.
Keeping the cost predictable
Cost scales with n and quality. Use medium while you search, then re-render only the chosen composition at high or above. Read the model's price in the catalog and multiply it yourself before a bulk run. If a reference URL cannot be fetched you get an input error rather than a charge; the image-not-fetchable post explains the usual causes.
For edits, set aspect_ratio to auto rather than leaving it out, as the auto versus omitted post explains. For a try-on rather than a product scene, start from the screenshot try-on post.
Naming the variants you keep
Store each chosen variant with the prompt, the model id, n, the seed-free settings you used, and the Sume URL. The API does not serve seed, so you cannot reproduce an image from a number; you can only reuse the prompt and the reference and draw again. That makes the stored URL the real asset, and the prompt a template for the next draw.
Keep the rejects too, for a short time. When someone asks why a variant looked wrong, the full set shows whether it was one bad draw or a prompt that never worked. Delete them on a schedule you set in advance.
Sources
Related posts
More in Developers
- Prompt cache diagnostics are GA: why did my video agent miss?
Anthropic took cache diagnostics out of beta on Sep 23 and OpenAI made them GA on Sep 8. What each reports, and where Sume's run receipt fits in.
- Prove a voiceover read the approved script: the transcript receipt
A source-bound Sume TTS job carries a transcript receipt with the revision, sentence IDs and a SHA-256. It proves the text sent, not how it was pronounced.
- PWA manifest icons: any, maskable and monochrome from AI images
Make the three PWA icon purposes with the Sume image API: transparent, full-bleed maskable and one-color monochrome masters, plus the cost of each.
- Pydantic AI ToolCallJudge: check a Sume paid call before it runs
Pydantic AI 2.53.0 adds ToolCallJudge to assess tool calls before execution. Pair it with Sume's dry_run and max_spend_usd on paid calls.
Written by Sume