# HTTP API

In the default multi-agent layout each agent serves its routes at
`/<slug>/v1/*`, and `--mode single` serves them at `/v1/*`.

Routes use the agent's HTTP auth chain, which defaults to
`localDevStrict()`. `--bearer-token` and `--allow-anonymous` replace it
with bearer or anonymous access. Built-in JSON
routes return errors as `{ ok: false, error: "<code>", message? }`, and
MCP uses JSON-RPC.

## Host routes

These routes need no auth.

| Route                                                           | Contract                                              |
| --------------------------------------------------------------- | ----------------------------------------------------- |
| `GET /`                                                         | HTML index of mounted agents                          |
| `GET /v1/agents`                                                | JSON index of mounted agents, multi-agent layout only |
| `GET /<slug>/playground`, `GET /<slug>/playground/assets/:file` | The agent's playground page and assets                |
| `GET /docs`, `GET /docs/*`                                      | Documentation site                                    |

`--no-playground` removes the index and playground routes, and
`--no-docs` removes the docs.

## Start a session

`POST /v1/session` opens a durable conversation.

```bash
curl -X POST http://127.0.0.1:3000/<slug>/v1/session \
  -H 'content-type: application/json' \
  -d '{"message":"What can you do?"}'
# {"ok":true,"sessionId":"ses_…","continuationToken":"http:…",
#  "playgroundUrl":"…?sessionId=ses_…","traceUrl":"…/v1/session/ses_…/events"}
```

| Body field       | Contract                                                                                                                |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `message`        | Required user message                                                                                                   |
| `title`          | Display title                                                                                                           |
| `dryRun`         | Run read tools and stub write tools                                                                                     |
| `asOf`           | ISO-8601 instant with a timezone. Sets `ctx.now()` and rejects omitted, relative, or later declared tool time arguments |
| `workspaceFiles` | Relative files added to the session workspace                                                                           |
| `purpose`        | `"eval"` marks regression traffic                                                                                       |

## Send a follow-up

`POST /v1/session/:sessionId` continues an existing conversation.

```bash
curl -X POST http://127.0.0.1:3000/<slug>/v1/session/ses_… \
  -H 'content-type: application/json' \
  -d '{"continuationToken":"http:…","message":"Make it shorter."}'
```

The route accepts any chat session, including one a custom channel created. Each accepted follow-up returns a new continuation token. A message to a busy session interrupts the active turn. A stale token or a task session returns `409`.

## Stream or replay session events

`GET /v1/session/:sessionId/stream` is the live NDJSON feed.

```bash
curl -N 'http://127.0.0.1:3000/<slug>/v1/session/ses_…/stream?startIndex=0'
```

It replays from `startIndex`, which defaults to `0`, then follows new
events. To reconnect without duplicates, pass the last index you
received plus one.

