Build an AI image progress UI: gate on supports_streaming false
Sume's image catalog reports supports_streaming false on every row. Build the progress UI from job states and gate a live preview on that field.

To build an AI image progress UI on Sume, read supports_streaming from GET /v1/images/models and show a live preview only when it is true. Today the field is false on every row, and a request with stream returns 400 streaming_not_supported, so build the UI from job states: queued, processing, then completed or failed.
Why gate on the field
The OpenAI guide describes streaming partial images for its own API. Sume does not pass that through: the docs say real streaming would need partial-image events in the job pipeline, and the catalog says so with supports_streaming: false. If your UI reads the field, it will pick up streaming the day a model turns it on, with no code change. If it hard-codes the answer, you ship a dead code path or a broken request.
Do not fake percent. The status poll has no progress number, so a bar that reaches 90 percent on a timer misleads people. Show the state and the elapsed time.
| Signal | Available | Use |
|---|---|---|
| supports_streaming | false on every row | Gate any live preview |
| stream request field | 400 streaming_not_supported | Do not send |
| status values | queued, processing, completed, failed, canceled | State chip |
| next_poll_after_seconds | In the poll response | Polling interval |
| events_url | Pull snapshot, not SSE | Optional history |
Read the gate
Fetch the catalog once per session and read the row for the model you use.
import os, requests
H = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
r = requests.get("https://api.sume.com/v1/images/models", headers=H, timeout=30)
r.raise_for_status()
rows = {m["id"]: m for m in r.json()["data"]}
m = rows.get("openai/gpt-image-2.5")
if m is None:
raise SystemExit("model not in catalog")
if m.get("supports_streaming"):
print("show a live preview")
else:
print("show queued -> processing -> done states")What to show instead
These four elements give a calm interface without any claim about progress that the API cannot support.
- A state chip that follows
queued,processingandcompleted. - Elapsed seconds, so a long 4K job looks alive.
- A cancel button wired to the job, since a client timeout does not cancel it.
- A placeholder with the final aspect ratio, so the layout does not jump when the image arrives.
Handle the three endings
A job ends in one of three ways, and the interface should treat each one clearly. On completed, fetch the result and swap the placeholder for the image. On failed, show the public error message from the status response and offer a retry, and tell the user that failed jobs are not billed. On canceled, return to the form with the prompt kept, so nothing typed is lost.
Keep the polling interval from the server. The response carries next_poll_after_seconds, and following it keeps the request volume low for you and for the API. When the tab goes to the background, slow the loop or pause it, and run one status read on focus so the page is current again the moment someone returns.
Finally, store the job id in the page state or the URL. A reload then resumes the same job instead of paying for another.
Sources
Related posts
More in Developers
- AI image to CMYK for print: Pillow convert and what it misses
Image.convert('CMYK') makes a print-mode TIFF from a Sume image in two lines, but it is not color-managed. The code, the gamut risk, and when to ask for an ICC.
- AI video API: rate limit or concurrency, which stops a batch first
Concurrency binds long before request rate on Sume. Free allows 120 writes a minute but 1 running job; Pro 300 and 4. How to size a batch against both.
- AI video generator app: four server calls, key never on the client
An AI video app on Sume needs four server-side calls: submit, poll, download and balance. The key stays on your server, never in the browser or mobile app.
- AI video generator from image: the URL checklist before you submit
Image-to-video on Sume needs a public HTTPS image URL. Five checks, the two error codes when Sume cannot fetch it, and the first-frame request body.
Written by Sume