Why GET /v1/jobs/:id returns 404 for a job that exists: the owner rule
An API key reads only jobs its own member created in its workspace. Other members' jobs and other workspaces answer 404 not_found, which is how Sume hides them.

If GET /v1/jobs/:id returns 404 not_found for a job you know exists, the key you are using almost certainly did not create it. A job belongs to its workspace and to the member whose key or Agent turn created it, and an API key reads only the jobs its own member created in the key's workspace.
Sume answers 404 rather than 403 on purpose, so a key cannot learn whether a job id exists elsewhere. That makes the error look like a typo when it is really a visibility rule.
The read rule, case by case
The same rule governs GET /v1/jobs/:id, /status, /result, /events and the list call GET /v1/jobs. This table restates the Sume docs page on who can read a job (read 2026-10-03).
| Reader | Can read | Gets 404 for |
|---|---|---|
| API key | Jobs its own member created, in the key's workspace | Jobs from other workspaces, and other members' jobs |
| Agent turn in a thread | Every job in the thread it runs on, whoever created it | Jobs in unrelated threads of other members |
| Interactive turn | Its own member's jobs in sibling threads | Other members' jobs outside the thread |
| Unattended run | Only its own thread | Everything outside that thread |
Debug it in three steps
Start with the key. Call GET /v1/me with the same key to see which workspace and owner it resolves to, then confirm that is the workspace and member that submitted the job. A teammate's job is invisible to your key even inside one workspace.
Then check how the job was created. A job made by an Agent turn or by a Format run in a thread is readable from that thread, not from an unrelated API key. When a turn reads a job another member created, webhook_delivery.url and webhook_delivery.last_error are null, so you see delivery state without the owner's callback endpoint.
Last, check the filters. A thread_id filter on GET /v1/jobs narrows a list and never widens what a key can read, so adding it will not reveal a job the key could not already see; see the thread_id filter note.
curl https://api.sume.com/v1/me \
-H "Authorization: Bearer $SUME_API_KEY"
curl https://api.sume.com/v1/jobs/job_123/status \
-H "Authorization: Bearer $SUME_API_KEY"What to store
If several services share one workspace, give each its own key and record the job id next to the key that created it. Recovery after a crash then reads with the right key the first time. For the list endpoint and paging, see list and recover jobs.
Sources
Related posts
More in Developers
- GitHub App ghs_ tokens are now ~520 characters: check Sume calls
GitHub's new installation tokens are about 520 characters, not 40. What breaks in a workflow that also calls Sume, and why Sume takes one credential header.
- GitHub social preview as a transparent PNG: which Sume model
GitHub says PNG previews can be transparent, which helps dark mode. On Sume only ChatGPT Image 2.5 lists background transparent, and it has no 2:1 ratio.
- GitLab CI retry reruns the whole script: pin the Sume key
GitLab's retry keyword re-runs the full job script, so a retried job that calls Sume can submit and pay twice. Retry only runner failures and pin the key.
- Go 1.27 drains response bodies: a Sume job poll loop
Go 1.27 drains unread HTTP/1 body bytes on Close. A stdlib loop that polls GET /v1/jobs/:id/status and honors next_poll_after_seconds.
Written by Sume