Submit 12 thumbnail jobs with mode async and Idempotency-Key on Sume
Queue a dozen 16:9 thumbnails on POST /v1/images with mode async and one Idempotency-Key each. Re-run the script safely, then poll the status URLs. Python code.
To queue a batch of thumbnails without blocking, send each request to POST /v1/images with "mode": "async" and a stable Idempotency-Key. Each call returns 202 at once with a job envelope that holds status_url and result_url. If your script crashes and you run it again with the same keys and payloads, you get the original jobs back instead of paying twice.
Why async for a batch
A sync call waits up to 30 seconds per image, which makes a loop of twelve slow and fragile. Async returns immediately, so you can submit all of them and poll. YouTube asks for a 16:9 aspect ratio for video thumbnails and JPG or PNG files (YouTube Help, read 2026-10-07), so the request below asks for 16:9 and png.
The script
Set SUME_API_KEY. The keys are derived from the video id and variant number, so the same input always maps to the same key. Change the payload and you must change the key.
import os
import requests
URL = "https://api.sume.com/v1/images"
HEAD = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
prompts = [f"thumbnail variant {i}: bold title, one face, high contrast" for i in range(1, 13)]
jobs = []
for i, prompt in enumerate(prompts, start=1):
resp = requests.post(
URL,
headers={**HEAD, "Idempotency-Key": f"vid42-thumb-v{i}"},
json={"model": "google/nano-banana-2.1", "prompt": prompt,
"aspect_ratio": "16:9", "output_format": "png", "mode": "async"},
timeout=30,
)
resp.raise_for_status()
data = resp.json()["data"]
jobs.append((data["job"]["id"], data["status_url"]))
print(i, resp.status_code, data["job"]["id"])
print(len(jobs), "jobs queued")Read the results
For each status_url, poll until terminal is true, then fetch result_url when result_ready is true. The images are under result.artifacts[] as Sume-hosted URLs. For a callback instead of polling, use mode: "webhook" with a public HTTPS webhook_url and verify the signature, as described in Webhooks.
What the batch costs
| Item | Amount |
|---|---|
| Per image (1K) | $0.10 |
| Twelve images | $1.20 |
| Same twelve at 2K | $1.80 |
Retry and recovery
Three failure modes matter in a batch. A network error on submit: retry the same request with the same Idempotency-Key. A 4xx on one payload: fix the payload and use a new key. A job that ends failed: a failed generation is not billed, so resubmit with a fresh key.
Store (key, job id, status_url) in a file or table as you submit. If your process dies halfway, the next run reads the table, skips submitted keys and carries on. That turns twelve thumbnails into a resumable job, and a hundred videos into a queue you can reason about.
Rules to keep
- Reuse a key only for the same operation and payload; the retry then returns the original job and bills once.
- A failed or cancelled generation is not billed.
- Do not resubmit a paid job for the same intent while a poll is possible. See Jobs and results.
Sources
Related posts
More in Developers
- Submit 40 image jobs with mode webhook in Python on Sume
Send 40 POST /v1/images calls with mode webhook and a webhook_url: each returns a 202 job envelope at once and the result follows. Python, cost, status codes.
- Submit 6 ad hooks in parallel in Python with one Idempotency-Key each
A Python script that submits six 3-second Omni hook jobs in parallel, each with its own Idempotency-Key so a retry replays the original job. Cost: $2.25.
- Submit a Sume video job from PHP with cURL: sume/auto and polling
Replace a Sora call in a PHP worker with Sume /v1/videos: submit with cURL, poll the job, read the download URL, and know what a default clip costs.
- Submit and poll a Sume video job from Rust with reqwest
Rust reqwest blocking client for Sume /v1/videos: submit a sume/auto job, poll until completed, print the download URL and usage.cost. Cargo features listed.
Written by Sume