Cancel a Sume bulk queue: there is no queue cancel, so cancel children
Sume's API has no cancel-queue endpoint. Cancel each child with POST /v1/format-runs/{run_id}/cancel; the item frees its slot, and you pay for what already ran.

You cannot cancel a whole Sume bulk queue. The API has no public list-queues or cancel-queue endpoint. To stop work, cancel each child run with POST /v1/format-runs/{run_id}/cancel. The queue marks that item canceled and frees its slot, so the window starts the next queued item unless you cancel that one too.
Stopping a queue in practice
Read the queue at GET /v1/format-run-queues/{queue_id}. Items with a run_id are in flight or finished. Items without one are queued and have no child run yet, so there is nothing to cancel for them directly. That is the catch: while you cancel the running children, the window keeps filling from the queued items.
To stop the whole sheet, cancel the running children quickly, then keep polling and cancel the new ones as they start. Each cancel call needs formats:write and is idempotent.
| Situation | What happens |
|---|---|
| Child is running | cancel_effect is canceled; item status becomes canceled; slot freed |
| Child already finished | cancel_effect is no_op; you get the current receipt |
| Item still queued | No run_id; no cancel call exists for it |
| Webhook for a canceled run | Never delivered; use the receipt that cancel returns |
What you pay for
You pay for the generation that the run completed before the cancel, and usage on the receipt shows it. A cancel is not a refund of earlier work. The queue stays in running until every item is terminal, then it becomes completed. Completed does not mean succeeded. Branch on counts.canceled and counts.failed.
Plan the stop before you start
Since you cannot stop the queue from one call, build the stop into your design. Use a small concurrency, so few children run at once. Use caps per item, so a run that you cannot stop in time still has a ceiling. And keep batches short: 20 items at concurrency 2 is easier to wind down than 100 at 16.
If your integration is webhook-only, remember that cancel is the one path with no delivery. The cancel response is your record.
What to tell your users
If your product exposes a stop button, label it honestly: stop starting new renders, and cancel those in progress. Items that already finished remain finished and billed, and their media stays on media.sume.com. A canceled item has error.code of format_run_canceled, and a finished child that you canceled too late shows no_op.
Keep the queue id and each child run_id in your own records. A queue that you cannot see gets the same 404 format_run_queue_not_found as one that does not exist, so a lost id cannot be recovered by listing.
A loop that stops a queue
Poll the queue, collect every run_id whose status is running, and send a cancel for each. Repeat until counts.queued and counts.running are both 0. Do it with a delay between polls, because a poll spends the read budget, and a 429 is transient. The queue continues to work during a 429 or 503, so do not read those as failures.
Sources
Related posts
More in Formats
- Edited one ad hook and resent the bulk run? Same key gives 409
Reusing an Idempotency-Key with a changed Sume bulk-run payload returns 409 idempotency_conflict. Send only the edited hook under a new key.
- Format run incomplete_assembly: continue it, do not pay twice
incomplete_assembly means the run hit its time limit with generation jobs unfinished. Read pending_job_count, then continue with previous_run_id.
- Format run mcp_unavailable: failed before the model, charged false
mcp_unavailable means the per-turn tools never attached, so the run stopped before any turn. details.charged is false. Retry with a new Idempotency-Key.
- output_extraction_failed: harvest_unavailable or harvest_threw?
output_extraction_failed has two reasons with opposite handling: reread a completed run, or report a host defect. Here is how to tell them apart.
Written by Sume