Cancel a queued transcription job: what the 409 means

POST /v1/jobs/{id}/cancel works only before work starts. After that it returns 409 job_generation_already_started and the job finishes and bills normally.

4 min readSume
All posts

You can cancel a Sume transcription job only while it is still queued. POST https://api.sume.com/v1/jobs/{id}/cancel returns success before generation work starts; once the job is processing, the same call returns 409 job_generation_already_started with details.cancelable: false, and the job completes or fails normally. A cancel of a job that is already canceled is idempotent. Facts here are from Generation admission and Errors and rate limits, read 2026-10-06.

Why the cutoff exists

The OpenAPI description of the cancel route gives the reason: once any external generation task has begun, cancellation is rejected so usage settlement cannot refund work already submitted. Cancellation is a way to drop work you have not started paying for, not a way to stop a running job.

That matters for a bulk transcription run. If a batch is accepted as 120 queued jobs and you realize the audio URLs are wrong, cancel the queued ones first and let the few processing jobs finish.

Cancel behavior by job status, from Generation admission (docs.sume.com), read 2026-10-06.
Job statusCancel resultWhat to do
queuedCanceled; cancelable is trueCancel the jobs you no longer need
processing409 job_generation_already_started, details.cancelable: falseWait; the job completes or fails
canceledIdempotent successNothing to do
completed / failedNot cancelableRead the result or the events

A cancel loop that respects the 409

Treat the 409 as information, not as an error to retry. List what is still queued, cancel each id, and count the ones that had already started.

import os, requests

API = "https://api.sume.com"
H = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}


def cancel_queued(job_ids):
    canceled, started = [], []
    for job_id in job_ids:
        r = requests.post(f"{API}/v1/jobs/{job_id}/cancel", headers=H, timeout=30)
        if r.status_code == 409:
            started.append(job_id)
        else:
            r.raise_for_status()
            canceled.append(job_id)
    return canceled, started

How do I check what a canceled job cost?

Ask the ledger instead of assuming. GET /v1/usage?job_id=... returns a summary.debited_usd_micros for that job, and held or refunded amounts are not counted as spend. A job canceled while queued should show nothing debited; one that already started will show its normal capture. The step-by-step is in what one transcription job cost.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume