> ## 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.

# Chat

> Send messages to agents, manage conversations, and handle streaming responses.

# Chat

The chat endpoints power all agent interactions. Send messages, create conversations with welcome messages, and receive responses with optional streaming.

<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>

<Warning>
  This endpoint incurs provider cost and records a billing event via `record_external_cost_event()`. Credits are deducted from the organization's wallet based on the configured margin multiplier.
</Warning>

## Send Message

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

Send a message to an agent and receive a response. This is the core chat endpoint that orchestrates RAG context retrieval, prompt resolution, and LLM completion.

### Path Parameters

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

### Request Body

<ParamField body="message" type="string" required>
  User message text. 1-10,000 characters.
</ParamField>

<ParamField body="conversationId" type="string">
  Existing conversation UUID to continue. If omitted, a new conversation is created.
</ParamField>

<ParamField body="stream" type="boolean" default="false">
  Enable streaming response via Server-Sent Events (SSE). Only works if the agent also has `streamingEnabled: true`.
</ParamField>

<ParamField body="variables" type="object">
  Key-value pairs of template variables to merge into the conversation context. These are rendered into the system prompt.
</ParamField>

<ParamField body="attachments" type="object[]">
  File attachments to include with the message.

  <Expandable title="Attachment object">
    <ParamField body="id" type="string" required>Attachment UUID (from upload endpoint).</ParamField>
    <ParamField body="accessToken" type="string" required>Access token for the attachment.</ParamField>
  </Expandable>
</ParamField>

<ParamField body="includeVoice" type="boolean" default="false">
  Include a voice audio response (requires agent voice enabled).
</ParamField>

<ParamField body="systemPrompt" type="string">
  Override system prompt for this message only. Max 10,000 characters.
</ParamField>

### Response (200) -- Non-Streaming

<ResponseField name="response" type="string">The agent's text response.</ResponseField>
<ResponseField name="conversationId" type="string">Conversation UUID (new or existing).</ResponseField>
<ResponseField name="messageId" type="string">The response message UUID.</ResponseField>

<ResponseField name="sources" type="object[]">
  Knowledge base sources used to generate the response.

  <Expandable title="Source object">
    <ResponseField name="content" type="string">Chunk text content.</ResponseField>
    <ResponseField name="score" type="number">Relevance score (0-1).</ResponseField>
    <ResponseField name="documentTitle" type="string">Source document title.</ResponseField>
    <ResponseField name="knowledgeBaseId" type="string">Source KB UUID.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="usage" type="object">
  Token usage and cost information.

  <Expandable title="Usage object">
    <ResponseField name="promptTokens" type="number">Input tokens used.</ResponseField>
    <ResponseField name="completionTokens" type="number">Output tokens generated.</ResponseField>
    <ResponseField name="totalTokens" type="number">Total tokens.</ResponseField>
    <ResponseField name="cost" type="number">Estimated cost in USD.</ResponseField>
  </Expandable>
</ResponseField>

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://your-domain.com/api/bots/AGENT_ID/chat \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "message": "What is your return policy?",
      "conversationId": "conv-uuid-here",
      "stream": false
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    `https://your-domain.com/api/bots/${agentId}/chat`,
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${token}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        message: "What is your return policy?",
        conversationId: "conv-uuid-here",
      }),
    }
  );

  const data = await response.json();
  console.log(data.response);       // Agent's answer
  console.log(data.sources);        // KB sources cited
  ```
</CodeGroup>

### Streaming Response (SSE)

When `stream: true` is set and the agent has streaming enabled, the response is delivered as Server-Sent Events:

```javascript theme={null}
const response = await fetch(`https://your-domain.com/api/bots/${agentId}/chat`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${token}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    message: "Tell me about your product",
    stream: true,
  }),
});

