Is there a webhook when a Sume bulk Format queue finishes? No

No queue-level webhook on Sume bulk queues. Only per-item webhook_url, so poll the queue with backoff and read counts. A Python loop that handles 429 and 503.

3 min readSume
All posts

No. The bulk runs docs state it twice: the queue has no webhook, and communication.webhook_url is per item. To know the whole batch is finished, poll the queue's status_url until status is completed, which means every item is terminal.

Two ways to be told

  • Per item: put communication.webhook_url on each item for one callback per child run. You then count callbacks yourself.
  • Per queue: poll GET /v1/format-run-queues/{id} and watch counts.
  • Polling costs the read budget, separate from the create budget, so a slow loop does not starve your submits.

How often to poll

Each child can be minutes of work when the Format makes video, so polling every second buys nothing and costs rate limit. The docs recommend exponential backoff. A 429 or 503 during polling is transient: the queue keeps working, so back off and retry rather than marking the batch failed. If a poll returns 404 format_run_queue_not_found, the queue id is wrong or belongs to another owner.

Poll responses, read 2026-10-03
ResponseMeaningAction
200 status runningWindow still drainingWait and poll again
200 status completedAll items terminalCheck counts.failed and counts.canceled
429Read budget spentHonor retry-after
503Sume-side outage; queue still drainingBack off, retry

Poll loop

import json, os, time, urllib.error, urllib.request

queue_id = os.environ["QUEUE_ID"]
url = "https://api.sume.com/v1/format-run-queues/" + queue_id
headers = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"]}
delay = 15
while True:
    try:
        req = urllib.request.Request(url, headers=headers)
        with urllib.request.urlopen(req) as r:
            q = json.load(r)["data"]
        if q["status"] == "completed":
            print(q["counts"])
            break
        delay = 15
    except urllib.error.HTTPError as e:
        if e.code not in (429, 503):
            raise
        delay = min(delay * 2, 300)
    time.sleep(delay)

Sources

Related posts

More in Formats

All Formats posts

Written by Sume