> ## Documentation Index
> Fetch the complete documentation index at: https://aspect.inc/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent API

> Drive the Aspect AI assistant programmatically with conversations, streamed events, and tool approvals

The Agent API is the same interface the Aspect web app uses to power its [AI assistant](/docs/guides/ai-assistant). You can use it to build your own integrations: create a conversation, send a message to start a run, stream the assistant's events over SSE, and approve or reject any tool calls that require confirmation.

All endpoints live under `https://api.aspect.inc/agent` and authenticate with an `sk_` API key like the rest of the [REST API](/docs/api-reference).

## Lifecycle

<Steps>
  <Step title="Create a conversation">
    `POST /agent/conversations` creates a conversation scoped to a workspace (and optionally a project).
  </Step>

  <Step title="Start a run">
    `POST /agent/conversations/{conversation_id}/runs` sends a user message. The response is a Server-Sent Events stream of the run as it executes.
  </Step>

  <Step title="Follow events">
    `GET /agent/conversations/{conversation_id}/events/stream` streams the conversation's event log from any cursor - useful for reconnecting or observing from a second client.
  </Step>

  <Step title="Handle approvals">
    When a run pauses with `requires_approval`, submit a decision with `POST /agent/runs/{run_id}/approvals/{approval_id}`, then resume the run.
  </Step>
</Steps>

## Create a conversation

```bash theme={null}
curl -X POST https://api.aspect.inc/agent/conversations \
  -H "Authorization: Bearer sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "workspace_id": "9f0b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d",
    "project_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
    "title": "Footage review"
  }'
```

`workspace_id` is required (unless you pass `share_id` for a share-scoped conversation). `project_id` and `title` are optional. The response (`201`) includes the conversation `id`, scope, `status`, and timestamps.

Related conversation endpoints:

* `GET /agent/conversations?workspace_id=...&offset=0&limit=50`: list conversations in a scope; supports optional `project_id` or `share_id`, returns `conversations` and `has_more`.
* `GET /agent/conversations/{conversation_id}`: hydrate a conversation, returning its metadata plus full `messages`, `runs`, and `tool_calls`.
* `PATCH /agent/conversations/{conversation_id}`: update the title.

## Start a run

Send a user message. The connection stays open and returns the run's events as an SSE stream (`Content-Type: text/event-stream`):

```bash theme={null}
curl -N -X POST https://api.aspect.inc/agent/conversations/{conversation_id}/runs \
  -H "Authorization: Bearer sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"content": "Find all clips where someone mentions the product launch"}'
```

The request body accepts:

| Field           | Required | Description                                                                  |
| --------------- | -------- | ---------------------------------------------------------------------------- |
| `content`       | Yes      | The user message text.                                                       |
| `content_parts` | No       | Structured message content.                                                  |
| `mentions`      | No       | Structured mentions of resources (projects, assets, collections, and so on). |
| `page_context`  | No       | A snapshot of the client's current page context.                             |
| `model`         | No       | Optional model override.                                                     |

## Stream and list events

Every conversation has an ordered event log with a monotonically increasing integer `cursor`, so you can resume from wherever you left off:

```bash theme={null}
curl -N "https://api.aspect.inc/agent/conversations/{conversation_id}/events/stream?after_cursor=0" \
  -H "Authorization: Bearer sk_your_api_key"
```

Event types include `run.created`, `run.status_changed`, `text.delta`, `text.completed`, `tool_call.created`, `tool_call.updated`, `tool_call.completed`, `approval.required`, and `approval.resolved`. Each event carries its `cursor`, `event_type`, and a JSON `payload`.

For polling instead of streaming, `GET /agent/conversations/{conversation_id}/events?after_cursor=0&limit=100` returns a page of events with `has_more` and `latest_cursor`.

<Note>
  For SSE endpoints, the API key can also be passed as an `authorization` query parameter when your client cannot set request headers.
</Note>

## Approvals

Tools with side effects (creating share links, moving files, and so on) can pause the run with status `requires_approval`. The `approval.required` event carries the tool call details and an approval ID. Submit a decision:

```bash theme={null}
curl -X POST https://api.aspect.inc/agent/runs/{run_id}/approvals/{approval_id} \
  -H "Authorization: Bearer sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"decision": "approve"}'
```

`decision` is `approve` or `reject`, with an optional `note`. The response is the updated run. After deciding, resume the run to continue execution.

## Resume and cancel

Resume a paused run - the response is a fresh SSE stream of the continuing run:

```bash theme={null}
curl -N -X POST https://api.aspect.inc/agent/runs/{run_id}/resume \
  -H "Authorization: Bearer sk_your_api_key"
```

Cancel a run:

```bash theme={null}
curl -X POST https://api.aspect.inc/agent/runs/{run_id}/cancel \
  -H "Authorization: Bearer sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"reason": "No longer needed"}'
```

## Run statuses

A run moves through these statuses, reported via `run.status_changed` events and on run responses:

`pending` → `running` → (`requires_approval` | `paused`) → `completed` | `failed` | `cancel_requested` → `cancelled`

The assistant has the same tool set and permission checks as the in-app experience - it can only see and change what your API key's user can.
