Retry a Sume video submit safely: Idempotency-Key and the 409 conflict
Send the same Idempotency-Key and the same body to retry a Sume video submit without a second charge. A different body under the same key returns 409.

Add an Idempotency-Key header to POST /v1/videos. If a network error hides the response, resend the same key with the same body, and you get the original job back instead of a second one. If you reuse the key with a different body, Sume answers 409, so a typo cannot silently start a different job.
This matters most for long and expensive jobs, where a duplicate would hold the reserve twice.
What the key does
The docs say an idempotent replay gets the same route and the same price, because the sume/auto resolution is a pure function of the normalized request and the catalog version. The key ties the request to one job.
The key is yours to choose. Use something stable and unique, like an order id plus the shot number.
| Request | Result |
|---|---|
| new key, any body | new job, 202 |
| same key, same body | the original job |
| same key, different body | 409 conflict |
| no key | a new job every time |
A retry in Python
The script retries the submit up to three times on a network error and keeps the same key for each attempt. It stops on an HTTP error, because a 400 or 402 will not change on a retry.
import json, os, time, urllib.error, urllib.request
body = json.dumps({"model": "gemini-omni-flash-1.1",
"prompt": "A paper boat drifting down a rain gutter",
"duration": 5, "resolution": "720p"}).encode()
headers = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"],
"Content-Type": "application/json", "Idempotency-Key": "boat-shot-001"}
for attempt in range(3):
req = urllib.request.Request("https://api.sume.com/v1/videos",
data=body, headers=headers, method="POST")
try:
with urllib.request.urlopen(req, timeout=60) as r:
print(json.load(r))
break
except urllib.error.HTTPError as e:
print(e.code, e.read().decode())
break
except OSError:
time.sleep(2 ** attempt)Which errors to retry
Retry only when you got no response. A 402 insufficient_credits means the wallet is below the reserve, so add credit first. A 400 means the request is invalid, and the same request fails again. A 429 is rate limiting, so wait before the next try.
A 502 means the provider submission failed, and a retry with the same key is reasonable.
Key hygiene
Never reuse a key for a new shot, even a similar one, or you will get the old job or a 409.
- Build the key from your own record id.
- Keep the body byte-for-byte the same on a retry.
- Store the key with the job id.
- Change the key when you change the prompt on purpose.
Related posts
More in Developers
- Retry a video-trim: same key for the same body, new key for new start
A trim that timed out can be retried with the same Idempotency-Key and body. Changing start, duration or precision is a new operation and needs a new key.
- Revoked a Sume API key: does its past spend disappear from Usage?
No. Revoking a key does not cancel the attribution of past spend. Rows tied to the key id keep their origin; mismatched rows are skipped, not guessed.
- Rolling a webhook secret: Stripe's 24-hour overlap vs Sume's header
Stripe can keep an old signing secret live for up to 24 hours. Sume sends one sume-v1 entry per live secret; verify any match. Python verifier included.
- Rotate the Sume webhook secret without dropping deliveries
Sume signs with both secrets for 24 hours after a rotation, comma-separated in x-sume-webhook-signature. Upgrade the verifier first, then rotate. Steps inside.
Written by Sume