Sume job 404 for an id you created: check which member's key made it

A 404 on GET /v1/jobs/{id} can mean the job belongs to another member or workspace. A Python helper separates unknown from not visible.

5 min readSume
All posts

If GET /v1/jobs/{id} returns 404 for a job id you know exists, the likely cause is that you are reading with a different key than the one that created the job. A Sume API key reads only the jobs that its own member created, in the workspace of the key. Everything else answers 404 not_found, the same as an id that never existed, so the response does not reveal whether the job is real.

This shows up in teams: one person submits a batch, a second person's key tries to poll it, and the poller sees nothing. The fix is to read with the creating member's key, or to keep results in your own store.

The visibility rule

A thread_id filter on the list makes it smaller. It never increases what a key can read.

Who can read a job (Sume docs read 2026-10-08)
ReaderCan readGets 404 for
API keyJobs created by the key's own member, in the key's workspaceOther workspaces, and jobs of other members
Studio Agent turnEach job in the thread it runs on, whoever created itJobs in unrelated threads of other members
Anyone, to cancelOnly the member who created the jobJobs of other members

Telling unknown from not visible

The API gives the same 404 for both, so your own ledger has to tell them apart. If the id is in your table of submitted jobs, a 404 means the reader cannot see it; if it is not, the id is unknown or mistyped. The helper below encodes that. It takes the HTTP call as an argument, so you can test it offline, and the run shows the three outcomes.

class NotVisible(Exception):
    pass

def read_job(get, job_id, ledger):
    status, body = get(f"/v1/jobs/{job_id}")
    if status == 200:
        return body
    if status == 404 and job_id in ledger:
        raise NotVisible(f"{job_id} is ours, but this key cannot read it: check the key's member and workspace")
    if status == 404:
        raise KeyError(f"{job_id}: unknown id")
    raise RuntimeError(f"unexpected {status}")

ledger = {"job_a"}
same_key = lambda path: (200, {"id": "job_a", "status": "completed"})
teammate_key = lambda path: (404, {"error": {"code": "not_found"}})
print(read_job(same_key, "job_a", ledger)["status"])
for jid in ("job_a", "job_zzz"):
    try:
        read_job(teammate_key, jid, ledger)
    except (NotVisible, KeyError) as e:
        print(type(e).__name__, e)

What to do next

  • Store the id of the key's member (or a label for the key) next to each job in your ledger.
  • Poll with the same key that submitted. Do not share job ids between services that use different keys.
  • Use a webhook so the result is delivered to your endpoint without a read.
  • Do not retry a submit because a read returned 404. The job is probably running.

Cancel follows the same rule

Only the creating member can cancel a job. A cancel from another key will not find it. Cancellation also works only before generation starts; after that the API answers 409 job_generation_already_started and the job runs to completion.

Checks to run first

Before you suspect the job, check three things. First, the key: print the last four characters of the key in use and compare them to the key that submitted. Second, the workspace: a key is issued in one workspace, and a job from another workspace is not visible. Third, the id: copy it again, because a stray character gives the same 404.

If all three match and the job is still not found, read GET /v1/jobs with the same key and look for the id in the list. A job that appears there but not in the direct read would be worth reporting with its request id.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume