Cancel every queued Sume job without cancelling a running one

A Python script that lists queued jobs, checks the cancelable flag, posts the cancel, and handles 409 job_generation_already_started when the race is lost.

4 min readSume
All posts

List the jobs with status=queued, read each job's status snapshot, and POST /v1/jobs/:id/cancel only when cancelable is true. Cancel works only before generation work starts, so a job that moved to processing between your read and your write answers 409 job_generation_already_started and runs to completion. Treat that 409 as a normal outcome of the race, not as a bug.

Which answer means what

Cancel outcomes from the jobs docs, read 2026-10-08
SituationWhat the API does
Job is queued, cancelable trueCancel succeeds and the job becomes canceled
Generation already started409 job_generation_already_started with details.cancelable false
Job already canceledIdempotent: returns the same canceled job
Job is another member'sOnly the member who created a job can cancel it

The script

The helper reads the status snapshot first, because the snapshot carries both terminal and cancelable. It reports one line per job. Use it when a bad batch is queued and you want to stop the jobs that have not started.

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

BASE = "https://api.sume.com/v1"

def call(method, path):
    req = urllib.request.Request(BASE + path, method=method,
                                 headers={"x-api-key": os.environ["SUME_API_KEY"]})
    try:
        with urllib.request.urlopen(req, timeout=30) as r:
            return r.status, json.load(r)
    except urllib.error.HTTPError as e:
        return e.code, json.load(e)

def cancel_if_possible(job_id):
    _, body = call("GET", f"/jobs/{job_id}/status")
    snap = body["data"]
    if snap["terminal"]:
        return f"{job_id}: already {snap['status']}"
    if not snap["cancelable"]:
        return f"{job_id}: generation started, it will finish and bill"
    code, body = call("POST", f"/jobs/{job_id}/cancel")
    if code == 409:
        return f"{job_id}: lost the race ({body['error']['code']})"
    return f"{job_id}: canceled" if code < 300 else f"{job_id}: HTTP {code}"

if __name__ == "__main__":
    _, listing = call("GET", "/jobs?status=queued&limit=100")
    for job in listing["data"]["jobs"]:
        print(cancel_if_possible(job["id"]))

Cautions

Run a dry run first by printing the ids instead of posting the cancel. A cancel script that targets the wrong key's queue is easy to write and slow to undo.

  • Jobs that already started keep running and bill. Cancel is not a way to stop a running render.
  • The status cancel_url is null after generation starts and after terminal states, which is the same signal as cancelable false.
  • Page through the queue if you have more than 100 queued jobs. The list returns next_cursor while more jobs remain.
  • Check the cancellation and billing section of the admission docs for what happens to the reserved amount.

Why read the status first

You could post the cancel to every id and let 409 sort it out, but the status read makes the log far clearer. A terminal job shows its final status, a started job shows that it will bill, and only the jobs that are really cancelable cause a write. Writes have the smaller rate budget, 120 a minute on Free and 300 on Pro, while reads are 40 times larger, so spending a read to save a write is the right trade when you clean up a large queue.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume