---
name: rush
description: "Hand work to Rush, which runs agent work unattended: start an agent (Claude Code, Codex or OpenCode) in its own cloud sandbox with POST https://api.phoenix.so/o/{org}/sessions, follow or steer it, and read back the result: a pull request, a report, files or an answer. Use when a task should run in the cloud instead of here (long, parallel or repository work that should come back with proof), or when the user mentions Rush, getrush.ai or api.phoenix.so."
---

# Rush

Rush runs an agent in its own cloud sandbox, with a computer and a browser, and returns what it did with proof: a pull request with checks for code, otherwise a report, files or an answer. You send one HTTP request; the work happens in the cloud, not on this machine.

Base URL: `https://api.phoenix.so`. Every request sends `Authorization: Bearer $RUSH_API_KEY`. Every docs page has a Markdown copy at its path plus `.md`; the index is https://getrush.ai/llms.txt and the OpenAPI document https://getrush.ai/openapi.json.

## Before you start

- An API key (`rk_live_…`). An org admin creates it on the console's Developers page (https://cloud.getrush.ai/console/developers); it is shown once. Read it from `RUSH_API_KEY`; if it is not set, ask the user for it. Never print it, log it or put it in a file you commit.
- The org: the slug or id of the organization the key was made in, used as `{org}` in every path (`RUSH_ORG` in the samples). A key reaches only its own org; another org's paths answer `404`.
- A repository is optional. To work on one, the user installs the Rush GitHub App once from the console (Settings → Connections), then name the repository in `resources`.

## Hand Rush a task

### 1. Set your key

