Cheapest Sume image model for a 21:9 banner from a reference photo
Qwen Image at $0.025 is the cheapest row listing 21:9 with reference input. Flux 2 Pro is next at $0.0375. A short script finds it live.

The cheapest Sume image row that lists 21:9 and accepts reference images is Qwen Image at $0.025 per image, followed by Flux 2 Pro at $0.0375, Flux 2 Flex at $0.0625, Nano Banana 2.1 at $0.10 and Nano Banana Pro at $0.1875. Qwen Image Max and Recraft V4 also list 21:9, but neither accepts references. That is the catalog on origin/main, read 2026-10-08. Because the catalog changes, the script below runs the same filter against the live API.
It reads GET /v1/images/models, keeps the rows whose aspect_ratio descriptor includes 21:9 and whose input_references maximum is above zero, fetches each row's endpoint record, and prints the billed cost_usd.
The ranked answer
Prices are the endpoint pricing line, which is the billed figure for one image at the row's default settings.
| Model id | Billed per image | Reference images |
|---|---|---|
| qwen/qwen-image | $0.025 | Up to 10 |
| black-forest-labs/flux.2-pro | $0.0375 | Up to 10 |
| black-forest-labs/flux.2-flex | $0.0625 | Up to 10 |
| google/nano-banana-2.1 | $0.10 | Up to 10 |
| google/nano-banana-pro | $0.1875 | Up to 10 |
The script
It needs SUME_API_KEY in the environment and the requests package. It makes one list call and one endpoints call per matching row.
import os, requests
base = "https://api.sume.com/v1/images/models"
headers = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
models = requests.get(base, headers=headers, timeout=30).json()["data"]
rows = []
for m in models:
p = m["supported_parameters"]
ratios = p.get("aspect_ratio", {}).get("values", [])
refs = p.get("input_references", {}).get("max", 0)
if "21:9" in ratios and refs > 0:
e = requests.get(f"{base}/{m['id']}/endpoints", headers=headers, timeout=30)
price = e.json()["endpoints"][0]["pricing"][0]["cost_usd"]
rows.append((price, m["id"]))
for price, model_id in sorted(rows):
print(f"{price:.5f} {model_id}")
Reading the result
The output is ascending by price. Change "21:9" and the reference test to answer other questions, such as the cheapest row with 4:5 and no references. Only the contract fields in the descriptors are used, so a row added later is picked up without edits.
A reference-photo edit that must keep its shape should also set aspect_ratio on purpose. Docs say auto matches the reference on edit calls, while omitting the field is not the same as auto, and Qwen Image's list has no auto, so name 21:9 in the request.
Cheapest is not the same as best. The script answers a narrow question about what the contract allows and what it costs, and it cannot tell you which result looks right for your photo. Take the top two or three rows from its output and generate one banner on each before you commit to one.
The list call returns capabilities for every row in one response, so the script is fast to run and its only per-row cost is the endpoints lookup. If you run it often, cache the results for a short time.
Sources
Related posts
More in Developers
- Check ad video length for Pinterest, LinkedIn and Google in Python
A short Python check of a video-inspect probe against Pinterest, LinkedIn and Google Video action length limits read on 2026-10-08, before you upload an ad.
- Check Sume webhook signatures in Python with hmac.compare_digest
A Python verifier for the sume-v1 header: raw bytes, constant-time compare, 300 s replay window, empty-secret refusal, and a Flask route that dedupes on job_id.
- Claude per-message effort: drop to low while a Sume job runs
Claude's per-message effort beta keeps the prompt cache when you change effort mid-conversation. How to use it around Sume jobs, and its Haiku 5.5 limit.
- Claude tool search limits: 200-char regex, 500-char BM25, 5 results
Claude's tool search tool has fixed limits on pattern length, results and deferred tools. What they mean for a Sume hosted MCP tool list.
Written by Sume