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

# Agents

> Create, read, update, and delete AI agents. Manage agent publishing lifecycle.

# Agents

Agents (also called bots) are the core resource in Brainstormer. Each agent has a name, AI model, system prompt, linked knowledge bases, and configuration for streaming, voice, file uploads, and multimodal support.

<Note>
  All API requests require a valid JWT token in the `Authorization: Bearer <token>` header. The API Gateway decodes the JWT and forwards auth context (`user-id`, `organization-id`, `user-email`, `x-platform-role`, `x-org-role`) as headers to downstream services.
</Note>

## Create Agent

<ParamField method="POST" path="/api/bots" />

Create a new agent in your organization.

### Request Body

<ParamField body="name" type="string" required>
  Agent name. 1-255 characters.
</ParamField>

<ParamField body="description" type="string">
  Agent description. Max 2000 characters.
</ParamField>

<ParamField body="model" type="string">
  AI model ID (e.g. `openai/gpt-4o`). If omitted, uses the platform default.
</ParamField>

<ParamField body="systemPrompt" type="string">
  System prompt for the agent. Max 50,000 characters.
</ParamField>

<ParamField body="knowledgeBaseIds" type="string[]" required>
  Array of knowledge base UUIDs to link to this agent. At least one knowledge base is required when publishing (`isDraft: false`).
</ParamField>

<ParamField body="isDraft" type="boolean" default="false">
  If `true`, creates the agent as a draft. Draft agents do not need a linked knowledge base.
</ParamField>

<ParamField body="streamingEnabled" type="boolean" default="true">
  Enable streaming responses for chat.
</ParamField>

<ParamField body="fileUploadsEnabled" type="boolean" default="false">
  Allow file uploads in chat.
</ParamField>

<ParamField body="voiceEnabled" type="boolean" default="false">
  Enable voice capabilities.
</ParamField>

<ParamField body="voiceSettings" type="object">
  Voice configuration.

  <Expandable title="Voice settings">
    <ParamField body="voice" type="string" required>Voice ID.</ParamField>
    <ParamField body="speed" type="number">Speed multiplier (0.1-2.0).</ParamField>
  </Expandable>
</ParamField>

<ParamField body="multimodalConfig" type="object">
  Multimodal input configuration.

  <Expandable title="Multimodal config">
    <ParamField body="enabled" type="boolean" required>Enable multimodal inputs.</ParamField>
    <ParamField body="supportedTypes" type="string[]">Array of: `image`, `document`, `audio`, `video`, `text`.</ParamField>
  </Expandable>
</ParamField>

<ParamField body="tools" type="object[]">
  Tool configurations for the agent.

  <Expandable title="Tool config">
    <ParamField body="toolDefinitionId" type="string" required>Tool definition ID.</ParamField>
    <ParamField body="isEnabled" type="boolean" required>Whether the tool is active.</ParamField>
    <ParamField body="config" type="object">Tool-specific configuration.</ParamField>
  </Expandable>
</ParamField>

<ParamField body="templateVariables" type="object[]">
  Template variables for the system prompt.
</ParamField>

### Response (201)

<ResponseField name="success" type="boolean">Always `true` on success.</ResponseField>

<ResponseField name="bot" type="object">
  The created agent object.

  <Expandable title="Agent object">
    <ResponseField name="id" type="string">Agent UUID.</ResponseField>
    <ResponseField name="name" type="string">Agent name.</ResponseField>
    <ResponseField name="description" type="string">Agent description.</ResponseField>
    <ResponseField name="model" type="string">AI model ID.</ResponseField>
    <ResponseField name="organizationId" type="string">Owning organization UUID.</ResponseField>
    <ResponseField name="isDraft" type="boolean">Whether this is a draft.</ResponseField>
    <ResponseField name="streamingEnabled" type="boolean">Streaming enabled.</ResponseField>
    <ResponseField name="fileUploadsEnabled" type="boolean">File uploads enabled.</ResponseField>
    <ResponseField name="createdAt" type="string">ISO 8601 timestamp.</ResponseField>
    <ResponseField name="updatedAt" type="string">ISO 8601 timestamp.</ResponseField>
  </Expandable>