`GET /v1/session/:sessionId/events` returns a one-shot NDJSON dump, or
`{ sessionId, events, playgroundUrl }` with `?format=json`.
[Stream events](https://cursor.com/docs/agent-sdk/reference/sessions.md#stream-events) lists the event types.

## Manage sessions

| Route                              | Contract                                                  |
| ---------------------------------- | --------------------------------------------------------- |
| `POST /v1/session/:sessionId/stop` | Interrupt the active turn without sending another message |
| `GET /v1/sessions`                 | List sessions the caller owns                             |
| `GET /v1/session/:sessionId/cost`  | Per-turn token usage and estimated cost                   |

Under `serve --dev` on loopback, the list includes every principal's
sessions.

## Call a tool without a model turn

| Route                      | Contract                                                         |
| -------------------------- | ---------------------------------------------------------------- |
| `POST /v1/tools/:toolName` | Run a server tool on `{ input, sessionId?, continuationToken? }` |

[Tools](https://cursor.com/docs/agent-sdk/reference/tools.md#call-a-tool-without-a-model-turn) covers session
binding, busy sessions, and error codes.

## Discovery routes

| Route                  | Contract                                                                                                             |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `GET /v1/info`         | Everything discovery found, such as the model, tools, channels, and diagnostics                                      |
| `GET /v1/tools`        | Server and advertised MCP tools as `{ name, title?, source? }`, optionally for one `session` or `continuationToken`  |
| `GET /v1/tools/:name`  | One tool's schemas, effect rules, execution mode, and source. An unknown name returns `404` with the available names |
| `GET /v1/logs?after=N` | Recent server logs and the next polling cursor                                                                       |

`connectionErrors` names any connection that couldn't list its tools.

## List and download artifacts

`GET /v1/artifacts` returns the caller's `{ artifacts }`, newest-updated
first, filtered by `kind`, `sessionId`, and a positive `limit`.
`GET /v1/artifacts/:id/content` downloads an artifact's file or blob.
[Artifacts](https://cursor.com/docs/agent-sdk/reference/artifacts.md) covers tagging and record fields.

## Call custom channel routes

Authored routes mount under `/v1/channels/<id>` with their declared
methods and paths, behind each channel's auth chain.
[Route responses](https://cursor.com/docs/agent-sdk/reference/channels.md#route-responses) covers what a hosted
caller gets back.

## MCP endpoint

Both MCP routes use stateless streamable HTTP, so they take `POST` and
return `405` for `GET` and `DELETE`.

`/v1/mcp` serves `ask`, `check`, and `call_tool` when server tools
exist, behind the session API auth chain. `/v1/mcp/tools` serves only
deterministic server tools, behind the CLI-level loopback, bearer, or
anonymous auth chain. [MCP connections](https://cursor.com/docs/agent-sdk/reference/connections.md#peer-mcp-connection)
connects one agent to another.

## Playground eval routes

| Route                                   | Contract                                                                                                               |
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `GET /v1/dev/evals`                     | List discovered cases and eval config                                                                                  |
| `GET /v1/dev/evals/runs`                | List recent run snapshots, newest first                                                                                |
| `POST /v1/dev/evals/runs`               | Start `{ filterIds?, tags?, timeoutMs?, verbose? }`. Returns `202`, `404` for no match, or `409` while a run is active |
| `GET /v1/dev/evals/runs/:runId`         | Progress and the final snapshot                                                                                        |
| `POST /v1/dev/evals/runs/:runId/cancel` | Cancel an active run. Returns `409` when it already ended                                                              |

Poll a run until it is `completed`, `failed`, or `cancelled`. A case must match one entry from each of `filterIds` and
`tags` that you pass.

## Dev-mode routes

These routes exist only under `serve --dev`, where schedules and
reminders never fire on their own. `POST /v1/dev/schedules/:scheduleId`
dispatches a schedule once and returns `{scheduleId, sessionIds}`.
`GET /v1/dev/reminders` lists reminders, and
`POST /v1/dev/reminders/:reminderId` fires one.

## Status codes

| Code  | Meaning                                                                          |
| ----- | -------------------------------------------------------------------------------- |
| `202` | Accepted for asynchronous work                                                   |
| `400` | Invalid body, query, or tool input                                               |
| `401` | No auth policy admitted the request                                              |
| `403` | The caller doesn't own the resource                                              |
| `404` | A named resource doesn't exist, or no eval case matches                          |
| `405` | The route doesn't accept this method                                             |
| `409` | The resource's state rejects the request, such as a stale token or busy write    |
| `500` | A write-effect tool can't create its session workspace (`workspace_unavailable`) |

## Related

- [Sessions](https://cursor.com/docs/agent-sdk/reference/sessions.md)
- [Channels](https://cursor.com/docs/agent-sdk/reference/channels.md)
- [Deployment](https://cursor.com/docs/agent-sdk/deployment.md)


---

## Sitemap

[Overview of all docs pages](/llms.txt)