Put the key and your org (the `<your-org>` in the Developers page's example path) in your shell. Every sample on these pages reads them from there.

```bash
export RUSH_API_KEY=rk_live_...
export RUSH_ORG=your-org
```

### 2. Start a session

Send the task with an `agent`: `claude`, `codex` or `opencode`. Rush answers `202` at once with the session, before its sandbox is ready. Keep its `execution_id` (`export SESSION_ID=<execution_id>`); every other call names it. This task needs no repository.

```bash
curl -X POST "https://api.phoenix.so/o/$RUSH_ORG/sessions" \
  -H "Authorization: Bearer $RUSH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agent": "claude",
    "input": "Write a Python function that parses ISO 8601 durations like P1DT2H30M, with tests. Run the tests and report the result."
  }'
```

Reference: https://getrush.ai/docs/api/create-session.md

### 3. Watch it work

Hold the event stream to watch the agent think, run its tools and finish, in its own sandbox. The stream closes after `done`. If your connection drops, reconnect with `Last-Event-ID` and it picks up where it left off.

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

Reference: https://getrush.ai/docs/api/stream-session.md

### 4. Read the answer

The session carries the agent's answer in `result`. When the task touches a repository, it also carries the `branch` and the pull request it opened in `pr_url`.

```bash
curl "https://api.phoenix.so/o/$RUSH_ORG/sessions/$SESSION_ID" \
  -H "Authorization: Bearer $RUSH_API_KEY"
```

If everything worked:

```json
{
  "status": "completed",
  "result": "I wrote `parse_duration` and its tests, and all 4 tests pass: `python3 -m unittest -v test_iso_duration` printed \"Ran 4 tests ... OK\"."
}
```

Reference: https://getrush.ai/docs/api/get-session.md

### 5. Send a follow-up

Continue the same session in the same sandbox, with everything the agent did still on its disk. Send it once the turn has ended; while one is running it is refused with `409 TURN_ACTIVE`.

```bash
curl -X POST "https://api.phoenix.so/o/$RUSH_ORG/sessions/$SESSION_ID/messages" \
  -H "Authorization: Bearer $RUSH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": "Add support for week durations like P2W and rerun the tests."
  }'
```

Reference: https://getrush.ai/docs/api/post-session-message.md

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

Give the key a public `https` endpoint on the console's **Developers** page, and every run it starts posts `run.completed`, `run.failed` or `run.cancelled` there, signed per [Standard Webhooks](https://www.standardwebhooks.com/). No stream to hold, no polling. The request beside this step is the call that page makes with an admin's session; an API key cannot set its own webhook.

An API key cannot make this call (`PATCH /o/{org}/api-keys/{key}` takes a person's console session): ask an org admin to do it on the console's Developers page.

Reference: https://getrush.ai/docs/api/update-api-key-webhook.md

## What a session takes

`POST /o/{org}/sessions` (https://getrush.ai/docs/api/create-session.md):

- `agent`: What runs: a harness (`claude`, `codex` or `opencode`), or a saved agent's id (`GET /o/{org}/agents`), which brings its harness, model, effort, instructions, skills and connections.
- `input` (required): The task, as a string or as content blocks.
- `model`: A model `id` that GET /o/{org}/agents/available lists for this harness.
- `effort`: Reasoning effort; must be one the model's row lists.
- `account_id`: Refused `422 ACCOUNT_UNSUPPORTED` with an API key: a developer run always uses Rush's models.
- `strategy`: Rush's models, billed per token on the caller's plan.
- `request_id`: A UUID you make once for each run you mean to start.
- `skills`: Skills the agent loads for this run, each by public URL, as a string or `{url}`: a GitHub `tree` URL to a directory holding `SKILL.md`, a URL to a `SKILL.md` file (`github.com/…/blob/…`, `raw.githubusercontent.com/…` or any https host), or a `.zip` URL.
- `connections`: What this run connects to, each entry in one of three forms.
- `devices`: Your own linked computers this run may drive, by `name` from `GET /me/devices`.
- `resources`: What Rush puts in front of the agent before it starts, each by URL, with `connection` naming the account that reaches it when more than one could: `https://github.com/<owner>/<repo>` clones the repository at its default branch, `…/tree/<branch>` at that branch, and `…/pull/<n>` on that open pull request's branch; at most one repository per run, reached through a GitHub App installation of the caller (`connection` is an installation id from `GET /o/{org}/github`).

To run a saved agent, send its id as `agent`; it brings its own harness, model, instructions, skills and connections. Saved agents: https://getrush.ai/docs/concepts/saved-agents.md

## Session status

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

A turn takes minutes. Wait on the event stream, poll the session no more than every few seconds, or let a webhook tell your server. `needs_review` means the run finished without the proof it was asked for: report that, never call it done.

## Limits

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`.

## Errors

Every error is JSON with a stable `code` and a `message`; act on the `code`. Every code, its status and the operations that send it: https://getrush.ai/docs/api/errors.md

`ACCOUNT_UNSUPPORTED` (422), `ATTACHMENT_EXPIRED` (410), `ATTACHMENT_IN_USE` (409), `ATTACHMENT_NOT_FOUND` (404), `ATTACHMENT_NOT_UPLOADED` (409), `CANCELLATION_UNCONFIRMED` (503), `CATALOG_REFRESH_REQUIRED` (409), `COMPUTE_LIMIT_REACHED` (402), `CONNECTION_AMBIGUOUS` (422), `CONNECTION_NOT_READY` (422), `CONNECTION_UNAVAILABLE` (422), `CONTENT_TOO_LARGE` (400), `CONTINUATION_UNSUPPORTED` (409), `FIELD_REMOVED` (400), `FORBIDDEN` (403), `HANDLE_TAKEN` (409), `IDEMPOTENCY_CONFLICT` (409), `IF_MATCH_REQUIRED` (428), `IMMUTABLE_FIELD` (422), `INPUT_FETCH_FAILED` (422), `INSTALLATION_NOT_LINKED` (403), `INVALID_BODY` (400, 422), `INVALID_DESCRIPTION` (422), `INVALID_EFFORT` (422), `INVALID_FILTER` (400), `INVALID_HARNESS` (422), `INVALID_INSTRUCTIONS` (422), `INVALID_MODEL` (422), `INVALID_NAME` (422), `MCP_SERVER_URL_INVALID` (422), `MODEL_UNSUPPORTED` (422), `NOT_FOUND` (404), `PAYMENT_METHOD_REQUIRED` (402), `PROJECT_PAUSED` (409), `RATE_LIMITED` (429), `REPO_NOT_IN_INSTALLATION` (403), `REQUEST_TOO_LARGE` (413), `RESOURCE_NOT_ACCESSIBLE` (422), `RESOURCE_UNSUPPORTED` (422), `RUN_STATE_CONFLICT` (409), `SECRET_CHANGED` (409), `SECRET_DESCRIPTION_INVALID` (422), `SECRET_FIELD_IMMUTABLE` (422), `SECRET_KIND_INVALID` (422), `SECRET_NAME_INVALID` (422), `SECRET_NAME_TAKEN` (409), `SECRET_NOT_FOUND` (404), `SECRET_ONEPASSWORD_NOT_CONNECTED` (422), `SECRET_ONEPASSWORD_NOT_FOUND` (422), `SECRET_ONEPASSWORD_RATE_LIMITED` (422), `SECRET_ONEPASSWORD_TOKEN_REJECTED` (422), `SECRET_ONEPASSWORD_UNAVAILABLE` (422), `SECRET_PROJECT_NOT_IN_ORG` (422), `SECRET_PROJECT_REQUIRED` (422), `SECRET_SOURCE_INVALID` (422), `SECRET_TARGET_INVALID` (422), `SECRET_VALUE_INVALID` (422), `SESSION_NOT_CAPTURED` (404), `SKILL_FETCH_FAILED` (422), `SKILL_INVALID` (422), `SPEND_CAP_REACHED` (402), `STALE_ETAG` (412), `TASK_TERMINAL` (409), `TEMPLATE_FIELDS` (422), `TEMPLATE_IN_USE` (409), `TOKEN_LIMIT_REACHED` (402), `TOO_MANY_FILES` (400), `TURN_ACTIVE` (409), `UNKNOWN_FIELD` (400), `UNSUPPORTED_AGENT` (422), `UNSUPPORTED_PROFILE` (422), `VALIDATION_ERROR` (400), `WEEKLY_COMPUTE_LIMIT_REACHED` (402)

## From an MCP client instead

The same API is an MCP server at `https://api.phoenix.so/mcp`. If your client can add it, the tools below do these calls for you.

Create an API key in the console under Developers, then add the server with it:

```bash
claude mcp add --transport http rush https://api.phoenix.so/mcp --header "Authorization: Bearer $RUSH_API_KEY"
codex mcp add rush --url https://api.phoenix.so/mcp --bearer-token-env-var RUSH_API_KEY
```

In Cursor, add this under `mcpServers`:

```json
{"rush": {"url": "https://api.phoenix.so/mcp", "headers": {"Authorization": "Bearer rk_live_…"}}}
```

A key or a sign-in connects. A person's console session token is refused with `403 FORBIDDEN`.

| Sessions | `create_session`, `get_session`, `wait_for_sessions`, `list_sessions`, `send_session_message`, `cancel_session`, `list_session_events`, `get_session_changes`, `get_session_artifact` |
| --- | --- |
| Saved agents | `list_agents`, `get_agent`, `create_agent`, `update_agent` |
| Projects | `list_projects`, `get_project` |
| What a run can use | `list_models`, `list_connections`, `connect_account`, `list_repositories` |

Each tool makes the API call it names with your key or sign-in, so it reaches exactly what that reaches. A
refusal comes back as the API's `code` and message plus what to do next.

When a run is refused because an account is not connected, `connect_account` starts its sign-in and returns
an `authorize_url` for the person to open in their own browser. It takes no token, so no secret passes
through the model.

More: https://getrush.ai/docs/concepts/mcp-server.md

## Read more

- [API quickstart](https://getrush.ai/docs/quickstart.md)
- [Runs and sessions](https://getrush.ai/docs/concepts/runs-and-sessions.md): A session is one agent run. It moves through a fixed set of statuses, takes follow-ups between turns and keeps its sandbox while it is parked.
- [Your first run from code](https://getrush.ai/docs/learn/first-api-run.md): Create an API key, start a session with one request, follow it live with curl, read its answer and send a follow-up into the same sandbox.
- [Act on the result with a webhook](https://getrush.ai/docs/learn/act-on-the-result.md): Point your key at an endpoint, verify each signed POST, and handle every finished turn exactly once, even when a delivery is retried.
- [Projects and secrets](https://getrush.ai/docs/concepts/projects.md): A Project ties a repository, its secrets and its shared connections together inside your org. Sessions in it get all three without naming them.
- [Give a run files, skills and connections](https://getrush.ai/docs/learn/files-skills-connections.md): Start a run with files in its sandbox, skills loaded from a URL, the tools it may call and the repository or issue it works from.
- [Results and proof](https://getrush.ai/docs/concepts/results-and-proof.md): Every run ends with a record you can check: the answer, the branch and pull request, the files it saved, its transcript and what it used.
- [Run a saved agent from code](https://getrush.ai/docs/learn/saved-agents-from-code.md): Save a harness with its model, instructions, skills and connections once, then start each run with its id and a task.
- [Watch and steer live](https://getrush.ai/docs/concepts/watch-and-steer.md): Follow a run as it works, send it the next instruction, stop it, or take over its desktop. Every surface reads the same event stream.
- [Isolation, plainly](https://getrush.ai/docs/concepts/isolation.md): Each run gets its own microVM, each org sees only its own resources, and secrets reach a run only in the form you chose. What that means in practice.
- [Models and your access](https://getrush.ai/docs/concepts/models.md): API, MCP and template-agent runs use Rush's models, billed per token; console runs use your own account. Pick a model and effort from the list your org can run.
- [Automations](https://getrush.ai/docs/concepts/automations.md): An automation is a saved prompt in a Project with triggers that say when it runs: a GitHub event, a schedule, a webhook call or a Linear issue change.
- [Saved agents](https://getrush.ai/docs/concepts/saved-agents.md): Save a harness with its model, effort, instructions, skills and connections once, then start every run of it by sending its id as agent.
- [Connections](https://getrush.ai/docs/concepts/connections.md): Sign in to a tool or MCP server once, then name it on any run. Skills and resources come in by URL the same way.
- [Webhooks](https://getrush.ai/docs/concepts/webhooks.md): Give an API key an endpoint and every run it starts posts a signed event there when a turn ends, so you never hold a stream or poll.
- [Usage and billing](https://getrush.ai/docs/concepts/usage-and-billing.md): Rush meters compute while a run is awake and tokens on Rush's models. Every session records its tokens and cost; limits answer with a typed code.
- [Rush MCP server](https://getrush.ai/docs/concepts/mcp-server.md): Hand Rush a task from claude.ai, ChatGPT, Claude Code, Cursor or Codex: connect api.phoenix.so/mcp by signing in or with an API key, then start runs as tool calls.
- [Community agents](https://getrush.ai/docs/concepts/community-agents.md): Companies on Rush share saved agents they run. Add one and it becomes your own agent, running on your own apps, while its instructions stay with its maker.
- [API reference](https://getrush.ai/docs/api.md): every public operation
