Idempotency keys for a SKU catalog: SKU, asset, version

A fresh uuid per request makes Sume's Idempotency-Key decorative. Build it from SKU, asset and version so a retried holiday batch is not charged twice.

5 min readSume
All posts

Build the Idempotency-Key from the thing being made: SKU, asset name and a version number you bump on purpose. Then a retry after a timeout, or a script you run twice by mistake, returns the original instead of making and charging for a second one. A new uuid per request does the opposite.

Catalogs are about to get bigger and messier. Amazon's Seller Central now lets sellers import and link listings from eBay, Shopify, TikTok and Walmart (read 2026-10-04), so the same product can reach your media script from several places.

What do the docs say a replay does?

For Format runs, the docs describe the behavior exactly. Other create endpoints, such as video trim and Timeline 1.0, require the header too, so the same key habit applies.

Idempotency replay results for Format runs, from Sume docs, read 2026-10-04
ReplayResult
Same key, same body200 with the original receipt and idempotency_hit: true; no second run, no second charge
Same key, different body409 idempotency_conflict; nothing runs
First use of a key202, a fresh run

How should you name the key?

Make it readable and stable. Something like sku-1001-hero-clip-v1 says what it is. Bump v1 to v2 only when you deliberately want a new result, for instance after changing the prompt. If you change the body but keep the key, you get a 409 instead of a new job, which is the safe failure.

import os, requests

def trim(sku, version, start, duration, url):
    return requests.post(
        "https://api.sume.com/v1/video-trim",
        headers={
            "Authorization": "Bearer " + os.environ["SUME_API_KEY"],
            "Idempotency-Key": f"{sku}-supplier-trim-v{version}",
        },
        json={"video_url": url, "start": start, "duration": duration},
        timeout=60,
    )

url = "https://media.sume.com/artifacts/artf_demo/supplier.mp4"
for _ in range(2):
    print(trim("SKU-1001", 1, 0, 30, url).status_code)

What should you store?

Keep a row per key: SKU, asset, version, the job or run id from the response and the time. Then a crashed script can resume by skipping keys that already have an id, and the usage ledger can be read per job. The docs say that for Format runs you should store data.id and follow the URLs on the receipt.

When is a new key right?

When the output should differ: a new prompt, a new source photo, a different length. Bump the version, and write down why. When the output should be the same, never mint a new key.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume