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.

4 min readSume
All posts

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.

Bulk run limits (Sume docs, read 2026-10-09)
ItemValue
items1 to 100, in order
concurrency1 to 16 child runs in flight
Each itemNeeds one of instruction, input, previous_run_id, attachments
Bad itemWhole create fails with 400 invalid_request and details.index; nothing dispatches
Queue webhookNone; 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

All Formats posts

Written by Sume