Idempotency key for transcription: hash the request, avoid 409
Derive the Sume STT Idempotency-Key from a hash of audio_url, language and duration. A retry returns the same job. A changed body under that key is a 409.

Make the Idempotency-Key for a Sume transcription a hash of what the job means: the audio URL, the language code and the duration. A retry after a timeout sends the same key and gets the original job back with no second charge. Reusing a key with a different body is refused with 409 idempotency_conflict. Both rules are in Errors and rate limits and Jobs and results, read 2026-10-06.
Which keys fail, and why
A counter or a timestamp makes every retry a new job. A fixed string reused across clips makes the second clip a conflict. A hash of the request does neither: it is stable for the same intent and different for different intent. Keys can be up to 255 characters; a prefix plus 32 hex characters is plenty.
| Key | Retry after timeout | Next clip |
|---|---|---|
| Random UUID per attempt | New paid job | Fine |
| Same literal for a batch | Original job | 409 idempotency_conflict |
| Hash of url + language + seconds | Original job | New job |
A key function
Serialize with sorted keys so the order of fields never changes the hash.
import hashlib, json
def stt_key(audio_url, language_code, duration_seconds):
body = {"u": audio_url, "l": language_code, "d": duration_seconds}
digest = hashlib.sha256(json.dumps(body, sort_keys=True).encode()).hexdigest()
return f"stt-{digest[:32]}"
url = "https://media.sume.com/a.wav"
print(stt_key(url, None, 8))
print(stt_key(url, None, 8) == stt_key(url, None, 8))What if I change the language on purpose?
A new language code is a new request, so the hash changes and the job is new and billed again. That is correct: you asked for a different transcription. If you meant to retry the first one, you changed the wrong thing.
Sources
Related posts
More in Developers
- Ideogram 4.5 low to high on one order: new Idempotency-Key or a 409
A reused Idempotency-Key with a different payload returns 409 idempotency_conflict. Key on order id plus a payload hash so a quality change is a new job.
- Keep a series voice consistent: pin model, voice, speed and volume
A series sounds the same only if every episode sends the same TTS settings. Keep one profile in code, pin a model id, and send it with each Sume request.
- Same volume every Shorts episode: gain_db, duck_db, one music bed
Sume does not measure loudness. To keep a series consistent, pin audio.gain_db, soundtrack gain_db and duck_db in one function with one bed. Python plan loop.
- Ktor webhook route for an AI video job: receiveText and HMAC SHA-256
A Ktor route reads the raw body with call.receiveText(), checks Sume's sume-v1 HMAC over timestamp.body in Kotlin and returns 401 when the secret is empty.
Written by Sume