Wan 3.0 draft and final need different Idempotency-Keys (409)

Reusing one Idempotency-Key for a 480p draft and a 1080p final of the same prompt returns 409 idempotency_conflict. A Python key builder that avoids it.

3 min readSume
All posts

When you re-render a Wan 3.0 draft at final quality, change the Idempotency-Key. Sume's Generation admission page lists 409 idempotency_conflict for a key reused with a different operation or payload, and the 480p draft and the 1080p final differ in resolution. The key belongs to one exact request; reuse it only to retry that request. A retry of the draft costs nothing extra, and a 30-second 1080p final costs $7.50 against $1.875 for the draft.

A key that encodes what the request is

Build the key from the fields that change the result. Two requests with the same fields give the same key, so retries are safe; a changed field gives a new key.

import hashlib, json

def idem_key(shot: str, body: dict, version: int = 1) -> str:
    fields = {k: body[k] for k in ("model", "prompt", "duration", "resolution", "aspect_ratio")}
    digest = hashlib.sha256(json.dumps(fields, sort_keys=True).encode()).hexdigest()[:12]
    return f"{shot}-{body['resolution']}-v{version}-{digest}"

draft = {"model": "wan-3.0", "prompt": "Slow push-in on a sneaker", "duration": 30,
         "resolution": "480p", "aspect_ratio": "9:16"}
final = {**draft, "resolution": "1080p"}
print(idem_key("sneaker-ad", draft))
print(idem_key("sneaker-ad", final))
assert idem_key("sneaker-ad", draft) != idem_key("sneaker-ad", final)

What each outcome means

Behavior described in the admission docs and the idempotency guidance
You sendResult
Same key, exact same payloadThe original job comes back; no second reserve
Same key, different resolution409 idempotency_conflict
New key, same payloadA new job and a new reserve
No key on a retried POSTA second job is possible; keep the key

The cost of getting it wrong

A conflict is a rejected call, not a charge, so the failure is annoying rather than expensive. The expensive error is the opposite one: minting a fresh key on every retry of a timed-out submit, which can start two jobs for the same shot. At 1080p, two 30-second jobs cost $15.00.

Persist the key with the shot before you send the request, so a crash and restart reuses it.

Storing the key

Write the generated key into your database row for the shot before you send the request, and read it back on retry. If you generate it from a hash of the request fields, as above, the key is reproducible even if the row is lost.

Version bump for a deliberate re-run

Submitting the same fields under a new version starts a new job on purpose, which is how you ask for another take. Use that when you want another attempt, and keep the version unchanged when you are only retrying a failed call.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume