# Rush Cloud API

Start an agent in its own cloud computer from your server, follow it live, steer it, and read what it did. Claude Code, Codex and OpenCode run behind one HTTP API at `api.prix.dev`.

Base URL: `https://api.prix.dev`

## Quickstart

### 1. Get a key

An org admin creates a key in the console under **Settings → API keys**, or with the request beside this step from a signed-in session (`rush http` sends one for you). The `rk_live_…` secret is shown once; store it on your server as `RUSH_API_KEY`.

A key acts as the admin who created it, in its own org, on the session routes. Its runs use Rush's models on that admin's plan, so no Anthropic or OpenAI key is needed. Set `expires_at` up to a year out, or leave it out for a key that never expires.

Reference: [Create an API key](https://getrush.ai/docs/api/create-api-key.md)

```bash
curl -X POST "https://api.prix.dev/o/$RUSH_ORG/api-keys" \
  -H "Authorization: Bearer $RUSH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "ci-runner",
    "expires_at": "2027-01-01T00:00:00Z"
  }'
```

### 2. Start a session

A session is one agent run. `POST` it with an `agent` and a `prompt`; the response is the session, already `queued` or `running`.

`p/_` runs without a repository. Use a Project's handle instead to run in its repository with its connectors. `persistence` is `resumable` by default: the sandbox parks with its disk and memory when a turn ends, costs nothing while parked, and a follow-up wakes it where it left off. `ephemeral` tears it down when the turn ends.

Reference: [Start a session](https://getrush.ai/docs/api/create-session.md)

```bash
curl -X POST "https://api.prix.dev/o/$RUSH_ORG/p/_/sessions" \
  -H "Authorization: Bearer $RUSH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agent": "claude",
    "prompt": "Summarize the open issues labelled bug in three bullet points.",
    "persistence": "ephemeral"
  }'
```

### 3. Stream its events

Hold the event stream to watch the agent work. Each frame is an `event:` line and a JSON `data:` line. The stream closes after `done`, whose data carries the turn's status and answer. Reconnect with `Last-Event-ID` to resume where you left off.

Reference: [Follow a session live](https://getrush.ai/docs/api/stream-session.md)

```bash
curl -N "https://api.prix.dev/o/$RUSH_ORG/p/_/sessions/$SESSION_ID/events" \
  -H "Authorization: Bearer $RUSH_API_KEY" \
  -H "Accept: text/event-stream"
```

### 4. Send a follow-up

A follow-up continues the same session. It wakes a parked sandbox, and while a turn is still running it queues and is delivered when the turn ends (`202` with its place in the queue).

Reference: [Send a follow-up](https://getrush.ai/docs/api/post-session-message.md)

```bash
curl -X POST "https://api.prix.dev/o/$RUSH_ORG/p/_/sessions/$SESSION_ID/messages" \
  -H "Authorization: Bearer $RUSH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Also add a regression test for the timezone case."
  }'
```

### 5. Read the result

The result is the agent's last answer beside the run's status line, its branch and pull request when it opened one. Send `output_schema` when you start the session and the answer comes back as a typed object in `result.structured`.

Reference: [Get the session's answer](https://getrush.ai/docs/api/get-session-result.md)

```bash
curl "https://api.prix.dev/o/$RUSH_ORG/p/_/sessions/$SESSION_ID/result" \
  -H "Authorization: Bearer $RUSH_API_KEY"
```

### 6. Get a webhook when a turn ends

Instead of holding the stream, give the key a public `https` endpoint. The response carries the `whsec_…` signing secret once. Every run the key starts then posts `run.completed`, `run.failed` or `run.cancelled` to it within about 30 seconds of a turn ending, signed per [Standard Webhooks](https://www.standardwebhooks.com/).

Reference: [Set, change or remove the key's webhook](https://getrush.ai/docs/api/update-api-key-webhook.md)

```bash
curl -X PATCH "https://api.prix.dev/o/$RUSH_ORG/api-keys/$KEY_ID" \
  -H "Authorization: Bearer $RUSH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "webhook_url": "https://hooks.acme.dev/rush"
  }'
```

## Session lifecycle

- Starting: `queued` (Accepted; waiting for a run slot.), `allocating` (Its sandbox is being prepared.)
- Working: `running` (The agent is working.)
- Turn ended: `completed` (The turn finished with an answer.), `paused` (A resumable session parked between turns; costs nothing.), `input_required` (The agent asked a question; send a follow-up.), `needs_review` (Finished without the proof it was asked for.)
- Stopped: `failed` (The run stopped on an error.), `cancelled` (You cancelled it.), `expired` (A parked sandbox passed 7 idle days and was removed.)

## Authentication

Send `Authorization: Bearer <token>` on every request.

- `bearerAuth`: An org API key (`rk_live_…`, from POST /o/{org}/api-keys), which acts as the admin who created it, in its own org, on the session routes only; or a signed-in Phoenix ID session, as the console and the `rush` CLI send.

## Errors

Every non-2xx body. Two envelopes are live: most routes send `error`
(a sentence) with an optional `code` or `error_code`; the org-wide
session search sends `code` and `message`. Some refusals add fields
(`candidates`, `fields`, plan usage). Branch on `code` / `error_code`.

| Code | Status | Sent by |
| --- | --- | --- |
| `API_KEY_FIELD_UNSUPPORTED` | 422 | `createSession` |
| `CATALOG_REFRESH_REQUIRED` | 409 | `createSession` |
| `COMPUTE_LIMIT_REACHED` | 402 | `createSession` |
| `CONCURRENCY_LIMIT_REACHED` | 409 | `updateSessionStatus` |
| `CONTENT_TOO_LARGE` | 400 | `postSessionMessage` |
| `CONTINUATION_UNSUPPORTED` | 409 | `postSessionMessage` |
| `FIELD_UNSUPPORTED_FOR_HARNESS` | 422 | `createSession` |
| `INSTALLATION_NOT_LINKED` | 403 | `createSession` |
| `MODEL_UNSUPPORTED` | 422 | `createSession` |
| `NO_ACTIVE_TURN` | 409 | `updateSessionStatus` |
| `OUTPUT_SCHEMA_INVALID` | 400 | `createSession` |
| `PAYMENT_METHOD_REQUIRED` | 402 | `createSession` |
| `PERSISTENCE_MODE_CONFLICT` | 409 | `postSessionMessage` |
| `PLAN_REQUIRED` | 402 | `createSession` |
| `QUEUE_FULL` | 429 | `postSessionMessage` |
| `RATE_LIMITED` | 429 | `createSession` |
| `REPO_NOT_IN_INSTALLATION` | 403 | `createSession` |
| `SPEND_CAP_REACHED` | 402 | `createSession` |
| `STOP_TURN_UNCONFIRMED` | 422 | `updateSessionStatus` |
| `TASK_TERMINAL` | 409 | `postSessionMessage` |
| `TOKEN_LIMIT_REACHED` | 402 | `createSession` |
| `UNSUPPORTED_AGENT` | 422 | `createSession` |
| `VALIDATION_ERROR` | 400 | `createApiKey`, `updateApiKeyWebhook` |
| `WEEKLY_COMPUTE_LIMIT_REACHED` | 402 | `createSession` |

## Limits and concurrency

A key runs at most `max_concurrent` sessions at once (4 unless you set it when creating the key, up to 100). Starting one more answers `429`; wait for a run to end or cancel one.

A running session queues at most 20 follow-ups; one more answers `429` with `QUEUE_FULL`.

Model usage past what the plan includes continues at the metered rate up to the spend limit an admin sets in Billing; without one it stops with `402`.

## Pagination

List operations take `limit` (integer, default 50, at most 500) and `cursor`: pass the previous response's `next_cursor` to get the next page.

## API reference

Base URL: `https://api.prix.dev`. OpenAPI document: https://getrush.ai/openapi.json

### Sessions

Start, list, read and steer sessions. A session is one agent run in its own sandbox.

- [Search the org's sessions, or resolve one by selector](https://getrush.ai/docs/api/list-or-resolve-sessions.md): `GET /o/{org}/sessions`
- [List sessions in one Project](https://getrush.ai/docs/api/list-sessions.md): `GET /o/{org}/p/{project}/sessions`
- [Start a session](https://getrush.ai/docs/api/create-session.md): `POST /o/{org}/p/{project}/sessions`
- [Get one session](https://getrush.ai/docs/api/get-session.md): `GET /o/{org}/p/{project}/sessions/{session}`
- [Cancel, pause, resume, or stop the current turn](https://getrush.ai/docs/api/update-session-status.md): `PATCH /o/{org}/p/{project}/sessions/{session}`

### Events

Follow a session live over server-sent events, or read its log.

- [Follow a session live](https://getrush.ai/docs/api/stream-session.md): `GET /o/{org}/p/{project}/sessions/{session}/events`
- [Read the session's runtime log](https://getrush.ai/docs/api/get-session-logs.md): `GET /o/{org}/p/{project}/sessions/{session}/logs`

### Messages

Read a session's transcript and tool calls, and send it follow-ups.

- [Read a session's transcript](https://getrush.ai/docs/api/get-session-messages.md): `GET /o/{org}/p/{project}/sessions/{session}/messages`
- [Send a follow-up](https://getrush.ai/docs/api/post-session-message.md): `POST /o/{org}/p/{project}/sessions/{session}/messages`
- [List a session's tool calls](https://getrush.ai/docs/api/get-session-tool-calls.md): `GET /o/{org}/p/{project}/sessions/{session}/tool-calls`

### Results & artifacts

The answer, changed files, captured transcript and files a session produced.

- [Download the captured transcript, or its metadata](https://getrush.ai/docs/api/get-session-trajectory.md): `GET /o/{org}/p/{project}/sessions/{session}/trajectory`
- [List the files the session's pull request changed](https://getrush.ai/docs/api/get-session-changes.md): `GET /o/{org}/p/{project}/sessions/{session}/changes`
- [Get the session's answer](https://getrush.ai/docs/api/get-session-result.md): `GET /o/{org}/p/{project}/sessions/{session}/result`
- [List the files a session produced](https://getrush.ai/docs/api/list-session-artifacts.md): `GET /o/{org}/p/{project}/sessions/{session}/artifacts`
- [Download one artifact](https://getrush.ai/docs/api/get-session-artifact.md): `GET /o/{org}/p/{project}/sessions/{session}/artifacts/{name}`

### API keys

Org API keys for server-to-server calls, and the webhook each key delivers to.

- [List the org's API keys](https://getrush.ai/docs/api/list-api-keys.md): `GET /o/{org}/api-keys`
- [Create an API key](https://getrush.ai/docs/api/create-api-key.md): `POST /o/{org}/api-keys`
- [Set, change or remove the key's webhook](https://getrush.ai/docs/api/update-api-key-webhook.md): `PATCH /o/{org}/api-keys/{key}`
- [Revoke an API key](https://getrush.ai/docs/api/revoke-api-key.md): `DELETE /o/{org}/api-keys/{key}`
- [Rotate an API key's secret](https://getrush.ai/docs/api/rotate-api-key.md): `POST /o/{org}/api-keys/{key}/rotate`

### Agents & models

The harnesses, models, MCP servers and plugin marketplaces an org can run.

- [List the harnesses, models and connectors the org can run](https://getrush.ai/docs/api/get-agents-available.md): `GET /o/{org}/agents/available`

### Webhooks

Requests Rush Cloud sends to your server.

- [A run started with an API key finished a turn](https://getrush.ai/docs/api/run-finished.md): `webhook`