const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  const chunk = decoder.decode(value);
  // SSE format: "data: {\"token\":\"Hello\"}\n\n"
  const lines = chunk.split("\n");
  for (const line of lines) {
    if (line.startsWith("data: ")) {
      const data = JSON.parse(line.slice(6));
      if (data.token) {
        process.stdout.write(data.token);
      }
      if (data.done) {
        // Final event includes sources and usage
        console.log(data.sources);
        console.log(data.usage);
      }
    }
  }
}
```

### Chat Pipeline

The full processing pipeline for each message:

1. Validate input and extract attachment content (text, images from PDFs/DOCX)
2. Merge per-message variables into conversation variables
3. **RAG retrieval** across all linked knowledge bases:
   * Build enhanced query from last 5 messages + attachment text
   * Vector search (top 3 per KB, minimum score 0.35)
   * Hybrid reranking: 60% vector similarity + 25% text relevance + 15% importance weight
   * Deduplication: max 2 chunks per document
   * Post-filter: minimum 0.25 combined score
4. Fetch KB document registry (document map) for agent awareness
5. Graph entity search for structured context
6. Resolve system prompt (agent config -> system default -> code fallback)
7. Render system prompt with conversation variables
8. Call LLM via LangChain with full context
9. Save messages, record billing, return response

***

## Create Conversation

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

Create a new conversation with an agent. Optionally generates a welcome message based on the agent's welcome prompt configuration.

### Path Parameters

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

### Request Body

<ParamField body="variables" type="object">
  Initial template variables for the conversation (e.g., user name, context).
</ParamField>

<ParamField body="context_token" type="string">
  Signed context token containing sensitive variables (generated via the context token endpoint).
</ParamField>

### Response (201)

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

<ResponseField name="data" type="object">
  <Expandable title="data object">
    <ResponseField name="conversationId" type="string">New conversation UUID.</ResponseField>

    <ResponseField name="welcomeMessage" type="string">
      Welcome message content (if configured). May be a fixed string or LLM-generated.
    </ResponseField>
  </Expandable>
</ResponseField>

### Welcome Message Modes

The welcome message behavior depends on the agent's welcome prompt config:

* **No config / disabled**: Conversation created with no welcome message
* **Fixed mode**: Returns the rendered content template directly
* **Generated mode**: Sends the prompt to the LLM and returns the generated response (billable)

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://your-domain.com/api/bots/AGENT_ID/conversations \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "variables": {
        "userName": "Jane",
        "plan": "premium"
      }
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    `https://your-domain.com/api/bots/${agentId}/conversations`,
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${token}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        variables: { userName: "Jane", plan: "premium" },
      }),
    }
  );

  const { data } = await response.json();
  const { conversationId, welcomeMessage } = data;
  ```
</CodeGroup>

***

## List Conversations

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

List conversations for the authenticated user, with optional filters.

### Query Parameters

<ParamField query="botId" type="string">Filter by agent UUID.</ParamField>
<ParamField query="userId" type="string">Filter by user UUID. Defaults to current user.</ParamField>
<ParamField query="platform" type="string">Filter by platform (e.g., `web`, `api`).</ParamField>
<ParamField query="limit" type="number" default="50">Maximum results.</ParamField>
<ParamField query="offset" type="number" default="0">Pagination offset.</ParamField>

### Response (200)

<ResponseField name="conversations" type="object[]">Array of conversation objects.</ResponseField>

<ResponseField name="pagination" type="object">
  <Expandable title="Pagination">
    <ResponseField name="limit" type="number" />

    <ResponseField name="offset" type="number" />

    <ResponseField name="total" type="number" />

    <ResponseField name="hasMore" type="boolean" />
  </Expandable>
</ResponseField>

***

## Get Conversation

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

Get a single conversation by ID, including metadata.

### Path Parameters

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

***

## Get Messages

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

Retrieve all messages in a conversation.

### Path Parameters

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

***

## Preview Chat (Draft Config)

<ParamField method="POST" path="/api/bots/:id/preview-chat" />

Test a chat interaction using the agent's draft (unpublished) configuration. Useful for testing prompt changes before publishing.

### Path Parameters

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

### Request Body

Same as [Send Message](#send-message).

<Note>
  Preview chat uses the agent's current draft prompt configurations rather than the published ones. This allows testing system prompt changes without affecting live users.
</Note>

***

## Conversation Variables

### Set Variables

<ParamField method="POST" path="/api/bots/:id/conversations/:convId/variables" />

Set server-side or sensitive variables on an existing conversation. These are merged into the conversation's variable store.

### Get Variables

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

Get current conversation variables. Sensitive variables are excluded from the response.

### Generate Context Token

<ParamField method="POST" path="/api/bots/:id/context-token" />

Generate a signed context token for passing sensitive variables (e.g., user PII, auth context) that should not be exposed in client-side code. The token is passed when creating a conversation.
