stream: true on Sume's Images API returns 400: use async and events

Sume's image catalog rows report supports_streaming false, so stream: true is a 400 streaming_not_supported. Submit async and read /v1/jobs/:id/events instead.

4 min readSume
All posts

stream: true on POST /v1/images returns 400 streaming_not_supported. Every catalog row reports supports_streaming: false today, because native SSE streaming of partial images is not served in v1. The field exists in the schema so that clients can adopt streaming later without a code change.

For progress, submit with mode: "async" and read GET /v1/jobs/{id}/events, or use a webhook for the terminal event.

Four modes, one useful for progress

Communication modes on POST /v1/images (read 2026-10-07)
ModeWhat you getProgress?
sync (route default)Waits up to wait_timeout_seconds (0 to 30, default 30), then 200 with images or 202 with the jobNo
subscribeAn alias of sync: one bounded wait of up to 30 secondsNo
async202 with status_url, result_url and events_url at onceYes, via the events URL
webhook202, then a signed callback on job.completed, job.failed or job.canceledTerminal only

Do not confuse subscribe with streaming

The name suggests a stream. The jobs doc says mode: "subscribe" is not a progress stream; it behaves like sync. If you want a live bar in the UI, async plus events is the supported path, and polling status_url until terminal is true is the fallback that always works.

Gate the UI on the catalog

Read supports_streaming from GET /v1/images/models instead of hard-coding it. When Sume ships streaming for a model, the flag changes and your code starts to use it. Until then, show a spinner and the job state.

  • Do not send stream: true and catch the 400 as flow control.
  • Keep the wait short for a UI (a few seconds), then fall back to the 202 job.
  • Use the same Idempotency-Key when you retry the submit, so you do not pay for a second job.

A minimal async-and-poll loop

A progress UI needs three things: the job id from the 202 envelope, a poll interval of a second or two, and a stop on terminal. Show elapsed time to the user rather than a fake percentage, because the job reports states and not progress.

Failed and cancelled generations are not billed. If the user closes the tab, the job can still finish, so store the job id and resume the poll when they come back. A webhook is the better fit for server-side flows where nobody is watching: you get one signed callback per terminal state and can keep polling as a backup.

What a progress poll looks like

Submit async, take status_url from the envelope, and poll the booleans terminal and result_ready. Read the images from result_url when result_ready is true. The Jobs and results page has the field list, and Webhooks covers signature checks for the terminal callback.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume