Cancel a Sume bulk run: no queue endpoint, so cancel each child
Sume has no public cancel for a bulk queue. Poll the queue, then POST /v1/format-runs/{run_id}/cancel for each running child. fal cancels one request with PUT.

There is no public endpoint to cancel a Sume bulk queue, and no public list of queues. To stop a batch, read the queue with GET /v1/format-run-queues/{id}, then call POST /v1/format-runs/{run_id}/cancel for each item that has a run_id and is not terminal. Queued items only get a run_id when a slot frees, so repeat the loop until the queue drains.
What the queue gives you
The queue object lists items with index, status, run_id and error, plus counts for total, queued, running, completed, failed and canceled. When you cancel a child, the queue marks that item canceled and frees its slot for the next queued item.
That last rule is the trap: freeing a slot starts the next queued item. To really stop the batch, cancel the queued ones as well as soon as they get a run_id, or accept that a small tail will start.
| Service | Cancel call | Scope |
|---|---|---|
| Sume bulk queue | None public | Not available |
| Sume child run | POST /v1/format-runs/{run_id}/cancel | formats:write |
| Sume single job | Cancel URL on the envelope | Only before generation starts |
| fal request | PUT on the cancel endpoint | One request |
A loop that drains the window
The loop below cancels every child that has a run id and is not finished, then re-reads the queue until nothing is running or queued. It stops after a bounded number of rounds.
import json, os, time, urllib.request
H = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"]}
def call(url: str, method: str = "GET") -> dict:
req = urllib.request.Request(url, headers=H, method=method)
with urllib.request.urlopen(req, timeout=20) as r:
return json.load(r)
def stop(queue_id: str, rounds: int = 20) -> dict:
base = "https://api.sume.com/v1"
for _ in range(rounds):
q = call(f"{base}/format-run-queues/{queue_id}")["data"]
live = [i for i in q["items"] if i["run_id"] and i["status"] in ("queued", "running")]
if not live and q["counts"]["queued"] == 0:
return q
for i in live:
call(f"{base}/format-runs/{i['run_id']}/cancel", "POST")
time.sleep(2)
return qWhat it costs you
A run that already started generation may not be cancelable; the job rule is that cancel works only before generation starts, otherwise 409 job_generation_already_started. Treat that 409 as normal in the loop and keep going. Check counts.failed and counts.canceled at the end before you reconcile spend.
Reading the end state
After the loop returns, the queue status is completed, which means every item is terminal. It does not mean success. Read counts for completed, failed and canceled, and keep the three numbers with the batch record. A child that finished before your cancel arrived stays completed, and its cost is spent.
A cancel on a run that has begun generation can return a conflict. Handle that as expected, and let the run finish; the counts.completed field tells you how many ended that way.
Compared with fal
The fal queue page, read today, lists a cancel endpoint that uses PUT for one request, and it states that requests in the queue are never dropped, so a cancel is the only way to stop work there. Sume is the same at the single-run level and has no queue-level call, which is why the per-child loop exists.
Sources
Related posts
More in Developers
- Resume a bulk run after a crash: replay the Idempotency-Key
If your client dies after POSTing a 100-item bulk run, replay the same key and same body: Sume returns 202 with the original queue. A new body gets 409.
- Sume Image API 400 unsupported_parameter: which field fails where
Which Sume image models list quality, resolution, mask_url, background, output_format and references, and which never do (seed, stream). Plus a check script.
- result_ready vs terminal vs completed: gate the Sume result fetch
Poll a Sume job until terminal, fetch the result only when result_ready is true. Failed and canceled jobs answer 409 job_not_completed on /result.
- Sume TTS word timestamps to caption cues for a narrated 60-second clip
Ask Sume TTS for timestamps.words, group them into cues and send them to video-captions so no recognition runs. About 25 cents for a 60-second narration.
Written by Sume