Skip to content

Submit your first run

This page assumes an agent already exists in a workspace — see Agents if it does not — and that you have a service key for that workspace.

Throughout, https://your-deployment.example.com stands in for your deployment’s own host. The path carries no version segment. Breaking changes are not made, only additive ones: a field is retired with a Deprecation header and a sunset date at least 180 days out, never by disappearing.

Terminal window
curl https://your-deployment.example.com/system/health

/system/health is liveness and touches no database, so it answers even when the platform is having a bad day. /system/ready is the one that is allowed to fail — it checks that the database schema is at the head this build expects.

Terminal window
curl -X POST https://your-deployment.example.com/runs \
-H "X-Api-Key: $COBRE_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-4417-triage" \
-d '{
"agent_slug": "triage",
"input": {"text": "the package arrived open"}
}'

Name the agent with either agent_slug or agent_id. input is an open object; what belongs in it is decided by the agent’s own input schema, and an input that does not fit is a 422 naming the field.

You get 202 Accepted and a run in queued:

{
"id": "0190a2f4-…",
"status": "queued",
"agent_id": "…",
"agent_revision_id": "…",
"attempt_count": 0,
"queued_at": "2026-08-15T12:00:00Z",
"output": null
}

The response is the full RunView — the fields above are the ones you need first. Note agent_revision_id: the run is pinned to the exact revision that produced it, which is what makes a six-month-old run still explainable.

Three ways, and they suit different callers.

Terminal window
curl https://your-deployment.example.com/runs/0190a2f4-… \
-H "X-Api-Key: $COBRE_KEY"

Read status until it is terminal — succeeded, failed, timed_out or cancelled — and then read output. Simple, works everywhere, and costs you a request per poll.

Add response_mode: "sync" and a wait_seconds to the submission, and the call holds until the run settles:

Terminal window
curl -X POST https://your-deployment.example.com/runs \
-H "X-Api-Key: $COBRE_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_slug": "triage",
"input": {"text": "the package arrived open"},
"response_mode": "sync",
"wait_seconds": 30
}'

You get 200 instead of 202, with the settled run.

Two things this mode does that people get wrong:

  • A synchronous wait also ends when the run suspends. A caller waiting on a human approval is told so, rather than left to time out.
  • A wait that expires is a 504, and the run keeps running. The response carries the run id. Poll it or stream it — do not treat the 504 as a failed run.
Terminal window
curl -N https://your-deployment.example.com/runs/0190a2f4-…/stream?after_seq=0 \
-H "X-Api-Key: $COBRE_KEY"

Server-sent events, one frame per thing that happened, run.end last. Accumulate output text from text.delta and nothing else. There is a WebSocket on the same path when you need one. The guarantees, the resumption rules and the frame catalogue are on Streaming a run.

Four failures are worth handling by name before you ship:

What it meansWhat to do
402 budget_exceededThe workspace hit its ceiling. No run was created.Stop. Retrying cannot succeed until a limit is raised.
429 rate_limitedToo many submissions.Back off. A Retry-After header is sent when the platform can say how long; it is advisory and may be absent.
409 idempotency_in_flightYour first attempt with this key is still running.Wait a second and retry the same key.
504 on a sync waitThe wait expired. The run did not.Poll or stream the run id you were given.

Every failure carries the same envelope and a code from a closed catalogue. Branch on the code, never on the message — see Errors.

Which error you see is decided by a fixed gating order, and knowing it saves an afternoon:

  1. schema → 422
  2. agent visible → 404
  3. revision → 422
  4. persona → 422
  5. input schema → 422
  6. idempotency → 200 / 409 / 422
  7. budget → 402
  8. limits → 429
  9. insert

The budget check happens before any row is written, which is why a 402 leaves nothing behind to look at.

  • Authentication — the other credential kinds, and what a role floor does.
  • Conventions — pagination, partial updates, optimistic concurrency.
  • SDKs — if you would rather not write this by hand.