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.

4 min readSume
All posts

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

Ways to follow a Sume job (docs.sume.com, read 2026-10-06)
You wantUseNotes
The final result, no serverPoll GET /v1/jobs/{id}/statusObey next_poll_after_seconds
A timeline for debuggingGET /v1/jobs/{id}/eventsSnapshot: created, queued, started, completed
A push when it endswebhook_url or callback_urlTerminal events only
A short wait on submitmode sync, up to 30 sHTTP 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

All Developers posts

Written by Sume