</ResponseField>

### Errors

<ResponseField name="400 Knowledge base not ready" type="error">
  Returned when `isDraft` is `false` and the agent has no linked knowledge bases, or none of the linked knowledge bases have indexed documents. The response includes:

  <Expandable title="Error body">
    <ResponseField name="error" type="string">`Knowledge base not ready`</ResponseField>
    <ResponseField name="message" type="string">`At least one knowledge base must be linked and have indexed documents before this agent can go live.`</ResponseField>
  </Expandable>
</ResponseField>

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://your-domain.com/api/bots \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Customer Support Agent",
      "description": "Answers customer questions using the help center KB",
      "model": "openai/gpt-4o",
      "knowledgeBaseIds": ["kb-uuid-here"],
      "streamingEnabled": true
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://your-domain.com/api/bots", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${token}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      name: "Customer Support Agent",
      description: "Answers customer questions using the help center KB",
      model: "openai/gpt-4o",
      knowledgeBaseIds: ["kb-uuid-here"],
      streamingEnabled: true,
    }),
  });

  const { bot } = await response.json();
  ```
</CodeGroup>

***

## List Agents

<ParamField method="GET" path="/api/bots" />

List all agents in your organization.

### Query Parameters

<ParamField query="limit" type="number" default="50">
  Maximum number of agents to return.
</ParamField>

<ParamField query="offset" type="number" default="0">
  Number of agents to skip for pagination.
</ParamField>

### Response (200)

<ResponseField name="bots" type="object[]">Array of agent objects.</ResponseField>

<ResponseField name="pagination" type="object">
  <Expandable title="Pagination">
    <ResponseField name="limit" type="number">Requested limit.</ResponseField>
    <ResponseField name="offset" type="number">Requested offset.</ResponseField>
    <ResponseField name="total" type="number">Total count of agents.</ResponseField>
  </Expandable>
</ResponseField>

```bash curl theme={null}
curl https://your-domain.com/api/bots?limit=20&offset=0 \
  -H "Authorization: Bearer $TOKEN"
```

***

## Get Agent

<ParamField method="GET" path="/api/bots/:id" />

Get a single agent by ID, including linked knowledge bases.

### Path Parameters

<ParamField path="id" type="string" required>Agent UUID.</ParamField>

### Response (200)

Returns the full agent object plus:

<ResponseField name="knowledgeBases" type="object[]">
  Array of linked knowledge base objects with full details (name, description, document counts).
</ResponseField>

```bash curl theme={null}
curl https://your-domain.com/api/bots/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer $TOKEN"
```

***

## Update Agent

<ParamField method="PUT" path="/api/bots/:id" />

Update an existing agent. All fields are optional -- only provided fields are updated.

### Path Parameters

<ParamField path="id" type="string" required>Agent UUID.</ParamField>

### Request Body

Same fields as [Create Agent](#create-agent), but all are optional.

<Warning>
  If you include `knowledgeBaseIds`, the entire set of linked KBs is replaced. Sending an empty array `[]` will unlink all knowledge bases.
</Warning>

### Response (200)

Returns the updated agent object.

### Errors

<ResponseField name="400 Knowledge base not ready" type="error">
  Returned when `isDraft` is set to `false` and the agent has no linked knowledge bases, or none of the linked knowledge bases have indexed documents yet.
</ResponseField>

```bash curl theme={null}
curl -X PUT https://your-domain.com/api/bots/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Updated Agent Name",
    "model": "anthropic/claude-sonnet-4"
  }'
