Queue 100 Format runs at concurrency 16: 7 waves, one idempotency key
Sume bulk runs accept 1 to 100 items and a concurrency window of 1 to 16. The queue has no webhook, and completed does not mean all succeeded.

To queue many video runs with Sume, call POST /v1/formats/{handle}/{slug}/bulk-runs with concurrency (1 to 16) and items (1 to 100). At the maximum window of 16, 100 items run in ceil(100 / 16) = 7 waves. The server holds the queue, so you do not need to drive the fan-out from a laptop.
What a bulk request is
It is a server-side queue of ordinary Format runs, not a different engine. Each item has the same body as a single run: one sandbox, one agent turn, one receipt. It needs formats:write to create and formats:read to poll GET /v1/format-run-queues/{queue_id}. Service-account keys cannot create runs or queues.
| Item | Value |
|---|---|
| items | 1 to 100, in order |
| concurrency | 1 to 16 child runs in flight |
| Each item | Needs one of instruction, input, previous_run_id, attachments |
| Bad item | Whole create fails with 400 invalid_request and details.index; nothing dispatches |
| Queue webhook | None; set communication.webhook_url per item |
Three traps
First, completed means every item is terminal, not that everything succeeded. Read counts.failed. Second, the queue object has no webhook; give each child its own communication.webhook_url or poll status_url. Third, mint a fresh Idempotency-Key for every batch. Replaying a spent key returns 202 with the old queue, not a new one.
curl -sS -X POST "https://api.sume.com/v1/formats/acme/product-promo/bulk-runs" \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: batch-2026-10-09-a" \
-d '{
"concurrency": 3,
"items": [
{ "instruction": "clip 1", "input": { "url": "https://example.com/1.jpg" } },
{ "instruction": "clip 2", "input": { "url": "https://example.com/2.jpg" } }
]
}'Monitoring a queue
Poll status_url and read counts: total, queued, running, completed, failed, and canceled. When the queue status is completed, branch on counts.failed, then read each child at GET /v1/format-runs/{run_id} using the run_id in items[]. A child the API claimed but has not yet given a run_id still counts as running.
Because a bad item fails the whole create with details.index, validate your spreadsheet rows before you send the batch. The create is atomic with respect to validation: nothing dispatches if any item is wrong.
Per-item controls
Each item is a full single-run body, so it can carry its own output_schema, attachments, input, and communication.webhook_url. Items run with on_active_run: "allow", so sending skip or reject on an item does not stall the window. If your batch comes from a spreadsheet, skip rows that lack a finished draft before you build items, and give every row a stable index so that items[n].run_id in the queue maps back to your row.
Waves and time
Wave count is ceil(items / concurrency): 100 at 16 is 7, 100 at 4 is 25, 20 at 2 is 10. Workspace generation concurrency still applies to the children, so a window of 16 is a ceiling, not a guarantee. If each run takes 15 to 30 minutes, 7 waves is a few hours; estimate with a pilot batch before sizing the window.
Each item can set its own generation_spend_cap_usd, so one expensive row cannot use the allowance of the others. To cancel, use POST /v1/format-runs/{run_id}/cancel on a child; there is no cancel-queue or list-queues endpoint.
Sources
Related posts
More in Formats
- Format Contents API: If-Match stops two agents overwriting each other
Per-file sha checks do not catch two agents editing different files. Send If-Match with package_sha and handle 409 format_package_sha_mismatch.
- Share a Format with another workspace: grants, accept and the 404
A Format owner can share a team Format with another workspace by grant. The other workspace accepts, calls it with its own key, and pays its own bill.
- Format input vs instruction: where scraped product copy should go
Put scraped or customer text in the input object, not in instruction. Sume writes input to a file and marks it as data. Limits: 64 keys, 2 MiB, 4000 characters.
- Format package files: which types and paths the Contents API accepts
A Sume Format package accepts only .md, .json, .yaml, .yml and .txt files, one folder deep, with SKILL.md required. The full rule list and the error you get.
Written by Sume