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

# SDK Reference

> JavaScript API for programmatic widget control

The IllumiChat Widget SDK provides a JavaScript API for creating, controlling, and responding to widget events programmatically.

<Note>
  The SDK always opens the production AI-first widget. There is no public
  version selector or conversation-start mode. Existing embed URLs and SDK
  initialization calls continue to work with the production renderer.
</Note>

## Global API

### IllumiChat.Widget

The main widget class. Create an instance by passing a configuration object.

```javascript theme={null}
const widget = new IllumiChat.Widget({
  assistantId: 'YOUR_ASSISTANT_ID'
});
await widget.initialize();
```

### IllumiChat.getInstance()

Returns the current singleton widget instance. When the widget is loaded via a script tag with `data-assistant-id`, the SDK automatically creates a singleton.

```javascript theme={null}
const widget = IllumiChat.getInstance();
widget.open();
```

<Note>
  `getInstance()` returns `null` if no widget has been initialized yet.
</Note>

### IllumiChat.destroyInstance()

Destroys the current singleton instance, removes the widget from the DOM, and cleans up all event listeners.

```javascript theme={null}
IllumiChat.destroyInstance();
```

### IllumiChat.VERSION

Returns the current SDK version string.

## Instance Methods

| Method              | Returns         | Description                                                       |
| ------------------- | --------------- | ----------------------------------------------------------------- |
| `initialize()`      | `Promise<void>` | Initialize the widget, create the iframe, and render the launcher |
| `open()`            | `void`          | Open the chat panel                                               |
| `close()`           | `void`          | Close the chat panel                                              |
| `toggle()`          | `void`          | Toggle the chat panel open or closed                              |
| `sendMessage(text)` | `void`          | Send a message programmatically as if the visitor typed it        |
| `getState()`        | `string`        | Return the current widget state                                   |
| `getConfig()`       | `object`        | Return a copy of the current widget configuration                 |
| `destroy()`         | `void`          | Remove the widget from the DOM and release all resources          |

### initialize()

Must be called before any other method. Creates the iframe, injects styles, and renders the launcher button.

```javascript theme={null}
const widget = new IllumiChat.Widget({
  assistantId: 'YOUR_ASSISTANT_ID'
});

try {
  await widget.initialize();
  console.log('Widget is ready');
} catch (error) {
  console.error('Widget failed to initialize:', error);
}
```

<Warning>
  You must call `initialize()` before calling any other method. Calling `open()` or `sendMessage()` on an uninitialized widget has no effect.
</Warning>

### open()

Opens the chat panel.

```javascript theme={null}
document.getElementById('help-button').addEventListener('click', () => {
  const widget = IllumiChat.getInstance();
  if (widget) widget.open();
});
```

### close()

Closes the chat panel. The launcher button remains visible.

### toggle()

Toggles the chat panel. If open it closes; if closed it opens.

### sendMessage(text)

Sends a text message as if the visitor typed and submitted it.

```javascript theme={null}
widget.open();
widget.sendMessage('I have a question about pricing');
```

### getState()

Returns the current widget state as a string.

### destroy()

Removes the widget entirely from the page. After calling `destroy()`, the instance cannot be reused.

## Widget States

| State           | Description                                             |
| --------------- | ------------------------------------------------------- |
| `uninitialized` | Instance created but `initialize()` not called          |
| `initializing`  | `initialize()` called, setup in progress                |
| `ready`         | Initialization complete, launcher visible, panel closed |
| `open`          | Chat panel is visible                                   |
| `closed`        | Chat panel hidden, launcher visible                     |
| `error`         | An error occurred                                       |
| `destroyed`     | `destroy()` called, widget fully removed                |

## Event System

### Subscribing to Events

```javascript theme={null}
// Subscribe
const unsubscribe = widget.on('open', () => {
  console.log('Chat panel was opened');
});

// Unsubscribe
unsubscribe();
```

### One-Time Listeners

```javascript theme={null}
widget.once('ready', () => {
  console.log('Widget is ready — fires only once');
});
```

### Removing a Specific Handler

```javascript theme={null}
function handleOpen() { console.log('Opened'); }
widget.on('open', handleOpen);
widget.off('open', handleOpen);
```

### Available Events

