Clear a full Sume queue: cancel queued jobs after 429 queue_full
When submits fail with 429 queue_full, list queued jobs with GET /v1/jobs?status=queued and cancel the ones you no longer need. Safe on a 409, with a script.

When submits start returning 429 queue_full, list your queued jobs with GET /v1/jobs?status=queued&limit=100 and send POST /v1/jobs/{id}/cancel for the ones you no longer need. Cancellation works only before generation starts, so a job that began in the meantime answers 409 job_generation_already_started and keeps running.
The Generation admission page lists this as the second step after you stop adding work: poll until at least one job is terminal, cancel queued jobs you do not need, then retry with the same idempotency key.
What the sweep may touch
A job belongs to the member whose key created it, and only that member can cancel it. An API key reads the jobs its own member created in the workspace, so the sweep cannot cancel a teammate's work. It also means a workspace that is full because of someone else's jobs will not be fixed by your sweep.
| Situation | Response | Your move |
|---|---|---|
| Job still queued | Canceled job, terminal | Confirm refund in the usage ledger if you need it. |
| Generation already started | 409 job_generation_already_started, details.cancelable false | Leave it; it completes or fails. |
| Already canceled | Same canceled job (idempotent) | Nothing. |
| Job not visible to this key | 404 not_found | Skip it. |
The script
It lists one page of queued jobs, cancels each, and prints a short id with the outcome. The list is newest-first and capped at 100 per page; when data.next_cursor is present, pass it back as starting_after for the next page. The sample prints a notice instead of paging, because a sweep that cancels the newest hundred is usually a decision you want to make deliberately.
import json, os, urllib.error, urllib.request
def call(method, path):
req = urllib.request.Request("https://api.sume.com" + path, method=method,
headers={"x-api-key": os.environ["SUME_API_KEY"], "User-Agent": "sume-sweep/1.0"})
try:
with urllib.request.urlopen(req, timeout=30) as r:
return r.status, json.load(r)["data"]
except urllib.error.HTTPError as e:
return e.code, json.load(e)["error"]
status, data = call("GET", "/v1/jobs?status=queued&limit=100")
for job in data["jobs"]:
code, body = call("POST", f"/v1/jobs/{job['id']}/cancel")
if code == 409:
print(job["id"][:8], "not cancelable:", body["code"])
else:
print(job["id"][:8], "cancel ->", code)
print("more pages" if data.get("next_cursor") else "all queued jobs seen")Before you run it
Decide which queued jobs are disposable. A sweep that cancels everything also cancels work that would have finished. Join on idempotency_key, which each job row carries, to cancel only a batch label you own, and not by array position.
After the sweep, re-read generation_limits on the next submit response. queue_capacity_remaining tells you how much room you bought, and the pacing formula max(0, concurrency_limit - active - queued) tells you how wide to go.
- Cancel is a write; it spends the write budget, not the read one.
- Do not cancel jobs that are
processing; it will 409. - Keep the list call in a loop only if you can name the batch to cancel.
How big the queue is
Queue capacity is derived from the plan's concurrency: the larger of 3 or five times the concurrency limit. That makes it 5 for Free (1 running), 20 for Pro (4), 40 for Startup (8) and 100 for Scale (20), per the generation admission docs read 2026-10-10. Once running plus queued jobs fill it, the next submit gets 429 queue_full and nothing is charged for the refused request.
After you cancel, do not refill the queue in one burst. The generation_limits block reports queue_capacity_remaining and a wave_size_hint; submit one wave of that size, wait for slots, and repeat. That keeps the queue from filling again and the next queue_full from arriving.
Sources
Related posts
More in Developers
- Empty job_id next to job_ids: how Sume MCP treats placeholders
Some agent clients fill every optional tool field with empty strings, zeros and empty arrays. What Sume's MCP drops, what it keeps, and what still errors.
- Crash-safe Sume submit: write the key first, reconcile on boot
If a worker dies between POST and saving the job id, list queued and processing jobs, match idempotency_key, and resubmit only keys still unknown.
- Detect Sume OpenAPI drift in CI: hash the operations you call
Fetch api.sume.com/reference/json, hash only the operations you use, and fail CI when one changes. A 23-line script, plus the User-Agent a stdlib fetch needs.
- Image API docs example vs live catalog: Seedream 4.5 shows 5 ratios
The docs example for Seedream 4.5 lists 5 ratios and 0.033 USD. The catalog lists 9 ratios and 0.05 USD. Why you read the endpoint, not the example.
Written by Sume