Agent Completions 404 agent_run_not_found: which id to poll
A 404 agent_run_not_found means the id is not an Agent Completion run of your account, often an Action or Format run id. Poll, list and cancel agrun_ runs.

A 404 agent_run_not_found from Sume's Agent Completions endpoints means the id you polled is not a completion run in your account: it is unknown, it belongs to someone else, or it is an Action or Format run id, which will not resolve here. Poll the id from the 202 receipt of POST /v1/agent/completions, the one that starts with agrun_.
This post covers the three run surfaces, the poll and cancel calls, and a loop that stops at the right time.
Why does a Format or Action run id return 404?
Sume has three ways to run its agent, and they share a receipt shape but not an id space. The docs put it this way: a Format stores how to do something, a scheduled Action stores what to do and when, and an Agent Completion stores nothing because you send the task on every call. Each starts from its own endpoint, and a run created by one is read through that one's endpoints.
So when a worker queue passes ids around, carry the surface with the id, or poll GET /v1/agent-runs/{id} only for ids you got from POST /v1/agent/completions.
| Surface | Start with | Poll a completion id here? |
|---|---|---|
| Format | POST /v1/formats/{handle}/{slug}/runs | No, 404 |
| Scheduled | POST /v1/actions/{handle}/{slug}/runs | No, 404 |
| Agent Completions | POST /v1/agent/completions | Yes, GET /v1/agent-runs/{id} |
How do you poll a completion?
Statuses are queued, processing, completed, failed and canceled, the same as Action runs. The receipt also carries a status_url; the docs say to poll it until next_action stops being poll_status. A completed run fills output, with the closing text in output.text and generated media in output.images, output.videos, output.audio and output.files, as durable media.sume.com URLs. Back off between polls, since a run opens a sandbox and may generate media.
import os
import time
import requests
HEADERS = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
DONE = {"completed", "failed", "canceled"}
def wait_for_run(run_id, every=5.0, limit=1800.0):
start = time.monotonic()
while time.monotonic() - start < limit:
r = requests.get(
f"https://api.sume.com/v1/agent-runs/{run_id}",
headers=HEADERS, timeout=30)
r.raise_for_status()
run = r.json().get("data", r.json())
if run["status"] in DONE:
return run
time.sleep(every)
every = min(every * 1.5, 30.0)
raise TimeoutError(run_id)How do you cancel or list runs?
To stop a run in flight, POST /v1/agent-runs/{id}/cancel; the receipt's cancel_url is the same address. GET /v1/agent-runs lists your completions, newest first. A local timeout in your poller does not cancel anything on Sume, so a loop that gives up should also call cancel if the run is still not terminal, or the run keeps working under its spend cap.
Two more causes of surprise. A key created before Agent Completions shipped has no agent_completions:* scope and gets 403 insufficient_scope, and scopes cannot be added to an existing key, so create a new one. And if you want a push instead of a poll, communication.webhook_url takes a public HTTPS URL notified at a terminal status (Run webhooks).
What does the receipt tell you?
The 202 receipt is the record to keep. The fields below are the ones that matter when you debug a 404 or a stuck run.
| Field | What it is | Use it for |
|---|---|---|
| id | The agrun_ run id | Polling and canceling |
| object | agent.run | Telling it apart from other run types in logs |
| model | sume-agent, the only value | Nothing; omit model on requests |
| thread_id | The thread this run used | Finding the run in the product; every completion gets a fresh one |
| status_url, cancel_url | Ready-made addresses | Poll and cancel without building URLs |
| usage | Spend cap in micros, then recorded spend | Reconciling cost per run |
If a 404 persists for an id you are sure came from the completions endpoint, check which API key made the call. The docs say a run belonging to another account returns the same 404, so a worker using a key from a different account than the submitter will see exactly this.
Sources
Related posts
More in Developers
- Agent Completions 400: generation_spend_cap_usd is required
POST /v1/agent/completions returns 400 invalid_request without generation_spend_cap_usd. It has no default: why, how to size it, and what the receipt echoes.
- Agent Completions input_image: send a photo in messages[]
Send an image to Sume's Agent Completions as an input_image content part inside messages[], merge it with attachments, and get a caption back as typed output.
- AI image API 429s: queue_full vs rate_limited, and how to retry each
Sume returns 429 for two different reasons. rate_limited means back off; queue_full means wait for jobs to finish. A Python retry that treats them differently.
- Is there an asset library API for AI images and videos?
Sume has no folders or tags. Your library is completed jobs plus durable media.sume.com artifacts, which you list, label by Idempotency-Key, and download.
Written by Sume