| Event                    | Payload                                                          | Description                                                        |
| ------------------------ | ---------------------------------------------------------------- | ------------------------------------------------------------------ |
| `ready`                  | --                                                               | Widget finished initializing                                       |
| `open`                   | --                                                               | Chat panel was opened                                              |
| `close`                  | --                                                               | Chat panel was closed                                              |
| `error`                  | `{ message, code? }`                                             | An error occurred                                                  |
| `message:sent`           | `{ content, timestamp }`                                         | The visitor sent a message                                         |
| `message:received`       | `{ content, timestamp }`                                         | The assistant sent a response                                      |
| `conversation:started`   | `{ conversationId }`                                             | A new conversation was initiated                                   |
| `session:created`        | `{ sessionId, visitorId }`                                       | A new session was created                                          |
| `session:restored`       | `{ sessionId, visitorId }`                                       | An existing session was restored                                   |
| `lead:submitted`         | `{ contactId, isNew }`                                           | The lead plugin submitted a contact                                |
| `form:submitted`         | `{ formId, data }`                                               | The active lead, ticket, or custom form was submitted successfully |
| `form:error`             | `{ error }`                                                      | The active form submission failed with a visitor-safe error        |
| `form:hide`              | --                                                               | The active form was closed                                         |
| `live_chat:started`      | `{ sessionId, agentName, agentId }`                              | A live-support session was assigned                                |
| `live_chat:message`      | `{ sessionId, content, senderType, senderName?, senderAvatar? }` | A live-support message was delivered                               |
| `live_chat:queue_update` | `{ sessionId, position }`                                        | The visitor's queue position changed                               |
| `live_chat:ended`        | `{ sessionId, endedBy }`                                         | The live-support session ended                                     |

### Event Examples

**Track conversations in analytics:**

```javascript theme={null}
widget.on('conversation:started', ({ conversationId }) => {
  analytics.track('Chat Started', { conversationId });
});

widget.on('message:sent', ({ content }) => {
  analytics.track('Chat Message Sent', { content });
});
```

**Capture leads and forward to a CRM:**

```javascript theme={null}
widget.on('lead:submitted', ({ contactId, isNew }) => {
  analytics.track('Lead Captured', { contactId, isNew });
});
```

**Handle errors:**

```javascript theme={null}
widget.on('error', ({ message, code }) => {
  console.error('Widget error:', code, message);
  document.getElementById('fallback-support').style.display = 'block';
});
```

**Observe forms and live support:**

```javascript theme={null}
widget.on('form:submitted', ({ formId, data }) => {
  analytics.track('Widget Form Submitted', { formId, fieldCount: Object.keys(data).length });
});

widget.on('live_chat:started', ({ sessionId, agentName }) => {
  analytics.track('Live Support Started', { sessionId, agentName });
});
```

## Production capability notes

* Text messages, forms, quick-reply actions, and live-support lifecycle events
  are supported by the production v2 experience.
* Attachments and browser voice input are fast-follow composer capabilities.
  Do not use SDK configuration to infer that those controls are visible.
* The plugin registration API remains available for compatibility and host-side
  lifecycle integrations. Plugin-rendered widget UI is a fast-follow v2
  capability and should not be treated as generally available.

## Configuration Reference

```typescript theme={null}
interface WidgetConfig {
  assistantId: string;
  position?: 'bottom-right' | 'bottom-left';
  authMode?: 'anonymous' | 'authenticated' | 'auto';
  branding?: {
    primaryColor?: string;    // Default: "#6366f1"
    companyName?: string;
    launcherSize?: number;    // Default: 60
  };
  autoOpen?: number;          // Delay in ms, 0 to disable
  suggestedMessages?: string[];
  popupMessages?: string[];   // Teaser bubbles above the launcher
  suggestedMessagesBubbles?: {
    enabled?: boolean;        // Default: false (dashboard toggle overrides)
    delay?: number;           // Default: 3000
  };
  metadata?: Record<string, string | number | boolean>;
  session?: {
    persist?: boolean;        // Default: true
  };
  debug?: boolean;            // Default: false
}
```

## TypeScript Declarations

```typescript theme={null}
declare global {
  interface Window {
    IllumiChat: {
      Widget: new (config: WidgetConfig) => WidgetInstance;
      getInstance: () => WidgetInstance | null;
      destroyInstance: () => void;
      VERSION: string;
    };
  }
}

interface WidgetInstance {
  initialize(): Promise<void>;
  open(): void;
  close(): void;
  toggle(): void;
  sendMessage(text: string): void;
  getState(): string;
  getConfig(): object;
  destroy(): void;
  on(event: string, handler: Function): () => void;
  once(event: string, handler: Function): () => void;
  off(event: string, handler: Function): void;
}
```

## Troubleshooting

| Problem                             | Likely Cause               | Solution                                                |
| ----------------------------------- | -------------------------- | ------------------------------------------------------- |
| `IllumiChat is not defined`         | SDK script not loaded yet  | Wait for the `load` event or check script URL           |
| `getInstance()` returns `null`      | No widget initialized      | Call `new IllumiChat.Widget(config).initialize()` first |
| `open()` has no effect              | Widget not yet initialized | Await `initialize()` or listen for `ready` event        |
| Widget appears but does not respond | Incorrect assistant ID     | Verify the ID in your assistant's Widget settings       |
| Console shows CORS errors           | Domain not authorized      | Add your domain to the widget's allowed domains list    |
| Multiple launcher buttons           | Widget initialized twice   | Call `destroyInstance()` before creating a new instance |
