FLUX.3 not on Sume yet: detect it via /v1/images/models, fall back
Sume does not list FLUX.3. A Python script reads /v1/images/models, uses FLUX.3 if it appears, else Nano Banana 2.1 at 2K for $0.15. BFL 2k is $0.100.

Sume does not list FLUX.3 Image. Its public catalog shows flux-2-flex and flux-2-pro rows and no flux-3 entry (read 2026-10-09). Rather than hard-code a guess, ask the API: GET /v1/images/models returns the ids Sume can run, and the script below looks for one containing flux-3 and otherwise uses google/nano-banana-2.1 at 2K, which costs $0.15 per image on Sume.
The two prices
Black Forest Labs lists FLUX.3 Image at $0.041 for 768x768, $0.048 for about 1 MP, $0.100 for about 4 MP (2k) and $0.607 for about 16 MP (4k), with 1 credit equal to $0.01. Those are the vendor's prices on its own pricing page, not Sume prices, because Sume does not list the model. The fallback is a different model, so the comparison below is about cost, not about the look of the image.
| Option | Size | Price per image | Where the price comes from |
|---|---|---|---|
| FLUX.3 Image (BFL) | 2k, about 4 MP | $0.100 | BFL docs; not available on Sume |
| FLUX.3 Image (BFL) | 1k, about 1 MP | $0.048 | BFL docs; not available on Sume |
| nano-banana-2.1 (Sume) | 2K | $0.15 | Sume price list |
| nano-banana-2.1 (Sume) | 1K | $0.10 | Sume price list |
| flux-2-pro (Sume) | default | $0.0375 | Sume price list |
The detection script
The script lists model ids, picks the first id with flux-3 in it, and prints which path it took. It then posts to /v1/images with an Idempotency-Key and branches on the status code, not on the body shape: 200 is the finished image response and 202 is a job envelope with a status_url to poll. POST /v1/images waits up to 30 seconds, and slow settings such as 4K, high quality or a large n are the most likely to return 202.
import json, os, urllib.request
BASE = "https://api.sume.com"
HEADERS = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"], "Content-Type": "application/json"}
def call(path, body=None, key=None):
headers = {**HEADERS, **({"Idempotency-Key": key} if key else {})}
req = urllib.request.Request(BASE + path, json.dumps(body).encode() if body else None, headers)
with urllib.request.urlopen(req) as r:
return r.status, json.load(r)
_, listing = call("/v1/images/models")
ids = [m["id"] for m in listing["data"]]
flux3 = [i for i in ids if "flux-3" in i]
model = flux3[0] if flux3 else "google/nano-banana-2.1"
print("model:", model, "(FLUX.3 listed)" if flux3 else "(no FLUX.3 in the catalog)")
status, out = call("/v1/images", {"model": model, "prompt": "Matte black bottle on marble",
"resolution": "2K", "aspect_ratio": "1:1"}, "flux3-fallback-001")
if status == 200:
print(out["data"][0]["url"], out["usage"]["cost"])
else:
print("202: poll", out["data"]["status_url"])Make the fallback explicit
Log which model ran, and expose it to whoever pays. A silent switch from FLUX.3 to another model changes both price and style. Also keep the fallback id in a config value so that a person can change it without a deploy.
When FLUX.3 does show up in the listing, the script's substring match picks it, but check supported parameters first: models differ in accepted resolutions and aspect ratios, and the endpoints route shows the per-endpoint price lines for the id you are about to use.
A small budget example: four images at 2K cost 4 x 0.15 = $0.60 on the Nano Banana 2.1 fallback. At BFL's 2k price the same four would be 4 x 0.100 = $0.40, but that is only a comparison, because Sume cannot run the FLUX.3 request. Do not quote the BFL number to a customer as a Sume price.
The script also shows how to write a feature check that cannot go stale: the decision is made from the live listing on each run, and the printed line says which path was used. Put that line in your job log and you can answer later why a batch ran on one model and not another.
- Match on the listing, never on a hard-coded date.
- Compare the cost line with the vendor price once the model appears.
- Keep flux-2-pro as the cheap option if you need FLUX-family output now.
Sources
Related posts
More in Developers
- Format run expires_at: a 90 minute ceiling for your Python poll loop
A Sume Format run receipt has an expires_at deadline: 90 minutes from creation, sooner if the run goes quiet. Use it as your loop ceiling, with Python backoff.
- Four status vocabularies in the Sume API: job, resource, run, delivery
Jobs say queued and processing, resources say ready, deliveries say exhausted, queue-shaped fields say IN_QUEUE. A table so a client branches on the right one.
- frame_images or image_url? Image-to-video fields on Sume's two APIs
Sume's /v1/videos uses frame_images and input_references; /v1/video-router/generate uses image_url, end_image_url and reference_*_urls. A field-by-field map.
- Game NPC barks: 150 short lines in one TTS job (43 cents) vs 150 jobs
Short lines cost 1 cent each as separate Sume TTS jobs. One job with sentence slices returns the same 150 lines as separate WAV files for 43 cents.
Written by Sume