SSE or WebSocket for AI video progress on Sume? Poll or webhook
Sume has no SSE or WebSocket. mode subscribe is the same 30 s wait as sync. Use async with status polling, the events snapshot, or a webhook. Python example.

Can I stream Sume video progress over SSE or a WebSocket?
No. The Developer API has no SSE or WebSocket transport today. GET /v1/jobs/{id}/events is a pull snapshot of a public timeline, not a stream. For long video work, submit with mode: "async" and either poll the status route or take a webhook.
The word subscribe is a trap. A job submitted with mode: "subscribe" is an alias of sync: the same bounded wait of at most 30 seconds on the submit call, and no progress events. Most video jobs outlast that wait, so you would fall back to polling anyway.
What to use for which need
| You want | Use | Notes |
|---|---|---|
| The final result, no server | Poll GET /v1/jobs/{id}/status | Obey next_poll_after_seconds |
| A timeline for debugging | GET /v1/jobs/{id}/events | Snapshot: created, queued, started, completed |
| A push when it ends | webhook_url or callback_url | Terminal events only |
| A short wait on submit | mode sync, up to 30 s | HTTP budget, not job length |
Poll loop that honours the server
The status envelope carries terminal, sume_status and, while the job is open, next_poll_after_seconds. Sleep for that value and fall back to a modest backoff when it is absent. Pass the job id as an argument.
import json, os, sys, time, urllib.request
def get(path: str) -> dict:
req = urllib.request.Request(
"https://api.sume.com" + path,
headers={"x-api-key": os.environ["SUME_API_KEY"]},
)
with urllib.request.urlopen(req, timeout=20) as r:
return json.load(r)
def follow(job_id: str) -> dict:
delay = 3.0
while True:
s = get(f"/v1/jobs/{job_id}/status")
print(s.get("sume_status"), s.get("next_poll_after_seconds"))
if s.get("terminal"):
return s
delay = min(delay * 1.5, 30)
time.sleep(s.get("next_poll_after_seconds") or delay)
if __name__ == "__main__":
final = follow(sys.argv[1])
print("done:", final.get("sume_status"), "result ready:", final.get("result_ready"))Events are for debugging, webhooks are for pushing
Event names include job.created, job.queued, job.started, generation.submitted, the terminal events and webhook.delivery. They never expose raw provider ids or URLs. Use them to answer "where did my job stall", not to drive a progress bar.
If you need push, give Sume a public HTTPS webhook_url and keep the poll as a fallback. Terminal events only are sent: there are no partial or percentage updates, so a progress bar has to be a spinner with an elapsed timer.
A practical split: let a webhook drive your pipeline, since it arrives within moments of the job finishing, and let the poll loop run only for jobs that have been open longer than you expect. That way a healthy system makes almost no status calls, and a dropped delivery still resolves on the next sweep.
When the job is terminal and sume_status is completed, fetch GET /v1/jobs/{id}/result for the artifacts. A failed or canceled job has no result, so read the error from the status envelope and decide whether to resubmit with a new key.
Sources
Related posts
More in Developers
- Keep a series voice consistent: pin model, voice, speed and volume
A series sounds the same only if every episode sends the same TTS settings. Keep one profile in code, pin a model id, and send it with each Sume request.
- Same volume every Shorts episode: gain_db, duck_db, one music bed
Sume does not measure loudness. To keep a series consistent, pin audio.gain_db, soundtrack gain_db and duck_db in one function with one bed. Python plan loop.
- Ktor webhook route for an AI video job: receiveText and HMAC SHA-256
A Ktor route reads the raw body with call.receiveText(), checks Sume's sume-v1 HMAC over timestamp.body in Kotlin and returns 401 when the secret is empty.
- Label speakers without diarization: transcribe each mic track, merge
Sume STT has no speaker labels. If you record each speaker on a separate track, transcribe both tracks and merge the segments by start time. Python script.
Written by Sume