# Start a session (console, by Project)

`POST /o/{org}/p/{project}/sessions`

The console's form of `POST /o/{org}/sessions`, with the Project in the path
(`_` for none). A signed-in caller reads the console's own session shape.

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `org` | path | string | yes | The org's slug or id. A caller with no role in the org gets `404`. |
| `project` | path | string | yes | A Project's handle (name) or id, resolved inside `{org}` — OR the reserved sentinel `_` meaning "no Project" (a direct-repo / repo-less dispatch on `POST`; "no Project constraint, resolve by session id alone" everywhere else). A real handle that doesn't match the session's actual Project is `404`.  |
| `Idempotency-Key` | header | string | no | A retried create with the same key and body returns the run the key first started, until that run fails or is cancelled. The same key with another body is `409 IDEMPOTENCY_CONFLICT`. Keys are per caller and org.  |

## Request body

- `harness` (string, optional): `claude`, `codex` or `opencode`.
- `input` (string | array of object | object, required): The task, as a string or as content blocks. Text blocks are joined, with a blank line between them, into the prompt (at most 256 KiB, at least one text block). Every file block is stored before the run starts and downloaded into the sandbox at `/workspace/.rush/attachments/`, where the prompt names it.
- `model` (string, optional): A model `id` that GET /o/{org}/agents/available lists for this harness. Omitted: the harness default.
- `effort` (string, optional, one of `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`, `auto`): Reasoning effort; must be one the model's row lists.
- `agent_id` (string, optional): A saved agent (`GET /o/{org}/agents`) to run: its harness, model, effort, instructions, skills and connections.
- `account_id` (string, optional): Run on this one of the caller's own accounts (a Claude or ChatGPT subscription, or an Anthropic or OpenAI API key). Omitted: their subscriptions first, then their API key.
- `strategy` (string, optional, one of `platform`): Run on Rush's models, metered on the caller's plan, instead of their own accounts.
- `skills` (array of string | object, optional): 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. Fetched when the run is created; a GitHub source is pinned to the commit its branch or tag points at, and the pin is kept with the run. All of a run's skills pack to at most 96 KiB compressed. An unreachable URL is `422 SKILL_FETCH_FAILED`; no `SKILL.md`, a bad name or too large is `422 SKILL_INVALID`.
- `connections` (array of string | object, optional): What this run connects to, each entry in one of three forms: - **An id** of one of the caller's own connections (`GET /me/connections`): an MCP server (connected with a token, by OAuth, or with no auth), a Google, Microsoft or GitLab account. Secrets are never named: a session gets every secret of its Project (`/o/{org}/secrets`). - **A name** of one of them, the `name` `GET /me/connections` lists: the name the caller gave an MCP server (`"deepwiki"`, `"EXA_API_KEY"`), or the provider of an account or a built-in connector, which `GET /me/connections` lists as `{type: "app", name: "linear"}` (`"linear"`, `"google"`). Only the caller's own rows match, and only user-level ones or ones in this run's Project. A name that matches two of them is `422 CONNECTION_AMBIGUOUS`, whose message lists their ids; send one id instead. - **An inline MCP server** `{url, name?, auth?}`, used by this run and its follow-ups only and never added to `/me/connections`. `url` is a streamable HTTP endpoint on https whose host resolves to public addresses only (else `422 MCP_SERVER_URL_INVALID`). `auth` is the shape `POST /me/connections` takes: `{mode: "bearer", token}` sends the token as `Authorization: Bearer`; `{mode: "none"}` or no `auth` sends none. A `token` beside `url` is `400 FIELD_REMOVED`. The token is stored encrypted on the run and never returned. `name` defaults to a slug of the host (`mcp-deepwiki-com`), and may not be a built-in connection's or share a name with another entry (`422 CONNECTION_AMBIGUOUS` when it matches a named server). Ids and names fit Anthropic's stored-credential model (a vault id per run); the inline form fits OpenAI's inline `authorization` and Cursor's `mcpServers` headers. An id or name that is unknown, still connecting, or waiting on a reconnect is `422 CONNECTION_NOT_READY`. Follow-ups keep all three.
- `resources` (array of object, optional): 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`). On a Project run it may only name the Project's repository. `https://linear.app/<workspace>/issue/<ID>` puts the issue in the prompt, read through the caller's Linear connection. Any other URL is `422 RESOURCE_UNSUPPORTED`; a repository no installation covers, or an issue with no Linear connection, is `422 RESOURCE_NOT_ACCESSIBLE`.
  - `url` (string, required)
  - `connection` (string, optional)

## A run with no repository

```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 '{
    "harness": "claude",
    "input": "Summarize the open issues labelled bug in three bullet points."
  }'
```

```typescript
const org = process.env.RUSH_ORG;

const res = await fetch(`https://api.prix.dev/o/${org}/p/_/sessions`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.RUSH_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    harness: "claude",
    input: "Summarize the open issues labelled bug in three bullet points.",
  }),
});

console.log(res.status, await res.text());
```

```python
import os

import requests

org = os.environ["RUSH_ORG"]

res = requests.post(
    f"https://api.prix.dev/o/{org}/p/_/sessions",
    headers={"Authorization": f"Bearer {os.environ['RUSH_API_KEY']}"},
    json={
        "harness": "claude",
        "input": "Summarize the open issues labelled bug in three bullet points.",
    },
)

