One Idempotency-Key, two Sume Formats: you start two runs

A Sume idempotency key is scoped to one Format, so one key sent to two Formats starts two paid runs. Build keys from order, Format and version.

4 min readSume
All posts

The scope of a Sume idempotency key is one Format, so sending the same key to two different Formats starts two runs and charges for both. Put the Format slug into your key, along with the order or item and a version number, and hash it if it could pass 255 characters.

The four replays

Sume's Format docs list four outcomes for a replay. The same key with the same body returns 200 with the original receipt and idempotency_hit: true, and no second run or charge. The same key with a different body is 409 idempotency_conflict. Two requests at the same moment give one winner and a retryable 409 idempotency_key_in_use. And a key that was used on a create that failed, for example with 402 or 503, is released.

Where the scope surprises people

The scope rule is stated just under that table: if you send the same key to two Formats, you start two runs. It is easy to trip on when one order triggers two Formats, say a product commercial and a slideshow, and a shared helper builds the key from the order id alone.

Compared with Stripe

Stripe's idempotency page is a useful comparison, because many teams copy its habits. Stripe keys can be up to 255 characters, results are saved including 500 errors, keys may be pruned after 24 hours, and a request whose parameters differ from the saved one returns an error (per its page, read 2026-10-05). Sume documents the 255-character limit and the replay table above. The Format docs do not state a pruning window, so do not build a flow that depends on one.

Idempotency rules compared (Stripe page read 2026-10-05, Sume docs from repo)
RuleStripeSume Format run
Maximum key length255 characters255 characters
Same key, different bodyError409 idempotency_conflict
ScopeNot stated on the pageOne Format
Key after a failed createSaved result is replayed, including 500sReleased after 402, 503 and similar
PruningMay be pruned after 24 hoursNot documented

A key that names its Format

The function below builds a key that includes the Format slug. It hashes the parts, so the result is always 64 characters, and it changes only when you bump the version. It is plain Python, so you can run it as written and drop it into any caller.

import hashlib

def run_key(customer: str, order: str, format_slug: str, version: int) -> str:
    raw = f"{customer}|{order}|{format_slug}|v{version}"
    return hashlib.sha256(raw.encode()).hexdigest()

a = run_key("cust-42", "order-9001", "sume-product-commercial", 1)
b = run_key("cust-42", "order-9001", "sume-slideshow", 1)
print(a)
print(len(a), a != b)

What to leave out of the key

Do not use the time of the request, or a fresh UUID for each call. The docs warn that a new value for each request makes the header useless. Bump the version only when you want a re-run, for example after you change the brief.

A side benefit

A key that includes the Format also makes support easier. When a run looks duplicated, the key tells you at once whether it was a retry that missed the key, or two different Formats that were meant to run.

Sources

Related posts

More in Formats

All Formats posts

Written by Sume