OpenRouter batch custom_id vs one Sume Idempotency-Key per job
OpenRouter's Batch API needs a custom_id unique within each batch. Sume has no batch envelope for these submits: give each job its own Idempotency-Key.

In OpenRouter's Batch API, each item in the requests array is { custom_id, body }, and custom_id must be unique within the batch. For the Sume generation endpoints in these docs, the equivalent is one Idempotency-Key per submitted job, each its own request. Build the key from your item id so a retry of item 7 repeats key 7 and nothing else.
OpenRouter facts are from its quickstart, read 2026-10-01. Sume facts are from Generation admission and Jobs and results.
What does custom_id do on OpenRouter?
It labels one request inside a batch. Submit returns 202 Accepted with status: "validating", and results come back later keyed to your ids. It is a lookup key inside one batch, not a retry guard across submits.
How does a Sume submit map to it?
| Concept | OpenRouter Batch API | Sume submit |
|---|---|---|
| Item label | custom_id, unique within the batch | Your own item id, kept in your code |
| Retry guard | Not what custom_id is for | Idempotency-Key header per submit |
| Unit of work | One batch, many requests | One accepted submit is one durable job id |
What does a per-item key look like?
The docs' bulk-loop example uses Idempotency-Key: avatar-batch-001-item-001: batch name plus item number. A submit is accepted the moment Sume has a durable job id, so store that id per item.
const items = ["a", "b", "c"];
for (const [i, item] of items.entries()) {
const key = "batch-001-item-" + String(i + 1).padStart(3, "0");
console.log(key, item);
// POST to your Sume generate endpoint with header "Idempotency-Key": key
}What breaks if I reuse a key?
Reuse the same key only for the same operation and payload. Per the admission docs, reusing a key for a different operation or payload returns 409 idempotency_conflict; reuse keys only for exact retries, so fix your key derivation rather than retrying as is. For another vendor's id-in-payload pattern, see Replicate's custom id vs Sume's job id.
Sources
Related posts
More in Developers
- OpenRouter batch 24h window and expired vs Sume queued jobs
OpenRouter batches use a 24-hour completion window and can end as expired. Sume jobs have no queue expiry option today: a queued job waits, or you cancel it.
- OpenRouter batch DELETE 409 vs Sume cancel 409 after start
OpenRouter returns 409 when you DELETE an in-flight batch. Sume returns 409 job_generation_already_started on cancel once generation starts. Handle both.
- OpenRouter batch has no results download; Sume has a URL per job
OpenRouter batch results come inline on GET /batches/:id with no download endpoint. Sume returns a result_url per job and a batch result read over MCP.
- OpenRouter batch results kept 30 days; Sume media URLs don't expire
OpenRouter deletes batch inputs and results 30 days after creation, then returns 410 Gone. Sume job results use durable media.sume.com URLs that do not expire.
Written by Sume