Cancel one bulk-run child: pay for what finished, slot moves on
Cancel a Format run inside a bulk queue with POST /v1/format-runs/{run_id}/cancel. The item turns canceled, its slot starts the next one, no webhook fires.

To stop one bad item in a Sume bulk queue, cancel its child run: POST /v1/format-runs/{run_id}/cancel. The queue marks that item canceled, frees the slot, and immediately starts the next queued item. You pay for the generation the child completed before the cancel, and the receipt's usage shows the amount. A canceled run never delivers a webhook, so if you rely only on webhooks you will not hear about it.
What a cancel does and does not do
The cancel call needs formats:write and is idempotent. The receipt comes back with cancel_effect: canceled means this call stopped a run that was in progress, and no_op means the run had already finished. There is no queue-level cancel, and the API has no list-queues call either, so stopping a whole queue means canceling each child. Children still queued have no run_id yet, which is the part that surprises people.
| Situation | Result |
|---|---|
| Child running | Cancel stops it; item canceled; slot frees |
| Child already finished | cancel_effect: no_op; you pay the normal amount |
Item still queued, run_id: null | No run to cancel yet; the item starts when a slot opens |
| Webhook-only integration | A canceled run sends no webhook; poll the queue |
| Whole queue | No endpoint; cancel each child run |
Stopping the spend of a queue
Because queued items start as slots free up, canceling the running children of a 100-item queue with a concurrency of 16 does not stop the queue: the next 16 start. To stop a queue you must cancel in a loop until nothing is running or queued, reading the queue's counts each pass. The safer controls come earlier: a small per-item generation_spend_cap_usd, a concurrency that matches your plan, and a batch size you can afford to see through.
for RUN in $RUN_IDS; do
curl -sS -X POST "https://api.sume.com/v1/format-runs/$RUN/cancel" \
-H "Authorization: Bearer $SUME_API_KEY" \
| jq -r '.data.id + " " + (.data.cancel_effect // "?")'
doneCheaper to split than to cancel
If you expect to stop partway, submit smaller queues. Three queues of 30 each with a fresh idempotency key give you three natural stopping points, and you simply do not create the next queue. This is the same reason prices that fall every month still call for a spend ceiling: lower prices make a runaway loop cheaper but not harmless.
Queue completion is also not success. A queue is completed when every item is terminal, so read counts.canceled and counts.failed before you declare the batch done.
Sources
Related posts
More in Formats
- Change a Format grant role: PATCH run to write and back
PATCH .../grants/{workspace} with {role} changes a pending or accepted grant. Raising to write applies on the next authoring call; lowering to run closes it now
- Change only the CTA of a finished ad: previous_run_id on a Format
Re-do one line of a finished Sume Format ad without paying for the whole ad again: previous_run_id, a new key and cap, and the four refusals to expect.
- Check a Format run's video with ffprobe: duration and audio stream
Before you publish a Format run's clip, run ffprobe on primary_output_url, confirm an audio stream exists and compare its length with duration_ms.
- Continue a Sume Format run with previous_run_id after a review gate
Send previous_run_id on a new POST .../runs so the agent redoes one part. A yes/no review model decides whether to continue; each new run gets its own webhook.
Written by Sume