> ## Documentation Index
> Fetch the complete documentation index at: https://raveculture-mintlify-provision-email-header-1774047024.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Agents API

> Create, manage, and interact with agents

# Agents API

Create, manage, and interact with agents.

<Note>All agent endpoints that require authentication are scoped to the authenticated user's data through [row-level security](/security#row-level-security). You can only access agents that belong to your account.</Note>

## List agents

```http theme={null}
GET /api/agents
```

Returns all agents owned by the authenticated user. When no session is present, returns an empty list instead of a `401` error.

### Response

```json theme={null}
{
  "agents": [
    {
      "id": "agent_123",
      "name": "My Agent",
      "model": "claude-opus-4-6",
      "status": "running",
      "websocketUrl": "ws://openclaw-gateway:10000/agent/user_123",
      "createdAt": "2026-03-01T00:00:00Z",
      "updatedAt": "2026-03-18T00:00:00Z"
    }
  ],
  "count": 1,
  "status": "ok"
}
```

## Create agent

<Warning>The `POST /api/agents` endpoint is deprecated. Use [`POST /api/agents/provision`](#provision-agent) to create agents.</Warning>

## Get agent

```http theme={null}
GET /api/agents/:id
```

Requires authentication and ownership of the agent.

### Response

```json theme={null}
{
  "agent": {
    "id": "agent_123",
    "status": "active",
    "startedAt": "2026-03-01T00:00:00Z",
    "plan": "starter",
    "subdomain": "agent_123.agents.localhost",
    "url": "https://agent_123.agents.localhost",
    "openclawVersion": "2026.3.13",
    "verified": false,
    "verificationType": null,
    "attestationUid": null,
    "verifiedAt": null
  },
  "status": "ok"
}
```

### Errors

| Code | Description                          |
| ---- | ------------------------------------ |
| 401  | Unauthorized                         |
| 404  | Agent not found or not owned by user |
| 500  | Failed to fetch agent                |

## Update agent

<Warning>`PUT /api/agents/:id` is deprecated. Use [`PUT /api/agents/:id/config`](#update-agent-configuration) to update agent configuration.</Warning>

## Delete agent

<Warning>`DELETE /api/agents/:id` is deprecated. Use the lifecycle endpoints to manage agent state (for example, [`POST /api/instance/:userId/stop`](#stop-agent)).</Warning>

## Provision agent

```http theme={null}
POST /api/agents/provision
```

Provisions a new agent. Requires an active subscription unless the caller is an admin.

<Note>Provisioning requests may be processed asynchronously through the background task queue. The agent is created immediately with a `provisioning` status and transitions to `running` once the gateway confirms the deployment. If gateway provisioning fails, the status changes to `error`.</Note>

### Request body

| Field    | Type   | Required | Description                                                                          |
| -------- | ------ | -------- | ------------------------------------------------------------------------------------ |
| `name`   | string | Yes      | Agent name                                                                           |
| `model`  | string | No       | AI model (default: `claude-opus-4-6`). Options: `claude-opus-4-6`, `gpt-4`, `custom` |
| `config` | object | No       | Agent configuration                                                                  |
| `tier`   | string | No       | Subscription tier hint. Options: `starter`, `pro`, `enterprise`                      |

<Note>The agent limit is determined by the subscription plan on the authenticated user's account (`starter`: 1, `pro`: 3, `enterprise`: 100). It cannot be overridden in the request body.</Note>

### Admin bypass

Admin users (configured via `ADMIN_EMAILS`) are exempt from the following restrictions:

* **Subscription requirement** — admins can provision agents without an active subscription (the `402` error is not returned).
* **Agent limit** — admins receive an elevated agent slot limit instead of the plan-based cap.

### Response (201 Created)

```json theme={null}
{
  "success": true,
  "agent": {
    "id": "agent_789",
    "name": "My Agent",
    "status": "running",
    "websocketUrl": "ws://openclaw-gateway:10000/agent/user_123",
    "model": "claude-opus-4-6",
    "createdAt": "2026-03-19T00:00:00Z"
  }
}
```

### Errors

| Code | Description                                                                                                                                                                                               |
| ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 400  | Agent name is required                                                                                                                                                                                    |
| 401  | Unauthorized                                                                                                                                                                                              |
| 402  | Active subscription required to provision agents                                                                                                                                                          |
| 429  | Agent limit reached for your plan. Response includes `current` (agent count) and `limit` fields. Limits: `starter` 1, `pro` 3, `enterprise` 100. Users without a recognized plan default to a limit of 1. |
| 500  | Failed to provision agent                                                                                                                                                                                 |

## List provisioned agents

```http theme={null}
GET /api/agents/provision
```

Requires session authentication.

### Response

```json theme={null}
{
  "success": true,
  "agents": [
    {
      "id": "agent_789",
      "name": "My Agent",
      "model": "claude-opus-4-6",
      "status": "running",
      "websocketUrl": "ws://openclaw-gateway:10000/agent/user_123",
      "createdAt": "2026-03-19T00:00:00Z",
      "updatedAt": "2026-03-19T00:00:00Z"
    }
  ],
  "count": 1
}
```

### Errors

| Code | Description           |
| ---- | --------------------- |
| 401  | Unauthorized          |
| 500  | Failed to list agents |

## Get agent configuration

```http theme={null}
GET /api/agents/:id/config
```

Returns the current configuration for an agent. Requires authentication and ownership.

### Response

```json theme={null}
{
  "config": {}
}
```

### Errors

| Code | Description                 |
| ---- | --------------------------- |
| 401  | Unauthorized                |
| 502  | Backend service unavailable |

## Update agent configuration

```http theme={null}
PUT /api/agents/:id/config
```

Updates the configuration for an agent. Requires authentication and ownership. The request body is forwarded to the backend.

### Errors

| Code | Description                 |
| ---- | --------------------------- |
| 401  | Unauthorized                |
| 502  | Backend service unavailable |

## Get agent logs

<Warning>`GET /api/agents/:id/logs` is deprecated. This endpoint is not currently implemented and may be removed in a future release.</Warning>

## Get agent messages

```http theme={null}
GET /api/agents/:id/messages
```

Returns paginated messages for an agent. Requires authentication and ownership.

### Query parameters

| Parameter | Type   | Description                              |
| --------- | ------ | ---------------------------------------- |
| `limit`   | number | Maximum messages to return (default: 50) |
| `offset`  | number | Offset for pagination (default: 0)       |

### Response

```json theme={null}
{
  "messages": [],
  "total": 0,
  "limit": 50,
  "offset": 0,
  "status": "ok"
}
```

### Errors

| Code | Description                 |
| ---- | --------------------------- |
| 401  | Unauthorized                |
| 502  | Backend service unavailable |

## Get agent stats

```http theme={null}
GET /api/agents/:id/stats
```

Returns live container metrics when available, with a mock fallback.

### Response (live)

```json theme={null}
{
  "stats": {
    "agentId": "agent_123",
    "cpu": "0.15%",
    "memory": "128MiB / 2GiB",
    "memoryPercent": "6.25%",
    "network": "1.2kB / 3.4kB",
    "uptime": 86400000,
    "uptimeFormatted": "1d 0h",
    "status": "running",
    "pids": "12",
    "messagesProcessed": "N/A",
    "messagesPerHour": "N/A",
    "averageResponseTime": "N/A",
    "successRate": "N/A",
    "errorRate": "N/A"
  },
  "status": "ok"
}
```

### Response (mock fallback)

When the backend is unavailable, mock data is returned with `"status": "mock"`:

```json theme={null}
{
  "stats": {
    "agentId": "agent_123",
    "messagesProcessed": 1234,
    "messagesPerHour": 456,
    "averageResponseTime": 789,
    "uptime": 12345,
    "successRate": "95.42",
    "errorRate": "4.58",
    "timestamp": "2026-03-19T00:00:00Z"
  },
  "status": "mock"
}
```

## Agent lifecycle

Lifecycle operations use the `/api/instance/:userId` endpoint pattern. These endpoints require session authentication and proxy to the backend agent management service.

### Start agent

```http theme={null}
POST /api/instance/:userId/start
```

```json theme={null}
{
  "success": true,
  "status": "running"
}
```

### Stop agent

```http theme={null}
POST /api/instance/:userId/stop
```

```json theme={null}
{
  "success": true,
  "status": "stopped"
}
```

### Restart agent

```http theme={null}
POST /api/instance/:userId/restart
```

```json theme={null}
{
  "success": true,
  "status": "running"
}
```

### Update agent image

```http theme={null}
POST /api/instance/:userId/update
```

Triggers an image update on the backend.

```json theme={null}
{
  "success": true,
  "status": "running"
}
```

### Repair agent

```http theme={null}
POST /api/instance/:userId/repair
```

Returns the backend response directly.

```json theme={null}
{
  "success": true,
  "message": "Agent repaired successfully"
}
```

### Reset agent memory

```http theme={null}
POST /api/instance/:userId/reset-memory
```

Returns the backend response directly.

```json theme={null}
{
  "success": true,
  "message": "Memory reset successfully"
}
```

### Lifecycle error responses

All lifecycle endpoints return the following shape on failure:

```json theme={null}
{
  "success": false,
  "status": "error"
}
```

| Code | Description                                                       |
| ---- | ----------------------------------------------------------------- |
| 401  | `AUTH_REQUIRED` or `TOKEN_INVALID` — missing or invalid JWT token |
| 403  | Forbidden — authenticated user does not own this agent instance   |
| 502  | Backend service unavailable                                       |
| 500  | Internal server error                                             |

## Get instance details

```http theme={null}
GET /api/instance/:userId
```

Returns the current status and metadata for an agent instance.

### Response

```json theme={null}
{
  "userId": "user_123",
  "status": "running",
  "startedAt": "2026-03-01T00:00:00Z",
  "subdomain": "user_123.agents.localhost",
  "url": "https://user_123.agents.localhost",
  "plan": "solo",
  "openclawVersion": "2026.2.17"
}
```

## Get instance stats

```http theme={null}
GET /api/instance/:userId/stats
```

Returns resource usage statistics for an agent instance.

### Response

```json theme={null}
{
  "userId": "user_123",
  "cpu": "0.15%",
  "memory": "128MiB",
  "status": "running",
  "plan": "starter",
  "openclawVersion": "2026.3.13"
}
```

## Get agent gateway token

```http theme={null}
GET /api/instance/:userId/token
```

Returns an auto-generated gateway token for the agent. A new token is created if none exists.

```json theme={null}
{
  "token": "abc123def456"
}
```

### Errors

| Code | Description                 |
| ---- | --------------------------- |
| 502  | Backend service unavailable |
| 500  | Failed to get token         |

## Agent verification

Agents can be verified using multiple verification types: `eas` (Ethereum Attestation Service), `coinbase`, `ens`, or `webauthn`.

### Get verification status

```http theme={null}
GET /api/agents/:id/verify
```

```json theme={null}
{
  "verified": false,
  "verificationType": null,
  "attestationUid": null,
  "verifierAddress": null,
  "verifiedAt": null,
  "metadata": null
}
```

### Verify agent

```http theme={null}
POST /api/agents/:id/verify
```

#### Request body

| Field              | Type   | Required    | Description                                                                                 |
| ------------------ | ------ | ----------- | ------------------------------------------------------------------------------------------- |
| `verificationType` | string | Yes         | One of: `eas`, `coinbase`, `ens`, `webauthn`                                                |
| `attestationUid`   | string | For `eas`   | Attestation UID from EAS                                                                    |
| `walletAddress`    | string | No          | Address of the verifying wallet                                                             |
| `signature`        | string | Conditional | Cryptographic signature. Required for `coinbase`, `ens`, and `webauthn` verification types. |

#### Response

```json theme={null}
{
  "success": true,
  "verified": true,
  "verificationType": "eas",
  "attestationUid": "0x123...",
  "verifiedAt": "2026-03-19T00:00:00Z"
}
```

#### Errors

| Code | Description                                          |
| ---- | ---------------------------------------------------- |
| 400  | Invalid verification type or missing required fields |
| 401  | Unauthorized                                         |

### Remove verification

```http theme={null}
DELETE /api/agents/:id/verify
```

```json theme={null}
{
  "success": true
}
```

## Provision with channel tokens

```http theme={null}
POST /api/provision
```

Provisions a new agent with messaging channel tokens. No authentication is required. Rate-limited per IP. At least one channel token is required.

The request is proxied to the backend provisioning service. A dedicated Mux live stream is automatically created for the agent. The backend may enqueue the provisioning job to the `provision` queue for asynchronous processing.

### Request body

| Field                  | Type   | Required    | Description                                                                                                                                                                             |
| ---------------------- | ------ | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `telegramToken`        | string | Conditional | Telegram bot token. At least one channel token is required.                                                                                                                             |
| `telegramUserId`       | string | No          | Telegram user ID for owner binding                                                                                                                                                      |
| `whatsappToken`        | string | Conditional | WhatsApp API token. At least one channel token is required.                                                                                                                             |
| `discordBotToken`      | string | Conditional | Discord bot token. At least one channel token is required.                                                                                                                              |
| `aiProvider`           | string | No          | AI provider (default: `openrouter`). Options: `openrouter`, `gemini`, `groq`, `anthropic`, `openai`                                                                                     |
| `apiKey`               | string | No          | API key for the AI provider                                                                                                                                                             |
| `plan`                 | string | No          | Plan tier. Options: `solo`, `collective`, `label`, `network`. A paid plan is required — requests with `plan` set to `free` (or omitted) return `402 Payment Required`.                  |
| `email`                | string | No          | User email address. Used for admin and tester bypass of payment enforcement. Falls back to the `x-user-email` request header when not provided in the body (see below).                 |
| `stripeSubscriptionId` | string | No          | Active Stripe subscription ID. Required for non-admin, non-tester users on paid plans. When absent and the user is not an admin or tester, the endpoint returns `402 Payment Required`. |

<Note>The `email` field can also be provided via the `x-user-email` request header. When the request body does not include `email`, the backend reads the header value instead. This is useful when the auth middleware has already resolved the user's email and forwarded it in the header.</Note>

<Warning>The `free` plan value is deprecated. The provisioning service now requires a paid plan (`solo`, `collective`, `label`, or `network`) and a valid Stripe subscription. Requests with `plan` set to `free` return `402 Payment Required` with `code: "PAYMENT_REQUIRED"`.</Warning>

<Warning>The following request fields are deprecated and no longer accepted: `whatsappPhoneNumberId`, `whatsappBusinessAccountId`, `discordGuildId`, `discordChannelId`.</Warning>

### Response

The proxy returns a filtered subset of the backend response:

```json theme={null}
{
  "success": true,
  "userId": "a1b2c3d4e5",
  "subdomain": "dj-a1b2c3d4e5.agentbot.raveculture.xyz",
  "url": "https://dj-a1b2c3d4e5.agentbot.raveculture.xyz",
  "streamKey": "sk-ab12-cd34-ef56",
  "liveStreamId": "x7k9m2p4q1"
}
```

<Note>The `/api/provision` proxy returns only `success`, `userId`, `subdomain`, `url`, `streamKey`, and `liveStreamId`. The full response shape from the backend provisioning service is shown below.</Note>

### Full backend response

When calling the backend provisioning service directly, the response includes additional fields:

```json theme={null}
{
  "success": true,
  "userId": "a1b2c3d4e5",
  "agentId": "a1b2c3d4e5",
  "id": "a1b2c3d4e5",
  "aiProvider": "openrouter",
  "aiProviderConfig": {
    "model": "openai/gpt-4o-mini",
    "baseUrl": "https://openrouter.ai/api/v1",
    "requiresKey": true
  },
  "plan": "solo",
  "streamKey": "sk-ab12-cd34-ef56",
  "liveStreamId": "x7k9m2p4q1",
  "rtmpServer": "rtmps://live.mux.com/app",
  "playbackUrl": "https://image.mux.com/x7k9m2p4q1/playlist.m3u8",
  "subdomain": "dj-a1b2c3d4e5.agentbot.raveculture.xyz",
  "url": "https://dj-a1b2c3d4e5.agentbot.raveculture.xyz",
  "hls": {
    "playlistUrl": "https://image.mux.com/x7k9m2p4q1/playlist.m3u8"
  },
  "rtmp": {
    "server": "rtmps://live.mux.com/app",
    "key": "sk-ab12-cd34-ef56"
  },
  "status": "active",
  "createdAt": "2026-03-20T00:00:00Z",
  "metadata": {
    "channels": {
      "telegram": "enabled",
      "discord": "disabled",
      "whatsapp": "disabled"
    },
    "streaming": {
      "provider": "mux",
      "lowLatency": true,
      "resolution": "1920x1080",
      "bitrate": "5000k"
    }
  }
}
```

### Errors

| Code | Description                                                                                                                                                                                                |
| ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 400  | At least one channel token required (Telegram, WhatsApp, or Discord)                                                                                                                                       |
| 402  | Payment required. Returned when `plan` is `free` or when no valid Stripe subscription is present. The response includes `code: "PAYMENT_REQUIRED"` and a message directing the user to choose a paid plan. |
| 429  | Too many requests                                                                                                                                                                                          |
| 500  | Internal server error                                                                                                                                                                                      |
| 502  | Provisioning service unavailable or returned an error                                                                                                                                                      |
| 503  | Provisioning is temporarily disabled (kill switch active)                                                                                                                                                  |

## Agent interaction

```http theme={null}
GET /api/agent
POST /api/agent
```

Unified endpoint for interacting with agents. All requests require session authentication. The `userId` is always bound to the authenticated session and cannot be overridden by the client.

### GET actions

Pass the `action` query parameter to select the operation.

#### List endpoints

```http theme={null}
GET /api/agent
```

Returns available endpoints and version information when no action is specified.

```json theme={null}
{
  "apiVersion": "1.0.0",
  "agentbotVersion": "2026.3.1",
  "endpoints": {
    "GET /api/agent": "List endpoints",
    "GET /api/agent?action=health": "Health status",
    "GET /api/agent?action=sessions": "List sessions",
    "GET /api/agent?action=session&sessionId=xxx": "Get session details",
    "GET /api/agent?action=memory": "Get agent memory",
    "GET /api/agent?action=skills": "List available skills",
    "GET /api/agent?action=credentials": "List configured credentials",
    "POST /api/agent": "Send message to agent",
    "POST /api/agent?action=create-session": "Create new session",
    "POST /api/agent?action=update-skill": "Enable/disable skill"
  }
}
```

#### Health

```http theme={null}
GET /api/agent?action=health
```

```json theme={null}
{
  "status": "running",
  "version": "2026.3.1",
  "apiVersion": "1.0.0",
  "uptime": 86400,
  "model": "claude-sonnet-4-20250514",
  "channels": ["telegram"],
  "skills": [],
  "lastSeen": 1710806400000
}
```

#### List sessions

```http theme={null}
GET /api/agent?action=sessions
```

```json theme={null}
{
  "sessions": [
    {
      "id": "sess_abc123",
      "status": "active",
      "messageCount": 5,
      "createdAt": 1710806400000,
      "lastActivity": 1710810000000
    }
  ]
}
```

#### Get session

```http theme={null}
GET /api/agent?action=session&sessionId=sess_abc123
```

Returns the full session including messages.

#### Memory

```http theme={null}
GET /api/agent?action=memory
```

Returns the last 10 messages from the active session (truncated to 100 characters each).

```json theme={null}
{
  "memory": [
    { "role": "user", "content": "Hello, can you help me with..." },
    { "role": "assistant", "content": "Of course! Let me..." }
  ]
}
```

#### Skills

```http theme={null}
GET /api/agent?action=skills
```

Returns skills available on the agent instance.

#### Credentials

```http theme={null}
GET /api/agent?action=credentials
```

Returns which credentials are configured for the agent.

```json theme={null}
{
  "credentials": {
    "anthropic": false,
    "openai": false,
    "openrouter": true,
    "google": false,
    "telegram": true,
    "discord": false,
    "whatsapp": false
  }
}
```

### POST actions

Pass the `action` field in the request body.

#### Chat

```http theme={null}
POST /api/agent
```

| Field       | Type   | Required | Description                                                                               |
| ----------- | ------ | -------- | ----------------------------------------------------------------------------------------- |
| `action`    | string | No       | Set to `chat` or omit (default action)                                                    |
| `message`   | string | Yes      | Message to send to the agent                                                              |
| `sessionId` | string | No       | Session ID to continue. A new session is created if omitted and no active session exists. |

```json theme={null}
{
  "sessionId": "sess_abc123",
  "reply": "Agent is processing your request...",
  "timestamp": 1710810000000
}
```

#### Create session

| Field    | Type   | Required | Description      |
| -------- | ------ | -------- | ---------------- |
| `action` | string | Yes      | `create-session` |

```json theme={null}
{
  "sessionId": "sess_abc123",
  "status": "active"
}
```

#### Update skill

| Field     | Type    | Required | Description                                                                                   |
| --------- | ------- | -------- | --------------------------------------------------------------------------------------------- |
| `action`  | string  | Yes      | `update-skill`                                                                                |
| `skillId` | string  | Yes      | Skill ID to enable or disable                                                                 |
| `enabled` | boolean | No       | Whether to enable or disable the skill. Defaults to `false` (removes the skill) when omitted. |

```json theme={null}
{
  "success": true,
  "skillId": "browser",
  "enabled": true
}
```

#### Set credential

| Field    | Type   | Required | Description                                                               |
| -------- | ------ | -------- | ------------------------------------------------------------------------- |
| `action` | string | Yes      | `set-credential`                                                          |
| `key`    | string | Yes      | Credential key (for example, `anthropic`, `telegram`)                     |
| `value`  | string | No       | Credential value. When omitted, the credential is marked as unconfigured. |

```json theme={null}
{
  "success": true,
  "key": "anthropic",
  "configured": true
}
```

### Errors

| Code | Description                               |
| ---- | ----------------------------------------- |
| 400  | Invalid action or missing required fields |
| 401  | Unauthorized                              |
| 404  | Session not found                         |
| 500  | Internal error                            |

## Send message

```http theme={null}
POST /api/chat
```

Requires session authentication.

### Request body

| Field     | Type   | Required | Description        |
| --------- | ------ | -------- | ------------------ |
| `message` | string | Yes      | Message to send    |
| `topic`   | string | No       | Conversation topic |

```json theme={null}
{
  "message": "Hello!",
  "topic": "general"
}
```

### Response

```json theme={null}
{
  "id": "msg_123",
  "message": "Hello!",
  "topic": "general",
  "status": "sent",
  "timestamp": "2026-03-19T00:00:00Z",
  "reply": "Hi! How can I help?"
}
```

### Errors

| Code | Description            |
| ---- | ---------------------- |
| 400  | Message required       |
| 401  | Unauthorized           |
| 500  | Failed to send message |

## List messages

```http theme={null}
GET /api/chat
```

Returns the message history. Requires session authentication.

### Response

```json theme={null}
{
  "messages": [],
  "count": 0
}
```

### Errors

| Code | Description  |
| ---- | ------------ |
| 401  | Unauthorized |
