tts_source_revision_mismatch 409: stale expected_script_revision_id
Sume returns 409 tts_source_revision_mismatch when the accepted script changed under you or a run is frozen. How to re-read the revision and retry.

tts_source_revision_mismatch is a 409 from the Sume script-source API. It is the optimistic-concurrency error: the accepted script revision is not the one your request assumed. It has four triggers in the code, and the fix is always to read the current revision and decide again. All of these come back in Sume's standard error envelope with an HTTP status and a stable code, so branch on the code, not the message text.
The accept call, POST /v1/tts-1.0/source, takes script_texts and an optional expected_script_revision_id. If you pass it and the thread's current accepted revision is a different one, the answer is 409 with the message "Accepted revision changed." Pass null to say "I expect there is no accepted revision yet."
The four triggers
| Situation | Message | What to do |
|---|---|---|
| expected_script_revision_id differs from the thread's current revision | Accepted revision changed. | GET /v1/tts-1.0/source, merge, resubmit with the new id. |
| Generating with a revision not bound to this generation | The revision is not bound to this generation. | Use the revision accepted on this thread. |
| Run has no accepted source binding | This run has no accepted source binding. | Accept a script on the thread before the run starts. |
| Editing a frozen run | Accept edits on the thread, not an already frozen run. | Accept the edit on the thread, then start a new run. |
Safe update loop
The pattern is read, change, accept with the id you read, and on 409 start over. It stops two writers from silently replacing each other's script. Accepted revisions are immutable, so the previous revision and the jobs generated from it are untouched.
curl -s "https://api.sume.com/v1/tts-1.0/source" \
-H "x-api-key: $SUME_API_KEY" -H "content-type: application/json" \
-d "{\"script_texts\": [\"Hello there. Second sentence.\"], \"thread_id\": \"$THREAD\", \"expected_script_revision_id\": \"$REV\"}"Cost
A 409 is raised before dispatch, so it creates no job and no charge. The jobs you already generated from the older revision keep their receipts; verify-spine can re-adopt unchanged sentences when you pass explicit sentence_ids.
Sources
Related posts
More in Developers
- tts_source_too_large 422: Sume TTS 20,000-character cap on a selection
A transcript_source selection that resolves past 20,000 characters returns 422 tts_source_too_large. Split it by sentence ids and price each job.
- tts_text_source_conflict 400: transcript or transcript_source
Sume TTS wants exactly one of transcript and transcript_source. Sending both, neither or a malformed source returns 400. Which code, and how to fix.
- Sume TTS transcript_receipt: it proves the text, not the pronunciation
A source-bound Sume TTS job returns a transcript_receipt with a SHA-256 of the submitted text. It proves what was sent, not how it was spoken. Listen too.
- TTS sentence_ids: max 1,000 per request vs the 20,000-character cap
Sume TTS transcript_source takes 1 to 1,000 sentence ids, but the 20,000-character limit usually binds first: only sentences under 20 characters hit 1,000.
Written by Sume