Retake one narration line: why reusing the key returns 409
Resubmitting a changed TTS script under the same Idempotency-Key returns 409 idempotency_conflict, and an identical retry returns the original job. Key naming.

If you change a narration line and resubmit it under the same Idempotency-Key, Sume returns 409 idempotency_conflict, because the key was reused for a different payload. The generation admission docs, read 2026-10-03, tell clients to reuse keys only for exact retries. The fix is a new key for the new line; keep the old key for retries of the old line.
Which resubmit does what?
The first row comes from the jobs docs' rule for a bounded wait that expired: continue by polling, and if you retry the submit, reuse the same key.
| You send | What happens |
|---|---|
| Same key, same payload, after a timeout | The retry returns the original job instead of billing a second one |
| Same key, edited script | 409 idempotency_conflict |
| New key, edited script | A new paid job, billed as its own generation |
| Same key, different operation | 409 idempotency_conflict |
How should I name keys?
Build a key from the line and its revision, such as ep12-line07-r1 and ep12-line07-r2. A retry of revision two reuses revision two's key; an edit bumps the revision. Over MCP, tts_create needs an idempotency_key as well, and the docs say it is a transport and dedup key, not human approval.
What about the other takes?
- Only the edited line is a new job. The other lines' takes stay as they are, and you rejoin them with Timeline audio
concat. - Do not edit and resubmit just because a wait timed out. Poll first; a timeout is not a failure.
- Docs do not describe how long a key is remembered, so do not rely on a very old key still deduplicating.
Sources
Related posts
More in Developers
- Reverse a video by API: FFmpeg reverse is not on Sume's allowlist
FFmpeg's reverse filter buffers a whole clip. Sume's video-filter allowlist has no reverse and no setpts, and the free check shows it. What to do instead.
- Verify a Sume webhook in Ruby with OpenSSL, no Rack or Rails
A plain Ruby verifier for Sume's sume-v1 HMAC header: OpenSSL::HMAC, a constant-time compare that works on old Rubies, a 300 second window and a self-test.
- Run an OpenRouter video script on Sume: four changes (Python)
Sume's /v1/videos copies OpenRouter's video wire. Port a polling script by changing the base URL and model id, then dropping seed, size and provider options.
- Sume run webhook 3xx redirect: a failed attempt, not a delivery
Sume does not follow redirects on run webhooks, so a trailing-slash 301 fails every attempt. How to find it with a no-follow probe and register the final URL.
Written by Sume