Poll a Sume bulk-run queue in Python and list items not completed
A short asyncio script that polls GET /v1/format-run-queues/{id} until the queue is completed, prints the counts and lists every item that did not complete.

A Sume bulk queue has no webhook, so for the queue as a whole you poll GET /v1/format-run-queues/{id}. The queue is done when its status is completed, but the docs say completed means every item is terminal and not that every item succeeded. The script below waits for that status, prints counts and lists the items that are not completed.
What does the queue response give you?
| Field | Meaning |
|---|---|
| status | queued, running or completed |
| counts | total, queued, running, completed, failed, canceled |
| items[] | One row per submitted item, in order: index, status, run_id, error |
| status_url | The URL to poll |
What is the script?
It uses only the standard library, runs the blocking request in a thread, and wraps everything in asyncio.run(main(...)) so it works as a plain script. Read the key and the queue id from the environment.
import asyncio, json, os, urllib.request
BASE = "https://api.sume.com/v1/format-run-queues/"
def get(qid):
req = urllib.request.Request(
BASE + qid,
headers={"Authorization": "Bearer " + os.environ["SUME_API_KEY"]},
)
with urllib.request.urlopen(req, timeout=30) as r:
return json.load(r)["data"]
async def main(qid):
while True:
q = await asyncio.to_thread(get, qid)
if q["status"] == "completed":
break
await asyncio.sleep(30)
print(q["counts"])
for item in q["items"]:
if item["status"] != "completed":
print(item["index"], item["status"], item["run_id"], item["error"])
asyncio.run(main(os.environ["QUEUE_ID"]))What do I do with the items it prints?
Each printed row has an index that matches the order you submitted, so you can look up the original item. For a failed child, read its receipt at GET /v1/format-runs/{run_id}. Re-submit only the failed items as a new queue with a fresh Idempotency-Key; replaying the old key returns the old queue. The retry post goes through that.
Should I poll or use item webhooks?
Use both for different jobs. A per-item communication.webhook_url delivers one signed format.run.terminal event as each child ends, which suits uploading a clip the moment it is ready. The poll gives you the single moment the whole batch is terminal, which suits a final report. A lost delivery can be sent again with POST /v1/format-runs/{run_id}/webhook/redeliver.
Why does the script not stop on the first failure?
A queue keeps draining the other items when one fails, and a failed child frees its slot for the next one. So the right moment to report is when every item is terminal, which is what completed means. Stopping early on the first failure would leave you with a partial picture and a queue still running in the background, still spending.
What are the limits?
- The key needs
formats:read; a service-account key is refused for Format runs and queues. - Thirty seconds between polls is a choice. A shorter delay does not make renders finish faster.
- There is no queue-cancel endpoint, so a script that gives up leaves the queue running; cancel children with
POST /v1/format-runs/{run_id}/cancel. - If the script is interrupted, run it again with the same queue id. Nothing is lost, because the queue lives on Sume's side.
- For a per-item callback, set
communication.webhook_urlon each item and verify the signature, refusing an empty secret.
Sources
Related posts
More in Developers
- Dedupe Sume webhooks with Postgres ON CONFLICT DO NOTHING
Insert job_id or request_id with ON CONFLICT DO NOTHING RETURNING. A returned row means first delivery; no row means a duplicate. Includes the SQL.
- Preflight a video request against the catalog before you pay
Check duration, resolution, aspect ratio, frame types and reference types against a GET /v1/videos/models entry in Python, and catch the 400 fields up front.
- Python preflight for a YouTube Short: length and shape check
A short Python script that reads Sume's video inspect probe and flags a clip over 180 seconds or not square or vertical, including 90 degree rotation.
- Preflight a Sume image request against capability descriptors
Catch unsupported_parameter before you send: fetch the model descriptors, then check each field of your request against enum, range and boolean types.
Written by Sume