sync, subscribe, async or webhook: which Sume mode for a video job
Sume's sync and subscribe modes wait at most 30 seconds, then return a job id. Use async or webhook for video; Python that survives a timed-out wait.

For video, use async or webhook. The sync and subscribe modes are the same bounded HTTP wait of at most 30 seconds, which is a request budget and not a job duration; most video jobs outlast it, so the response arrives with a job id and no result.
That response is still a success. The job exists, paid work is in flight, and you must poll the status_url rather than submit again. Jobs and results calls this out because resubmitting is the costly mistake.
The four modes
| Mode | HTTP returns | Blocks | Then |
|---|---|---|---|
async (default) | 202 with job envelope | No | Poll status_url |
sync | Envelope after up to 30 s | Up to 30 s | Terminal? read it. Else poll |
subscribe | Same as sync | Up to 30 s | No progress events; alias of sync |
webhook | 202, callback stored | No | Verify the terminal callback; keep polling as backup |
Surviving a sync timeout
Sending a webhook_url without a mode selects webhook for you. This sample sends sync on the Video Router route and continues with polling when the wait ends early.
import os, time, requests
API = "https://api.sume.com"
H = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"]}
r = requests.post(API + "/v1/video-router/generate", timeout=60,
headers={**H, "Idempotency-Key": "sync-demo-001"},
json={"model": "wan-3.0", "prompt": "Steam over a teacup",
"duration": 5, "resolution": "480p",
"mode": "sync", "wait_timeout_seconds": 30})
r.raise_for_status()
job = r.json()["data"]
while not job["terminal"]: # sync.timed_out is true here: poll, never resubmit
time.sleep(job.get("next_poll_after_seconds") or 5)
job = requests.get(job["status_url"], headers=H, timeout=30).json()["data"]
print(job.get("sume_status") or job["job"]["status"])Rule of thumb
- Images often finish inside 30 seconds; video, avatar video and face swap usually do not.
wait_timeout_secondsis clamped to 0 to 30.- There is no SSE or WebSocket stream on the Developer API today.
Webhook plus poll
The most robust pattern for video combines the two non-blocking modes. Submit with a webhook_url so Sume tells you when the job ends, and keep a slow poll on status_url as a backup for deliveries that never arrive. A webhook is an optimization, not the only recovery path, and polling costs little at a thirty-second cadence.
- Use
asyncfor scripts and batch tools that can poll. - Use
webhookfor services that should not hold state between request and completion. - Use
synconly for short image or audio calls where the 30-second budget is enough.
Sources
Related posts
More in Developers
- rate_limited or queue_full? One Python submit handler for both 429s
Two different 429s need two different waits. A Python handler reads error.code, sleeps on retry-after for rate_limited, and waits for capacity on queue_full.
- Test one video prompt on ten models for under $7 (Python sweep)
A 5-second, lowest-resolution sweep of one prompt over ten Sume video ids costs about $5.60 in total. The price of each row and a script that submits them.
- TTS word timestamps: timestamps.words and sentence segmentation
Sume TTS accepts timestamps.words and segmentation.mode sentence so a generated voiceover can drive caption timing. Request fields, rules and a working call.
- Turn a roleplay debrief into an avatar feedback clip in Python
Take the written debrief from a roleplay or survey session and render it as a 16:9 Sume avatar clip with a retry-safe key, a 12 to 168 word check and polling.
Written by Sume