Async, webhook or sync: pick a Sume communication mode by job length
Use sync only for jobs that finish inside its 30 second cap, such as many images. Use async plus polling or webhook for video, and keep polling as the backup.

Pick the mode by how long the job can run. Sume's sync mode blocks for at most 30 seconds, so it fits work that usually finishes inside that, while async and webhook fit everything that can outlast it, which is most video work.
Every submit endpoint accepts a mode, and the mode decides only how you learn the outcome. It never changes whether a job is created, what it costs or how long it runs, so choosing wrong costs you plumbing, not money.
The four modes side by side
This table restates the Sume docs on communication modes (read 2026-10-03). Every mode returns the job id in the first response, so a 2xx always means a job exists.
| Mode | What HTTP returns | Server blocks | Client does next |
|---|---|---|---|
| async (default) | 202 with the job envelope and polling URLs | No | Poll status_url until terminal is true, then read result_url |
| sync | The envelope after up to wait_timeout_seconds (max 30) | Yes, at most 30 seconds | Terminal: read the job. Not terminal: poll, never resubmit |
| subscribe | Identical to sync | Same as sync | Same as sync; it is an alias, not an event stream |
| webhook | 202 with the envelope; callback is stored | No | Wait for the terminal callback, verify it, keep polling as backup |
A rule of thumb by job length
Think in three bands. Short jobs that often finish within seconds can use sync, and you check the response for terminal. If the wait budget runs out, the response is still a 2xx with the job id, sync.timed_out is true, and you continue with GET status_url. The 30 seconds is a wait budget, not a job duration.
Anything that regularly takes minutes should be async. Submit, store the job id, poll status_url with the next_poll_after_seconds hint when present and exponential backoff otherwise, and fetch the result only when result_ready is true. A client-side timeout does not cancel the job; it keeps running and keeps billing, so store the id and resume from status_url.
Fan-outs, nightly batches and anything driven by a server you control should use webhook: a public HTTPS webhook_url, three terminal events, and status_url polling kept as the fallback for deliveries that never arrive.
curl -X POST https://api.sume.com/v1/image-1.0/generate \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: hero-shot-001" \
-d '{"prompt":"Product hero shot of a matte black bottle on marble","mode":"async"}'Two traps
First, subscribe is not a stream. It runs the same bounded 30 second waiter as sync, and there is no SSE or WebSocket transport on the Developer API, so progress comes from GET /v1/jobs/:id/events or a webhook, as covered in subscribe is a sync alias.
Second, never resubmit because a wait timed out. Retrying the submit itself is fine if you reuse the same Idempotency-Key, because the retry returns the original job instead of billing a second one. See sync wait timed out for the flags.
Sources
Related posts
More in Developers
- attachment_too_large 413: 30 MB per image, 500 MB per run
A Format run 413 attachment_too_large means one image is over 30 MB or the set is over 500 MB. It is a different 413 from payload_too_large (4 MiB body).
- Audio detach in sync mode: 30 seconds, then a 202 you poll
Audio detach defaults to async. With mode sync it waits up to 30 seconds for a 200, or returns 202 to poll. Why a timeout is not a failure and how to retry.
- Audio detach file size: 16 kHz mono WAV vs 48 kHz stereo
A 900-second Sume audio detach is about 29 MB as 16 kHz mono WAV, 173 MB as 48 kHz stereo WAV and 14 MB as 128 kbps MP3. The arithmetic and choices.
- "Avatar does not have a usable TTS voice": the 400 and its fixes
Sume TTS with avatar_id or avatar_handle returns 400 when the avatar has no TTS voice, or when voice.id disagrees with it. What each message means and the fix.
Written by Sume