Cancel a queued avatar creation job before generation starts

Cancel a Sume avatar creation job with POST /v1/jobs/{id}/cancel. It works only before generation starts; later you get 409. Only the creator can cancel.

4 min readSume
All posts

You can cancel a queued avatar creation job on Sume with POST /v1/jobs/{job_id}/cancel, but only before generation work starts. If generation has begun, the API returns 409 job_generation_already_started with details.cancelable: false, and the job runs to completion. A cancel on a job that is already canceled is idempotent and returns the same canceled job. Only the member who created the job can cancel it.

This is the rule in Jobs and results, read 2026-10-05, and avatar creation uses the same jobs as every other submit endpoint, as shown on Create new avatar.

The three responses

Three outcomes are possible, and your code should handle each of them.

The first row is the only one where the cancel changes anything. The second is a safe no-op, which lets you call cancel twice, for example from a retry, without an error. The third and fourth are information: the job is not yours to stop, or it is already past the point where stopping is possible. Build the client so that all four are expected outcomes, with a message for each, rather than treating anything but success as an exception.

Cancel outcomes for a job, read 2026-10-05
Job state when you cancelResponseWhat to do
Queued, generation not startedJob becomes canceledStop polling; a job.canceled webhook is sent if you set one
Already canceledSame canceled job, idempotentTreat as success
Generation started409 job_generation_already_started, cancelable falseLet it finish and use or ignore the result
Created by a different memberNot cancelable by you; reads return 404Ask the creating member or use their key

Cancel from Python

The script below sends the cancel, reads the outcome, and prints what to do. It refuses to run with no API key and takes the job id as an argument.

import json, os, sys, urllib.request, urllib.error

key = os.environ.get("SUME_API_KEY", "")
if not key or len(sys.argv) < 2:
    sys.exit("Usage: SUME_API_KEY=... python3 cancel.py JOB_ID")
req = urllib.request.Request(
    "https://api.sume.com/v1/jobs/%s/cancel" % sys.argv[1],
    method="POST", headers={"Authorization": "Bearer " + key})
try:
    job = json.loads(urllib.request.urlopen(req).read().decode())
    print("status:", job.get("status"))
except urllib.error.HTTPError as e:
    err = json.loads(e.read().decode()).get("error", {})
    d = err.get("details") or {}
    print(e.code, err.get("code"), "cancelable:", d.get("cancelable"))

What a 409 means

Do not treat a 409 as a failure of your job. It means the work was handed over and now runs on its own schedule. The job will complete, fail or be canceled by the system, and you will see the terminal state through polling or a webhook of type job.completed, job.failed or job.canceled.

Also remember that a client-side timeout is not a cancel. The docs say a timeout in your process does not stop the job, and that you should poll the status URL or cancel explicitly. If you gave up waiting on an avatar, either poll until it is terminal or send the cancel yourself while it is still queued.

For a job that did start, you still have choices. You can ignore the result and let it be one more asset in your library, or you can use it. The docs say the job runs to completion, so plan for the cost of a started job to be incurred. What you control is what you do next, and whether your system submits another job for the same photo.

When the window is short

Cancel as early as you can. The docs say only that a cancel works before generation work starts, and they do not state how long that window lasts, so do not build a flow that depends on it. A realistic use is a user who uploads the wrong photo and corrects it in seconds. For a longer decision, such as comparing candidates, do not rely on a cancel: use the free preflight and previews, covered in the ten photo post.

See where the job is

Watch the job's events if you need to know where it is. The events post shows how to read them, and the 409 post covers the same error for video jobs.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume