Retry a timed-out POST /v1/videos with one Idempotency-Key, pay once

A Python submit wrapper that retries network errors, 429 and 5xx with a stable Idempotency-Key, so a replay returns the original job instead of a second charge.

3 min readSume
All posts

Send the same Idempotency-Key on every retry of the same POST /v1/videos, and a replay returns the original job rather than starting and billing a second one. Build the key from something stable in your own system, such as an order id and clip number, not a fresh UUID per attempt.

This matters most on timeouts. Your client cannot tell whether the request died before or after Sume created the job, and the docs are explicit that you must not submit duplicate paid work because a local call timed out.

The wrapper

It retries connection errors, timeouts, 429 and 5xx, honors retry-after, and raises immediately on other 4xx such as 402 or 400.

import os, time, requests

H = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"]}

def submit(body, key, tries=5):
    for n in range(tries):
        r = None
        try:
            r = requests.post("https://api.sume.com/v1/videos", json=body,
                              headers={**H, "Idempotency-Key": key}, timeout=30)
        except (requests.ConnectionError, requests.Timeout):
            pass
        if r is not None and r.status_code != 429 and r.status_code < 500:
            r.raise_for_status()  # 400/402/409 are not retried
            return r.json()
        wait = float(r.headers.get("retry-after", 0)) if r is not None else 0
        time.sleep(max(wait, 2 ** n))
    raise RuntimeError("gave up; resend with the same key: " + key)

job = submit({"model": "wan-3.0", "prompt": "Rain on a window, macro",
              "duration": 6, "resolution": "480p"}, "order-8823-clip-1")
print(job["id"])

The key rules

  • Reuse a key only for the exact same operation and payload.
  • The same key with a different body returns 409 idempotency_conflict.
  • Do not retry 402 insufficient_credits; no key can fix a short balance.
  • After a queue_full or provider_capacity_exceeded, retry later with the same key.

What a duplicate would have cost

One six-second Wan 3.0 clip at 480p is $0.375 on Sume. A wrapper that mints a new key per attempt and retries five times after an ambiguous timeout could, in the worst case, create five jobs and reserve $1.875 for one intended clip. A stable key keeps it at one.

Choosing the key

A good key names the intent, not the attempt. order-8823-clip-1 stays the same across retries, restarts and even a different worker picking up the same item. A random UUID generated inside the retry loop does the opposite and defeats the whole mechanism. If you do generate a UUID, create it once, persist it with the work item, and read it back on every attempt.

Idempotency key patterns
Key sourceSurvives a crash?Safe to retry?
Order id plus clip numberYesYes
UUID stored with the work itemYesYes
UUID created inside the retry loopNoNo, each attempt is a new job
TimestampNoNo

Remember that a key is bound to its payload. If you edit the prompt and resend under the same key, you get 409 idempotency_conflict; that is the signal to mint a new key because the operation is now a different one.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume