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

# Chat widget API reference

> The HTTP endpoints the Circuit chat widget uses: configuration, sending messages, streaming responses, and retrieving history.

This page documents the API the chat widget uses to communicate with Circuit. It exists for transparency: security reviewers can see exactly what the widget sends and receives, and developers can understand its behavior when debugging.

<Note>
  The script-tag widget is the supported way to embed Circuit chat. If you want to build a custom chat interface on these endpoints directly, contact the Circuit team.
</Note>

## Basics

* Base URL: `https://api.circuit.ai`
* Authentication: `Authorization: Bearer YOUR_AGENT_KEY` on every request
* Session continuity: `X-Session-Token` header (see [sessions](/it/chat-widget/security#sessions))
* All endpoints enforce the key's [domain allowlist](/it/chat-widget/security#domain-allowlisting) and share one [rate limit](/it/chat-widget/security#rate-limiting) of 60 requests per minute per key

## GET /chat-bot/config

Returns the full configuration for the agent bound to the key. The launcher calls this on every page load to render the bubble with the correct branding.

Response headers: `Cache-Control: public, max-age=60`, `Vary: Authorization, Origin`. The response is cacheable per (apiKey, origin) pair for 60 seconds.

Response body:

```json theme={null}
{
  "agent": {
    "name": "Support",
    "welcomeMessage": "How can I help?"
  },
  "branding": {
    "primaryColor": "#30a46c",
    "logo": "https://example.com/logo.png",
    "position": "bottom-right",
    "attribution": true,
    "style": "windowed"
  },
  "features": {
    "actions": true,
    "askUserQuestion": true
  }
}
```

* `welcomeMessage` is `null` when no welcome message is configured.
* `logo` is `null` when no logo is configured; the widget falls back to the Circuit mark.
* `position` accepts: `top-left`, `top-center`, `top-right`, `middle-left`, `middle-center`, `middle-right`, `bottom-left`, `bottom-center`, `bottom-right`. Unrecognized values fall back to `bottom-right`.
* `style`: `windowed` or `floating`.
* `features.actions` reflects whether the agent has any actions visible to widget visitors (admin-only and hide-in-chat actions are stripped).
* `features.askUserQuestion` is derived from whether the agent's tool list includes AskUserQuestion.

A non-2xx response or malformed body causes the launcher to log a `console.warn` and render nothing (fail-closed).

## POST /chat-bot/

Sends a visitor message and streams the agent's response.

On the first call, the server creates a session and returns the session token in `X-Session-Token`. Include this token on all subsequent requests as `X-Session-Token: <token>` to continue the same chat.

Request headers: `Content-Type: application/json`, `Accept: text/event-stream`, and for subsequent turns, `X-Session-Token: <token>`.

Request body:

```json theme={null}
{
  "messages": [
    { "type": "text", "block": { "value": "What are your support hours?" } }
  ]
}
```

The response is a server-sent event stream (`Content-Type: text/event-stream`). Each event has an event name and a JSON data payload:

| Event                 | Payload                                   | Meaning                                                                                    |
| --------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------ |
| `start`               | none                                      | The stream has begun.                                                                      |
| `text`                | string chunk                              | A piece of the agent's answer text. Concatenate chunks in order.                           |
| `progress`            | status text                               | A transient status line while the agent works.                                             |
| `tool_usage_start`    | tool info                                 | The agent started using a tool, such as searching an index.                                |
| `tool_usage_progress` | progress rows                             | Updates while the tool runs.                                                               |
| `tool_usage_stop`     | final status                              | The tool finished.                                                                         |
| `image`               | image data                                | An inline image in the response.                                                           |
| `error`               | `{ "message": "...", "retryable": true }` | Something failed mid-stream. `retryable` indicates whether resending is likely to succeed. |
| `done`                | none                                      | The response is complete.                                                                  |

The set of event types can grow over time. Consumers should ignore event types they do not recognize.

Error status codes: `400` malformed body, `401` missing or revoked key, `403` origin not in the allowed domains list, `429` rate limit exceeded.

## GET /chat-bot/history

Returns all messages in the current session, in order. Requires `X-Session-Token: <token>` to identify the session.

Returns `404` when there is no session, which is the expected state before the visitor's first message. This endpoint never creates a session.

```json theme={null}
{
  "messages": [
    { "id": "...", "role": "user", "content": "...", "created_at": "..." },
    { "id": "...", "role": "assistant", "content": "...", "created_at": "..." }
  ]
}
```

## GET /chat-bot/agent

Returns a narrow view of the agent bound to the key:

```json theme={null}
{
  "id": "...",
  "name": "Support Agent",
  "actions": [ ]
}
```

Admin-only and hide-in-chat actions are stripped server-side before the response is sent.

## JS API on the host page

The launcher attaches a small global to `window` so your page can drive the chat from its own UI:

```html theme={null}
<button onclick="window.CircuitChat.open()">Need help?</button>
```

| Method                       | Effect                                                                                                 |
| ---------------------------- | ------------------------------------------------------------------------------------------------------ |
| `window.CircuitChat.open()`  | Reveals the chat iframe (creating it lazily on first call) and asks the SPA to focus the prompt input. |
| `window.CircuitChat.close()` | Hides the iframe and asks the SPA to blur the prompt.                                                  |

Calls made before the SPA finishes loading are queued and flushed once it signals ready, so `window.CircuitChat.open()` on page load reliably opens the chat when the SPA mounts. `window.CircuitChat` is removed if the launcher is torn down.
