Queue-level webhook_url in a Sume bulk body fails: set it per item
A Sume bulk body takes concurrency, items and an optional key. A top-level webhook_url is an unknown field; set communication.webhook_url on each item.

A Sume bulk request accepts concurrency, items and an optional idempotency_key, and the API rejects unknown top-level fields. So a webhook_url at the top of a bulk body fails the create. Register the URL on each item's communication.webhook_url instead; the queue object itself has no webhook.
Where each field lives
Each bulk item is the same body as a single run, so it can carry its own communication.webhook_url. Each child run then sends its own terminal format.run.terminal event when it completes or fails.
| Field | Top level | On each item |
|---|---|---|
| concurrency | Required, 1 to 16 | Not applicable |
| items | Required, 1 to 100 | Not applicable |
| idempotency_key | Optional; header wins | Not applicable |
| communication.webhook_url | Unknown field, 400 | Accepted |
| output_schema, generation_spend_cap_usd | Unknown field, 400 | Accepted |
What this means for a 100-item batch
You get up to 100 deliveries, one per child that completes or fails, and none for canceled or skipped children. There is no event that says the whole queue finished.
- Point every item at the same URL, and map the delivery's
run_idto your row with the index map you saved. - To know the queue is done, poll
status_urluntilstatusiscompleted, then checkcounts.failedandcounts.canceled. - Size the receiver for a burst: with
concurrency: 16, many children can finish around the same time.
Building the body in code
Build the items in a loop and attach the same communication object to each one. Keep the queue envelope to its two required keys and the key, so a typo in a top-level field fails fast in your tests, not at 2 a.m.
A typo gets help from the API: for single runs, an unknown field returns 400 unknown_parameter with a suggestion when the name is close, such as webook_url for webhook_url.
Per-item webhooks also let you attach different settings to different rows, since each item is a full run body. A mixed batch can share one queue and one concurrency setting, with each item carrying its own output_schema and primary_output_key.
Tradeoff
Repeating the URL on 100 items is verbose, but it lets you route different rows to different receivers. If you want one signal for the batch, you build it: count the webhooks you receive, or poll the queue as the authority.
Sources
Related posts
More in Formats
- Bulk Format runs on Sume: concurrency 1-16, 1-100 items, fail early
A Sume bulk run takes concurrency 1 to 16 and 1 to 100 items. A bad item fails the whole create with details.index before any queue exists. Nothing dispatches.
- Bulk queue finished_at: measure the wall time of a 100-item batch
A Sume bulk queue sets finished_at when every item is terminal, so created_at to finished_at is your wall time. It does not mean every item succeeded.
- Bulk run concurrency 3 with 8 items: what the 202 receipt shows
With concurrency 3 and 8 items, the Sume 202 shows three running and five queued. Item 3 starts when item 0 finishes. Here is how the window and counts behave.
- Bulk run has no empty item: skip sheet rows without a finished script
A Sume bulk item must name at least one of instruction, input, previous_run_id or attachments. Filter unfinished sheet rows on your side before you send.
Written by Sume