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.
- 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.
- Scalar API Reference for the Sume OpenAPI JSON, with a Try It key
Scalar renders an OpenAPI document as an interactive reference with a test client. Point it at the Sume spec, and keep the Bearer key out of the page source.
- Sume SDK wait timeouts: 20 min, 10 min, and the 90-minute run
subscribeFormatRun waits 20 minutes, waitForRun 10, waitForJob 20, yet a run lives up to 90. Which clock fires first and how to resume after a timeout.
Written by Sume