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

# Widget

> Public-facing API endpoints for the embeddable chat widget, including session management, messaging, and lead capture.

The Widget API powers the embeddable IllumiChat widget. These endpoints are public-facing and use a different authentication model than the standard API, relying on assistant ID validation and domain allowlists instead of bearer tokens.

## Authentication Model

Widget endpoints do not use bearer token authentication. Instead, they rely on a three-layer security model:

1. **Assistant ID** -- Each request includes the assistant ID, which must have `widgetEnabled: true`.
2. **Domain allowlist** -- The `Origin` or `Referer` header is validated against the assistant's configured allowed domains.
3. **Session token** -- After initialization, a session token is returned and must be included in subsequent requests.

```
Authorization: Widget <session_token>
```

<Note>
  Widget sessions can be anonymous (no user identity) or authenticated (linked to a known contact via email or external ID). Anonymous sessions are converted to authenticated sessions when a lead form is submitted.
</Note>

***

## CORS and Domain Restrictions

Widget endpoints include appropriate CORS headers to allow cross-origin requests from approved domains.

| Header                         | Value                                               |
| ------------------------------ | --------------------------------------------------- |
| `Access-Control-Allow-Origin`  | The requesting origin, if it matches the allowlist. |
| `Access-Control-Allow-Methods` | `GET, POST, OPTIONS`                                |
| `Access-Control-Allow-Headers` | `Content-Type, Authorization`                       |
| `Access-Control-Max-Age`       | `86400`                                             |

<Warning>
  Requests from domains not in the assistant's allowlist receive a `403 Forbidden` response. During development, add `localhost` to the allowlist in the assistant's widget settings.
</Warning>

***

## Initialize Widget Session

Creates a new widget session or resumes an existing one. This must be the first call made by the widget.

```bash theme={null}
curl -X POST "https://app.illumichat.com/api/widget/ast_abc123/init" \
  -H "Content-Type: application/json" \
  -H "Origin: https://www.acme.com" \
  -d '{
    "sessionId": null,
    "metadata": {
      "page": "/pricing",
      "referrer": "https://google.com"
    }
  }'
```

| Parameter   | Type   | Required | Description                                                         |
| ----------- | ------ | -------- | ------------------------------------------------------------------- |
| `sessionId` | string | No       | Previous session ID to resume. Pass `null` to create a new session. |
| `metadata`  | object | No       | Page context: `page`, `referrer`, `userAgent`. Used for analytics.  |

**Response** `200 OK`

```json theme={null}
{
  "data": {
    "sessionId": "wsess_aaa111",
    "sessionToken": "wt_eyJhbGciOiJIUzI1NiJ9...",
    "config": {
      "assistantName": "Support Bot",
      "welcomeMessage": "Hello! How can I help you today?",
      "primaryColor": "#6366F1",
      "position": "bottom-right",
      "leadFormEnabled": true,
      "leadFormFields": ["name", "email", "phone"]
    },
    "messages": []
  }
}
```

<Tip>
  Store the `sessionId` in `localStorage` to resume sessions across page navigations.
</Tip>

***

## Send Message (Streaming)

Sends a visitor message and streams the assistant's response via SSE. The streaming format is identical to the standard [Chat API](/api/chat) SSE events.

```bash theme={null}
curl -N -X POST "https://app.illumichat.com/api/widget/ast_abc123/chat" \
  -H "Authorization: Widget wt_eyJhbGciOiJIUzI1NiJ9..." \
  -H "Content-Type: application/json" \
  -H "Origin: https://www.acme.com" \
  -d '{
    "content": "What are your pricing plans?",
    "sessionId": "wsess_aaa111"
  }'
```

| Parameter   | Type   | Required | Description                                |
| ----------- | ------ | -------- | ------------------------------------------ |
| `content`   | string | Yes      | The visitor's message text.                |
| `sessionId` | string | Yes      | The active session ID from initialization. |

***

## Get Session History

Retrieves the full message history for a widget session.

```bash theme={null}
curl -X GET "https://app.illumichat.com/api/widget/ast_abc123/sessions/wsess_aaa111/messages" \
  -H "Authorization: Widget wt_eyJhbGciOiJIUzI1NiJ9..." \
  -H "Origin: https://www.acme.com"
```

**Response** `200 OK`

```json theme={null}
{
  "data": [
    {
      "id": "msg_aaa111",
      "role": "assistant",
      "content": "Hello! How can I help you today?",
      "createdAt": "2025-09-15T10:00:00Z"
    },
    {
      "id": "msg_bbb222",
      "role": "user",
      "content": "What are your pricing plans?",
      "createdAt": "2025-09-15T10:00:15Z"
    }
  ]
}
```

***

## Submit Lead Form

Captures visitor contact information. Converts an anonymous session into an authenticated session linked to a contact record.

```bash theme={null}
curl -X POST "https://app.illumichat.com/api/widget/ast_abc123/sessions/wsess_aaa111/lead" \
  -H "Authorization: Widget wt_eyJhbGciOiJIUzI1NiJ9..." \
  -H "Content-Type: application/json" \
  -H "Origin: https://www.acme.com" \
  -d '{
    "name": "Jane Smith",
    "email": "jane@example.com",
    "phone": "+15559876543",
    "customFields": { "company": "Example Inc." }
  }'
```

| Parameter      | Type   | Required    | Description                                                        |
| -------------- | ------ | ----------- | ------------------------------------------------------------------ |
| `name`         | string | No          | Visitor's name.                                                    |
| `email`        | string | Conditional | Email address. Required if configured in lead form settings.       |
| `phone`        | string | No          | Phone number.                                                      |
| `customFields` | object | No          | Additional key-value pairs defined in the lead form configuration. |

**Response** `201 Created`

<Note>
  Lead form submissions trigger the `contact.created` webhook event if webhooks are configured for the workspace.
</Note>

***

## Submit Feedback

Allows visitors to rate a conversation or a specific assistant response.

```bash theme={null}
curl -X POST "https://app.illumichat.com/api/widget/ast_abc123/sessions/wsess_aaa111/feedback" \
  -H "Authorization: Widget wt_eyJhbGciOiJIUzI1NiJ9..." \
  -H "Content-Type: application/json" \
  -H "Origin: https://www.acme.com" \
  -d '{
    "messageId": "msg_ccc333",
    "rating": "positive",
    "comment": "Very helpful answer!"
  }'
```

| Parameter   | Type   | Required | Description                                                                    |
| ----------- | ------ | -------- | ------------------------------------------------------------------------------ |
| `messageId` | string | No       | Specific message to rate. If omitted, feedback applies to the session overall. |
| `rating`    | string | Yes      | One of `positive` or `negative`.                                               |
| `comment`   | string | No       | Optional free-text feedback from the visitor.                                  |

**Response** `201 Created`

***

## End Session

Explicitly ends a widget session. The session can no longer accept new messages after this call.

```bash theme={null}
curl -X POST "https://app.illumichat.com/api/widget/ast_abc123/sessions/wsess_aaa111/end" \
  -H "Authorization: Widget wt_eyJhbGciOiJIUzI1NiJ9..." \
  -H "Origin: https://www.acme.com"
```

**Response** `200 OK`

```json theme={null}
{
  "data": {
    "sessionId": "wsess_aaa111",
    "status": "ended",
    "messageCount": 6,
    "duration": 342,
    "endedAt": "2025-09-15T10:05:42Z"
  }
}
```

<Tip>
  Sessions also end automatically after a configurable period of inactivity (default 30 minutes). Explicitly ending a session triggers the `conversation.ended` webhook event immediately.
</Tip>