```

***

## Delete Agent

<ParamField method="DELETE" path="/api/bots/:id" />

Soft-delete an agent (sets deleted\_at; conversations are retained). The agent stops appearing in active listings.

### Path Parameters

<ParamField path="id" type="string" required>Agent UUID.</ParamField>

### Response (204)

No content on success.

```bash curl theme={null}
curl -X DELETE https://your-domain.com/api/bots/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer $TOKEN"
```

***

## Get Agent Usage

<ParamField method="GET" path="/api/bots/:id/usage" />

Get usage statistics for an agent (conversations, messages, token usage, costs).

### Path Parameters

<ParamField path="id" type="string" required>Agent UUID.</ParamField>

### Response (200)

Returns usage statistics including conversation counts, message counts, total tokens, and estimated cost.

***

## Version History

<ParamField method="GET" path="/api/bots/:id/versions" />

Get version history for an agent. Every update creates a new version snapshot.

### Path Parameters

<ParamField path="id" type="string" required>Agent UUID.</ParamField>

### Response (200)

<ResponseField name="versions" type="object[]">
  Array of version snapshots, newest first.

  <Expandable title="Version object">
    <ResponseField name="version" type="number">Version number.</ResponseField>
    <ResponseField name="changes" type="object">Snapshot of the agent config at this version.</ResponseField>
    <ResponseField name="notes" type="string">Version notes (user-provided or auto-generated).</ResponseField>
    <ResponseField name="createdAt" type="string">ISO 8601 timestamp.</ResponseField>
    <ResponseField name="createdBy" type="string">User ID who created this version.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="total" type="number">Total number of versions.</ResponseField>

***

## Revert to Version

<ParamField method="POST" path="/api/bots/:id/versions/:version/revert" />

Revert an agent's configuration to a specific version. This creates a new version (does not rewrite history).

### Path Parameters

<ParamField path="id" type="string" required>Agent UUID.</ParamField>
<ParamField path="version" type="number" required>Version number to revert to.</ParamField>

### Response (200)

<ResponseField name="success" type="boolean">Always `true`.</ResponseField>
<ResponseField name="bot" type="object">Updated agent object.</ResponseField>
<ResponseField name="message" type="string">Confirmation message.</ResponseField>

***

## Get Draft Status

<ParamField method="GET" path="/api/bots/:id/draft-status" />

Get the current publish/draft status of an agent, including any pending review.

### Path Parameters

<ParamField path="id" type="string" required>Agent UUID.</ParamField>

***

## Publishing Lifecycle

Agents follow a publish lifecycle: draft -> submitted for review -> approved/rejected -> published.

### Submit for Review

<ParamField method="POST" path="/api/bots/:id/submit-review" />

Submit a draft agent for review.

### Approve Agent

<ParamField method="POST" path="/api/bots/:id/approve" />

Approve a submitted agent (requires appropriate role).

### Reject Agent

<ParamField method="POST" path="/api/bots/:id/reject" />

Reject a submitted agent with feedback.

### Publish Agent

<ParamField method="POST" path="/api/bots/:id/publish" />

Publish an approved agent, making it available to end users.

### Errors

<ResponseField name="400 Knowledge base not ready" type="error">
  Returned when the agent has no linked knowledge bases, or none of the linked knowledge bases have indexed documents yet.
</ResponseField>

***

## Get Agent Indexing Status

<ParamField method="GET" path="/api/bots/:id/indexing-status" />

Returns the indexing status of all knowledge bases linked to this agent. Use this to check whether the agent is ready to be published.

### Path Parameters

<ParamField path="id" type="string" required>Agent UUID.</ParamField>

### Response (200)

<ResponseField name="linkedKbCount" type="number">Number of knowledge bases linked to the agent.</ResponseField>
<ResponseField name="totalDocuments" type="number">Total documents across all linked knowledge bases.</ResponseField>
<ResponseField name="indexedDocuments" type="number">Documents with `processing_status = completed`.</ResponseField>
<ResponseField name="failedDocuments" type="number">Documents that failed processing.</ResponseField>
<ResponseField name="pendingDocuments" type="number">Documents still pending or processing.</ResponseField>
<ResponseField name="ready" type="boolean">`true` when at least one knowledge base is linked and at least one document is indexed.</ResponseField>

```bash curl theme={null}
curl https://your-domain.com/api/bots/550e8400-e29b-41d4-a716-446655440000/indexing-status \
  -H "Authorization: Bearer $TOKEN"
```

***

## RBAC Permissions

All agent endpoints enforce role-based access control:

| Action       | Required Permission |
| ------------ | ------------------- |
| Get agent    | `use`               |
| List agents  | (org membership)    |
| Create agent | (org membership)    |
| Update agent | `edit`              |
| Delete agent | `delete`            |
| View usage   | `view_analytics`    |
