Pick the cheapest Sume image row for a ratio and 3 refs (Python)

A 24-line Python script reads GET /v1/images/models and the endpoints route, filters by aspect ratio and reference count, and sorts by billed price.

6 min readSume
All posts

To find the cheapest Sume image row that takes a given aspect ratio and a given number of reference images, call GET /v1/images/models, keep the rows whose aspect_ratio list contains your ratio and whose input_references max is at least your count, then read each survivor's price from its endpoints route and sort. The script below does exactly that in under 30 lines of standard-library Python.

New image rows keep arriving, and a row you picked last month may no longer be the cheapest one that fits. The catalog descriptors and the pricing lines are published for this reason: the Image API docs say you can find what a model supports before you call it, and that the endpoint pricing lines are what Sume charges.

The script

It needs only SUME_API_KEY in the environment. The list route gives supported_parameters for each model; the endpoints route gives pricing, a list of billable lines. Image rows publish one output_image line in dollars per image, so the first entry is the one to read. The docs show the endpoints response without a data wrapper, and the script tolerates either shape.

import json, os, urllib.request

BASE = "https://api.sume.com"
KEY = os.environ["SUME_API_KEY"]

def get(path):
    req = urllib.request.Request(BASE + path, headers={"Authorization": "Bearer " + KEY})
    with urllib.request.urlopen(req, timeout=30) as r:
        return json.load(r)

def pick(ratio, refs):
    rows = []
    for m in get("/v1/images/models")["data"]:
        sp = m["supported_parameters"]
        ratios = sp.get("aspect_ratio", {}).get("values", [])
        max_refs = sp.get("input_references", {}).get("max", 0)
        if ratio in ratios and max_refs >= refs:
            ep = get("/v1/images/models/" + m["id"] + "/endpoints")
            ep = ep.get("data", ep)
            rows.append((ep["endpoints"][0]["pricing"][0]["cost_usd"], m["id"]))
    return sorted(rows)

for price, model in pick("4:5", 3):
    print(f"{price:.5f}  {model}")

What it printed against the catalog I read

I did not call the live API for this post. I ran the same filter over the catalog code on origin/main, which builds the descriptors and prices that the routes publish, for a 4:5 ratio with 3 references. Thirteen rows qualified on 2026-10-10. Rows that do not list 4:5 (Grok Imagine, Higgsfield Soul, Imagen 4) and rows that take no references (Recraft V4, Qwen Image Max, Imagen 4) drop out.

Rows that list 4:5 and take 3 or more references, billed price per image, catalog read 2026-10-10
RowBilled per image
Qwen Image$0.025
Seedream 4.0$0.0325
FLUX.2 Pro$0.0375
Seedream 5.0 Lite$0.04375
Seedream 4.5$0.05
FLUX.2 Flex$0.0625
ChatGPT Image 2.5 and 2.5 Sunburst$0.065875 each
Ideogram V3 and Ideogram 4.5$0.075 each
Nano Banana 2.1$0.10 (1K)
Nano Banana Pro$0.1875 (1K)
ChatGPT Image 2$0.26375

Caveats before you trust the order

The price line is the default tier. Nano Banana 2.1 is $0.10 at 1K but $0.20 at 4K, and ChatGPT Image 2.5 is quoted at high quality and 1024 square, with other sizes and qualities admitted at their own estimate. Ideogram 4.5 is quoted at its default medium quality; low is cheaper and high is more expensive. If your job uses a non-default tier, add that tier's price to the table by hand.

Cheapest is not the same as right. The filter says nothing about how a row handles your product photo or your headline text. Use it to cut 19 rows to a shortlist, then generate one image on each of the top three and look at them.

  • Read the descriptor max for references, not the docs prose, because it can change per row.
  • Treat a row missing from the list as unavailable: the catalog hides rows whose provider is not configured.
  • Cache the table for the length of one batch, not for a month.

Make the filter fit your pipeline

Add n to the filter if you want several variants per call: Grok Imagine's n range is 1 to 1, so a four-variant job needs four calls on that row. Add resolution if you need a tier: only five rows list it. Add quality to keep GPT and Ideogram rows that expose a quality ladder.

Keep the output as data rather than printing it. A nightly job that writes the sorted rows to a file lets you diff today's shortlist against yesterday's and notice when a price moves or a row appears.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume