Shorts series bulk queue finishes out of order: publish by number
Episodes in a Sume bulk queue run in parallel and finish in any order. Sort by an episode number in your output schema, not by completion time.

Publish by an episode number you wrote into the request, never by the order in which runs finish. A Sume bulk queue runs items in parallel up to your concurrency, from 1 to 16, so episode 7 can finish before episode 2. Sort the finished set by the number in your output schema, then publish in that order.
This matters now because YouTube Shorts series play sequentially. A platform roundup reports that seasons, episodes, custom thumbnails and sequential playback have been rolling out since 2026-09-23 (Orthotropy, read 2026-10-06). If a viewer binges your season, a mis-ordered upload is visible immediately.
What the queue does and does not promise
The queue is a server-side list of ordinary Format runs. You POST up to 100 items with a concurrency window, then poll GET /v1/format-run-queues/{id}. Its status is queued, running or completed, and counts report total, queued, running, completed, failed and canceled. The queue lists items in submitted order, each with an index, a status and a run_id, but nothing in the contract says the runs finish in that order (Sume docs: Bulk runs, read 2026-10-06).
So treat order as your data, not the queue's. Put episode_number in each item's input, and require it back in the output schema as an integer.
Sort, then publish
The script below takes a list of finished receipts, filters to those that delivered, and sorts by the episode number. Items that failed are listed so a human can decide whether to hold the whole season or publish the gap.
import json
receipts = json.load(open("season1-receipts.json"))
done, missing = [], []
for r in receipts:
out = r.get("output") or {}
if r.get("status") == "completed" and out.get("episode_number"):
done.append(out)
else:
missing.append(r.get("id"))
done.sort(key=lambda o: o["episode_number"])
numbers = [o["episode_number"] for o in done]
gaps = [n for n in range(1, max(numbers, default=0) + 1) if n not in numbers]
for o in done:
print(o["episode_number"], o["video"]["url"])
print("gaps:", gaps, "unfinished:", len(missing))Gaps are the real risk
A queue reaching completed does not mean every item succeeded. Item failures surface as format_run_failed, format_run_canceled or format_run_failed_to_start, and counts.failed tells you how many. If episode 3 failed and you publish 4 to 8 on schedule, your series now skips an episode. Check counts.failed and the gap list before you schedule anything.
Rerun only the failed episodes in a fresh queue, and mint a new batch Idempotency-Key for it: the bulk create takes one key for the whole batch, and replaying a spent key returns the old queue with a 202 instead of starting anything. Leave the episodes that completed out of the new queue so you do not pay for them twice.
| Question | Answer | Where it comes from |
|---|---|---|
| Do items finish in index order? | Not guaranteed; they run in parallel | Concurrency 1 to 16 |
| Where does order live? | Your episode_number field | Input and output schema |
| Does completed mean success? | No; read counts.failed | Queue status vs counts |
| Can I cancel the queue? | No; cancel a child run | No cancel-queue endpoint |
Hold the upload until the set is whole
The temptation is to publish each episode the moment its run completes, because it feels faster. For a numbered series it is the wrong default. Viewers who find the series mid-season start at episode one and expect the next video to be episode two. A hole at episode three breaks that for every viewer who arrives later.
A calmer rule is to stage everything. Collect all receipts, sort them, confirm there is no gap, and only then release in order. If one episode failed, you have a choice you can make deliberately: hold the season, or publish through the gap and fill it later. Either is fine. Finding out after the upload is not.
Also keep the original request order in your own record. If you queued items 1 to 12, store that list beside the queue id, so the check for gaps compares against what you asked for rather than against whatever happened to finish.
Make the number travel with the item
The safest design puts episode_number in three places: the item input you send, the instruction the agent reads, and the output schema it must return. If the three ever disagree on a receipt, something went wrong, and you want to see that before publishing rather than after.
Sources
Related posts
More in Formats
- Shorts series: episode video and thumbnail from one Format run
YouTube Shorts series take a custom thumbnail per episode. Bind one output schema so each Sume Format run returns the video and the thumbnail together.
- Sume Format run expires_at: 90 minutes, and how to set your timeout
A non-terminal Sume Format run carries an expires_at, 90 minutes from creation. Use it as your client timeout instead of inventing a number.
- Sume output schema limits: depth 10, 5,000 properties, 120,000 chars
How big can a Sume output_schema be? Depth 10, 5,000 properties and 120,000 characters, and a refusal before any spend. What to flatten and where it fails.
- Sume webhook payload is null: receipt over 1 MiB, fetch result_url
A Sume format.run.terminal webhook with payload null means the receipt was over 1 MiB. Read error.result_url and fetch the receipt instead of failing the run.
Written by Sume