stream: true on the Sume Image API returns 400. What to show instead
Sume image models have no SSE streaming: stream true returns 400 streaming_not_supported. Use async mode and job events for stages, or a webhook for the end.

No, the Sume Image API does not stream partial images: stream: true returns 400 streaming_not_supported, and every row in GET /v1/images/models reports supports_streaming: false. If your UI needs feedback while a picture renders, submit with mode: "async" and show the stages from the job events, or wait for a webhook.
The schema accepts the field only so that a client written for streaming will work without a code change on the day Sume ships it.
The four ways to wait
The Image API docs describe the options. Only one gives you anything during the wait, and it is a timeline of stages, not a percentage.
| Mode | What you get | Progress during the wait |
|---|---|---|
| sync (default) | Up to 30 s of waiting, then 200 with images or 202 with a job | None |
| subscribe | Alias of sync: one bounded 30 s wait | None |
| async | 202 at once with status_url and result_url | Poll status, read /events |
| webhook | 202 at once, then a signed callback on the terminal event | None until the callback |
What the events give you
GET /v1/jobs/{id}/events returns a public timeline for the job. The documented event names are job.created, job.queued, job.started, generation.submitted, job.completed, job.failed, job.canceled and webhook.delivery. They tell a user that the job is queued, started and submitted to the model, which is enough for a three-step indicator. They do not say how far along the model is.
One caution: the 400 message for stream: true suggests mode: "subscribe" for job events. The Image API docs say the opposite and are the source to follow: subscribe is an alias of sync and is not a progress stream. Use async for events.
curl -s -X POST https://api.sume.com/v1/images \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"bytedance-seed/seedream-4.5","prompt":"a ceramic mug on linen","mode":"async"}'
# then, with the job id from the 202 body:
curl -s https://api.sume.com/v1/jobs/$JOB_ID/events \
-H "Authorization: Bearer $SUME_API_KEY"What happens if the client goes away
Streaming usually raises the question of what a dropped connection costs. For image generation the docs are direct: Sume bills on an all-or-nothing basis, and a request that ends early because the client disconnected is treated as a failed generation, with no charge. In async or webhook mode the job exists independently of your connection, so closing the browser tab does not stop it; the result is still in the job and can be fetched later with the job id.
That is a good reason to store the job id as soon as you get the 202: it lets a page reload pick the wait back up from the status URL instead of paying for a second generation.
What to build in the interface
Because the stages are coarse, a determinate bar would lie. A calmer pattern is a three-step label that follows the events: queued, started, finishing. Stop on completed, failed or canceled, poll with exponential backoff, and do not resubmit the paid request if your own client times out.
For a server-to-server flow where nobody is watching, skip polling and use mode: "webhook" with a public HTTPS webhook_url. The Webhooks page says Sume sends terminal job events only, never partial deliveries, and that localhost, private-network and non-HTTPS URLs are rejected.
- Do not send
stream: true; it will fail every time today. - Use
asyncplus/eventsfor a stage indicator. - Use
webhookwhen no one is waiting on a screen. - Keep the poll as a fallback for a webhook that you did not receive.
Sources
Related posts
More in Developers
- Sume API 401 on the dev host: keys only work on their own host
A Sume key works only on the host it was created for. A key from api.sume.com gets 401 on api.dev.sume.com and the reverse. Match key, host, and env var.
- Is there a Sume API test mode? No sandbox key, but two hosts
Sume has no sume_test key. Use the dev host with its own key, cap each run with generation_spend_cap_usd, and mock the rest. What each option costs and covers.
- sume/auto hides which image model ran: pin an id for brand assets
model sume/auto never discloses the family, and job.model stays sume/auto. Why a brand asset set needs a pinned image model id, and how to pin one on Sume.
- Sume GET /v1/balance expiration fields: warn before credits lapse
GET /v1/balance reports when your next credit lot expires and how much expires soon. Read the fields, convert micros to dollars, and alert from a cron job.
Written by Sume