print(res.status_code, res.text)
```

## A run with an image, a PDF and an uploaded file

```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 '{
    "harness": "claude",
    "input": [
      {
        "type": "text",
        "text": "Compare the logo with the brand guide and the attached spreadsheet."
      },
      {
        "type": "image",
        "source": {
          "type": "url",
          "url": "https://example.com/logo.png"
        }
      },
      {
        "type": "document",
        "name": "brand-guide.pdf",
        "source": {
          "type": "base64",
          "media_type": "application/pdf",
          "data": "JVBERi0xLjcK…"
        }
      },
      {
        "type": "file",
        "source": {
          "type": "file",
          "file_id": "6f1c0d2e-8a8e-4c55-9d2b-0f6f3f0a1b2c"
        }
      }
    ]
  }'
```

```typescript
const org = process.env.RUSH_ORG;

const res = await fetch(`https://api.prix.dev/o/${org}/p/_/sessions`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.RUSH_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    harness: "claude",
    input: [
      {
        type: "text",
        text: "Compare the logo with the brand guide and the attached spreadsheet.",
      },
      {
        type: "image",
        source: {
          type: "url",
          url: "https://example.com/logo.png",
        },
      },
      {
        type: "document",
        name: "brand-guide.pdf",
        source: {
          type: "base64",
          media_type: "application/pdf",
          data: "JVBERi0xLjcK…",
        },
      },
      {
        type: "file",
        source: {
          type: "file",
          file_id: "6f1c0d2e-8a8e-4c55-9d2b-0f6f3f0a1b2c",
        },
      },
    ],
  }),
});

console.log(res.status, await res.text());
```

```python
import os

import requests

org = os.environ["RUSH_ORG"]

res = requests.post(
    f"https://api.prix.dev/o/{org}/p/_/sessions",
    headers={"Authorization": f"Bearer {os.environ['RUSH_API_KEY']}"},
    json={
        "harness": "claude",
        "input": [
            {
                "type": "text",
                "text": "Compare the logo with the brand guide and the attached spreadsheet.",
            },
            {
                "type": "image",
                "source": {
                    "type": "url",
                    "url": "https://example.com/logo.png",
                },
            },
            {
                "type": "document",
                "name": "brand-guide.pdf",
                "source": {
                    "type": "base64",
                    "media_type": "application/pdf",
                    "data": "JVBERi0xLjcK…",
                },
            },
            {
                "type": "file",
                "source": {
                    "type": "file",
                    "file_id": "6f1c0d2e-8a8e-4c55-9d2b-0f6f3f0a1b2c",
                },
            },
        ],
    },
)

print(res.status_code, res.text)
```

## A run with a skill, two connections and a repository branch

```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 '{
    "harness": "claude",
    "input": "Add a dark mode toggle to the settings page.",
    "skills": [
      "https://github.com/anthropics/skills/tree/main/skills/frontend-design"
    ],
    "connections": [
      "6f1c2a9e-3b7d-4e0a-9c55-2d8e1f4a7b30",
      {
        "url": "https://mcp.exa.ai/mcp",
        "auth": {
          "mode": "bearer",
          "token": "exa-key"
        }
      }
    ],
    "resources": [
      {
        "url": "https://github.com/acme/web/tree/main"
      },
      {
        "url": "https://linear.app/acme/issue/ENG-42"
      }
    ]
  }'
```

```typescript
const org = process.env.RUSH_ORG;

const res = await fetch(`https://api.prix.dev/o/${org}/p/_/sessions`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.RUSH_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    harness: "claude",
    input: "Add a dark mode toggle to the settings page.",
    skills: [
      "https://github.com/anthropics/skills/tree/main/skills/frontend-design",
    ],
    connections: [
      "6f1c2a9e-3b7d-4e0a-9c55-2d8e1f4a7b30",
      {
        url: "https://mcp.exa.ai/mcp",
        auth: {
          mode: "bearer",
          token: "exa-key",
        },
      },
    ],
    resources: [
      {
        url: "https://github.com/acme/web/tree/main",
      },
      {
        url: "https://linear.app/acme/issue/ENG-42",
      },
    ],
  }),
});

console.log(res.status, await res.text());
```

```python
import os

import requests

org = os.environ["RUSH_ORG"]

res = requests.post(
    f"https://api.prix.dev/o/{org}/p/_/sessions",
    headers={"Authorization": f"Bearer {os.environ['RUSH_API_KEY']}"},
    json={
        "harness": "claude",
        "input": "Add a dark mode toggle to the settings page.",
        "skills": [
            "https://github.com/anthropics/skills/tree/main/skills/frontend-design",
        ],
        "connections": [
            "6f1c2a9e-3b7d-4e0a-9c55-2d8e1f4a7b30",
            {
                "url": "https://mcp.exa.ai/mcp",
                "auth": {
                    "mode": "bearer",
                    "token": "exa-key",
                },
            },
        ],
        "resources": [
            {
                "url": "https://github.com/acme/web/tree/main",
            },
            {
                "url": "https://linear.app/acme/issue/ENG-42",
            },
        ],
    },
)

print(res.status_code, res.text)
```

## Responses

### 202

The console's answer.

### 401

No bearer, an unknown, revoked or expired one, or an API key on a route keys cannot call.

### 404

No such resource for the caller, including one that exists in an org the caller cannot see.

## Example response (202)

```http
HTTP 202 The console's answer.
```
