Localized video batch: one Sume bulk queue per language
Split a multilingual batch into one Sume bulk queue per language so each language gets its own concurrency, spend cap, idempotency key and retry.

Should one queue hold every language, or one queue per language?
A bulk queue holds 1 to 100 items, and each item has the same body as a single run, so a mixed-language queue is possible: every row simply carries its own language in input. But there are practical reasons to group by language instead.
A queue has one concurrency and one idempotency key, and it reports one set of counts. When all items share a language, a failure pattern is easy to read: if all 12 Korean items failed and the 12 Spanish ones passed, the problem is the Korean inputs or the Format's Korean handling, not luck.
What do I gain by splitting?
- Independent retries: re-submit the Korean queue with a new key without touching the others.
- Separate
generation_spend_cap_usdper language, since some voices and captions cost more than others. - Different
concurrencyper queue, within your plan's generation concurrency of 1 on Free, 4 on Pro, 8 on Startup or 20 on Scale. - Keys that name the language, such as
launch-42-ko, so a replay returns that language's queue and a changed payload is a409.
How do I build the queues?
Pass the language as your own input key and let the Format's instructions read it. The first-party cookbook recipe reads a vo_language key; for your own Format, document the key you choose in its SKILL.md. Group rows by language, then submit one queue each:
from collections import defaultdict
import os, requests
URL = "https://api.sume.com/v1/formats/acme/launch-clip/bulk-runs"
H = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"]}
def submit_by_language(batch_id, rows, concurrency=4):
groups = defaultdict(list)
for row in rows:
groups[row["language"]].append(row)
queues = {}
for lang, part in groups.items():
body = {"concurrency": concurrency,
"items": [{"input": r} for r in part[:100]]}
r = requests.post(URL, json=body, timeout=30,
headers={**H, "Idempotency-Key": f"{batch_id}-{lang}"})
r.raise_for_status()
queues[lang] = r.json()["data"]["id"]
return queues
What does the split not solve?
The ceiling per language is still 100 items, so a language with 140 rows needs two queues. Queues also share your workspace's wallet and concurrency, so five queues submitted together compete for the same slots. Check counts.failed on each, because completed only means every item is terminal.
Sources
Related posts
More in Formats
- Make Iterator and Array aggregator: build a Sume bulk items array
In Make, an Iterator splits an array into bundles and an Array aggregator joins them. Use the pair to turn sheet rows into a Sume bulk items array.
- Map Sume bulk queue results back to spreadsheet rows by item index
A Sume bulk queue lists items in the order you submitted. Use each item's index to write results back to the right spreadsheet row, and handle run_id null.
- A gift portrait for your store homepage: model product portrait Format
The sume-model-product-portrait Format returns one finished still of a person with your product. Use it for a homepage hero, not for a motion ad.
- November 1 switch: restyle Halloween product stills into a fall set
After Halloween, run your stills through the sume-restyle Format in one bulk queue of up to 100 items and keep the product while changing the mood.
Written by Sume