Can you cancel a Sume TTS job? Only before generation starts
Sume cancels a job only before generation work begins. After that the cancel call is rejected with 409. How to code for both outcomes.

Yes, but only early. POST /v1/jobs/{id}/cancel durably cancels a Sume job before generation work has started. Once any external generation task has begun, cancellation is rejected, so usage settlement cannot refund work that was already submitted. That applies to TTS, STT and every other job type that goes through the same job routes.
So a cancel button in your product should be a request, not a promise. Build the UI and the code so that a rejected cancel is a normal result.
What does the cancel route say?
The Sume OpenAPI spec lists 200, 400, 401, 404, 409, 429, 500 and 503 for the cancel route. A 200 returns canceled, an idempotency_hit flag that is true when the job was already canceled, and the job record. A 409 is the signal that generation has already begun.
| Job state when you call cancel | Expected result |
|---|---|
| Queued, generation not started | 200, status CANCELED |
| Already canceled | 200 with idempotency_hit true |
| Generation already submitted | Rejected, expect 409 |
| Job id you cannot see | 404 |
How do you handle a rejected cancel?
Do not resubmit the same text. A second job is a second charge. Instead, let the first job finish, and discard the result if the user no longer wants it. If a sync wait timed out and you are tempted to retry, read what to do when a TTS sync wait times out first.
- Check
cancelableon the status response before you show a cancel control. - Treat 409 as success of the job, not failure of your app.
- Keep job ids; they are your handle for status, result and events.
What does the code look like?
A small helper that reports which outcome you got:
import os, requests
H = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"]}
job_id = os.environ["JOB_ID"]
r = requests.post(
f"https://api.sume.com/v1/jobs/{job_id}/cancel",
headers=H, timeout=30,
)
if r.status_code == 200:
print("canceled", r.json()["data"]["canceled"])
elif r.status_code == 409:
print("too late: generation already started, wait for the result")
else:
print("unexpected", r.status_code, r.text[:200])
Why does Sume work this way?
The spec gives the reason directly: cancellation after submission would let usage settlement refund work already sent for generation. The status response carries a cancelable flag that is true only before external generation work has started, so check it rather than guessing.
Sources
Related posts
More in Developers
- Captions for a clip that switches English and Spanish mid-sentence
MAI-Transcribe-2-Streaming advertises continuous language detection. For a recorded code-switching clip on Sume, lock the wording with script_text.
- Watch the Sume video catalog for new ids and changed limits in Python
Fetch GET /v1/videos/models, save a snapshot and diff new ids, removed ids and changed durations or resolutions. A Python script, testable offline.
- Chapter markers from Sume STT sentence segments
Request segmentation mode sentence on Sume STT, get time ranges per sentence, and turn the ones you pick into 0:00-style chapter lines with a 12-line formatter.
- Check Sume artifact size, width and duration before you download
Read size_bytes, width, height and duration_ms from the job result and reject an unexpected artifact before spending bandwidth. Node 18 TypeScript sample.
Written by Sume