@spectrumsense/spectrum-chat-dev
Version:
Embeddable AI Widget - Add trusted, evidence-based answers directly to your website. Simple installation, enterprise-grade security.
916 lines (670 loc) • 20.9 kB
Markdown
# Spectrum Chat API Reference
**Version:** 1.0
**Last Updated:** October 6, 2025
---
## Table of Contents
1. [Widget Configuration](#widget-configuration)
2. [Custom Element API](#custom-element-api)
3. [Global Mode API](#global-mode-api)
4. [Security Functions](#security-functions)
5. [Event System](#event-system)
6. [Storage Keys](#storage-keys)
7. [Error Types](#error-types)
8. [TypeScript Definitions](#typescript-definitions)
---
## Widget Configuration
### Configuration Options
All configuration options work in both custom element (as attributes) and global mode (as properties).
#### Required Options
| Option | Type | Description | Example |
|--------|------|-------------|---------|
| `api-url` / `apiUrl` | `string` | API endpoint URL | `https://api.example.com/api/v1/conversations` |
| `site-key` / `siteKey` | `string` | Public site key for origin validation | `pub_customer_a1b2c3d4` |
#### Security Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `use-jwt` / `useJWT` | `boolean` | `false` | Enable JWT session tokens (Phase 1) |
| `tenant-id` / `tenantId` | `string` | Optional | Legacy tenant ID (backward compatibility) |
#### Feature Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `citations` / `enableCitations` | `boolean` | `true` | Include source citations in responses |
| `title` | `string` | `'AI Assistant'` | Widget header title |
| `intro-text` / `introText` | `string` | Default message | Welcome message displayed on first open |
| `show-intro` / `showIntro` | `boolean` | `true` | Show intro message on first open |
#### Styling Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `primary-color` / `primaryColor` | `string` | `hsl(220 15% 25%)` | Primary theme color (header, buttons) |
| `user-color` / `userColor` | `string` | `hsl(220 15% 45%)` | User message bubble color |
| `ai-color` / `aiColor` | `string` | `hsl(220 15% 25%)` | AI message bubble color |
| `fab-icon` / `fabIcon` | `string` | `'✦'` | Floating action button icon (emoji or text) |
| `fab-color` / `fabColor` | `string` | `hsl(220 15% 25%)` | FAB background color |
| `position` | `string` | `'bottom-right'` | Widget position (`bottom-right`, `bottom-left`, `top-right`, `top-left`) |
| `width` | `string` | `'320px'` | Widget panel width |
| `height` | `string` | `'350px'` | Widget panel height |
| `panel-border-radius` / `panelBorderRadius` | `string` | `'1rem'` | Border radius of widget panel |
| `panel-shadow` / `panelShadow` | `string` | Default shadow | Box shadow for widget panel |
#### Advanced Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `debug` | `boolean` | `false` | Enable debug console logging |
| `max-messages` / `maxMessages` | `number` | `100` | Maximum messages in browser storage |
| `browser-storage` / `browserStorage` | `boolean` | `false` | Use DeepChat's browser storage |
| `custom-styles` / `customStyles` | `string` | `'{}'` | JSON string of custom DeepChat styles |
| `enable-response-interceptor` / `enableResponseInterceptor` | `boolean` | `true` | Enable response processing (citations, etc.) |
---
## Custom Element API
### Basic Usage
```html
<spectrum-chat
api-url="https://api.example.com/api/v1/conversations"
site-key="pub_customer_a1b2c3d4"
title="Help Center">
</spectrum-chat>
```
### Methods
#### `open()`
Opens the chat widget panel.
```javascript
const widget = document.querySelector('spectrum-chat');
widget.open();
```
#### `close()`
Closes the chat widget panel.
```javascript
const widget = document.querySelector('spectrum-chat');
widget.close();
```
#### `isChatOpen()`
Returns whether the chat panel is currently open.
**Returns:** `boolean`
```javascript
const widget = document.querySelector('spectrum-chat');
console.log(widget.isChatOpen()); // true or false
```
#### `updateConfig(newConfig)`
Updates widget configuration dynamically.
**Parameters:**
- `newConfig` (object): New configuration values
```javascript
const widget = document.querySelector('spectrum-chat');
widget.updateConfig({
title: 'Customer Support',
primaryColor: '#2563eb'
});
```
#### `refreshStyles()`
Refreshes message bubble styles (useful after color changes).
```javascript
const widget = document.querySelector('spectrum-chat');
widget.refreshStyles();
```
#### `hideIntro()`
Manually hides the intro message.
```javascript
const widget = document.querySelector('spectrum-chat');
widget.hideIntro();
```
### Events
#### `spectrum-chat-opened`
Fired when the chat panel is opened.
```javascript
const widget = document.querySelector('spectrum-chat');
widget.addEventListener('spectrum-chat-opened', (event) => {
console.log('Chat opened!');
});
```
#### `spectrum-chat-closed`
Fired when the chat panel is closed.
```javascript
const widget = document.querySelector('spectrum-chat');
widget.addEventListener('spectrum-chat-closed', (event) => {
console.log('Chat closed!');
});
```
---
## Global Mode API
### Basic Usage
```javascript
window.SpectrumChatConfig = {
apiUrl: 'https://api.example.com/api/v1/conversations',
siteKey: 'pub_customer_a1b2c3d4',
useJWT: true,
title: 'Help Center'
};
```
### `SpectrumChatGlobal` Object
The global API is available at `window.SpectrumChatGlobal`.
### Configuration Methods
#### `getConfig()`
Gets current widget configuration.
**Returns:** `object` - Current configuration
```javascript
const config = SpectrumChatGlobal.getConfig();
console.log(config);
```
#### `updateConfig(newConfig)`
Updates widget configuration and reinitializes if needed.
**Parameters:**
- `newConfig` (object): New configuration values
```javascript
SpectrumChatGlobal.updateConfig({
title: 'Customer Support',
primaryColor: '#2563eb',
useJWT: true
});
```
### Widget Control Methods
#### `open()`
Opens the chat widget panel.
```javascript
SpectrumChatGlobal.open();
```
#### `close()`
Closes the chat widget panel.
```javascript
SpectrumChatGlobal.close();
```
#### `isOpen()`
Returns whether the chat panel is currently open.
**Returns:** `boolean`
```javascript
console.log(SpectrumChatGlobal.isOpen()); // true or false
```
#### `getWidget()`
Gets the DOM element of the widget.
**Returns:** `HTMLElement | null`
```javascript
const widgetElement = SpectrumChatGlobal.getWidget();
console.log(widgetElement);
```
### Session Management Methods
#### `getConversationId()`
Gets the current conversation ID.
**Returns:** `string | null`
```javascript
const conversationId = SpectrumChatGlobal.getConversationId();
console.log('Conversation ID:', conversationId); // "c_abc123..."
```
#### `getSessionId()`
Gets the current JWT session ID (Phase 1 only).
**Returns:** `string | null`
```javascript
const sessionId = SpectrumChatGlobal.getSessionId();
console.log('Session ID:', sessionId); // "550e8400-e29b..."
```
#### `getTokenData()`
Gets the complete JWT token data (Phase 1 only).
**Returns:** `object | null`
```javascript
const tokenData = SpectrumChatGlobal.getTokenData();
console.log(tokenData);
// {
// token: "eyJhbGciOiJI...",
// session_id: "550e8400-e29b...",
// expires_at: "2025-10-06T13:00:00Z"
// }
```
#### `isTokenValid()`
Checks if the current JWT token is valid (Phase 1 only).
**Returns:** `boolean`
```javascript
const isValid = SpectrumChatGlobal.isTokenValid();
console.log('Token valid:', isValid); // true or false
```
#### `initializeSession()`
Manually initializes or refreshes the JWT session (Phase 1 only).
**Returns:** `Promise<object | null>`
```javascript
try {
const tokenData = await SpectrumChatGlobal.initializeSession();
console.log('Session initialized:', tokenData);
} catch (error) {
console.error('Failed to initialize session:', error);
}
```
#### `clearSession()`
Clears the current session (conversation ID, JWT token, and messages).
```javascript
SpectrumChatGlobal.clearSession();
console.log('Session cleared');
```
### Lifecycle Methods
#### `reinitialize()`
Reinitializes the entire widget (removes and recreates).
```javascript
SpectrumChatGlobal.reinitialize();
```
---
## Security Functions
These functions are used internally but can be accessed for advanced use cases.
### `hashPageUrl()`
Generates SHA256 hash of current page URL.
**Returns:** `Promise<string>`
```javascript
const hash = await hashPageUrl();
console.log('Page URL hash:', hash);
```
### `generateNonce()`
Generates a UUID v4 nonce for request tracking.
**Returns:** `string`
```javascript
const nonce = generateNonce();
console.log('Nonce:', nonce); // "550e8400-e29b-41d4-a716-446655440000"
```
### `isTokenValid(tokenData)`
Checks if a JWT token is valid (not expired, with 5-minute buffer).
**Parameters:**
- `tokenData` (object): Token data with `expires_at` property
**Returns:** `boolean`
```javascript
const tokenData = {
token: "...",
session_id: "...",
expires_at: "2025-10-06T13:00:00Z"
};
const isValid = isTokenValid(tokenData);
console.log('Token valid:', isValid);
```
### `createSession(config)`
Creates a new JWT session (Phase 1).
**Parameters:**
- `config` (object): Configuration with `apiUrl` and `siteKey`
**Returns:** `Promise<object>`
```javascript
try {
const tokenData = await createSession({
apiUrl: 'https://api.example.com/api/v1/conversations',
siteKey: 'pub_customer_a1b2c3d4',
debug: true
});
console.log('Session created:', tokenData);
} catch (error) {
console.error('Failed to create session:', error);
}
```
### `handleApiError(error)`
Translates technical API errors to user-friendly messages.
**Parameters:**
- `error` (object): Error object or response
**Returns:** `object` - Formatted error with `text` and `error` properties
```javascript
try {
// ... API call
} catch (error) {
const userError = handleApiError(error);
console.log('User message:', userError.text);
console.log('Error code:', userError.error);
}
```
---
## Event System
### Custom Element Events
Events dispatched by the `<spectrum-chat>` custom element:
#### `spectrum-chat-opened`
Dispatched when the chat panel opens.
```javascript
document.querySelector('spectrum-chat').addEventListener('spectrum-chat-opened', () => {
console.log('Chat opened');
// Track analytics
// Update UI
});
```
#### `spectrum-chat-closed`
Dispatched when the chat panel closes.
```javascript
document.querySelector('spectrum-chat').addEventListener('spectrum-chat-closed', () => {
console.log('Chat closed');
// Track analytics
// Update UI
});
```
### Global Mode Events
Events dispatched on `document` in global mode:
#### `spectrum-chat-opened`
```javascript
document.addEventListener('spectrum-chat-opened', (event) => {
console.log('Chat opened:', event.detail);
// event.detail = { isOpen: true }
});
```
#### `spectrum-chat-closed`
```javascript
document.addEventListener('spectrum-chat-closed', (event) => {
console.log('Chat closed:', event.detail);
// event.detail = { isOpen: false }
});
```
### DeepChat Events
The underlying DeepChat component also fires events:
#### `message`
Fired when user sends a message.
```javascript
const widget = document.querySelector('spectrum-chat');
const deepChat = widget.shadowRoot.querySelector('deep-chat');
deepChat.addEventListener('message', (event) => {
console.log('User message:', event.detail);
});
```
#### `response`
Fired when AI responds.
```javascript
deepChat.addEventListener('response', (event) => {
console.log('AI response:', event.detail);
});
```
---
## Storage Keys
The widget uses `sessionStorage` (default) or `localStorage` for persistence.
### Storage Keys
| Key | Type | Description |
|-----|------|-------------|
| `spectrum-chat-conversation-id` | `string` | Current conversation ID |
| `spectrum-chat-token` | `string` (JSON) | JWT token data (Phase 1 only) |
| `spectrum-chat-messages` | `string` (JSON) | Message history (global mode only) |
### Token Data Structure
```javascript
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"expires_at": "2025-10-06T13:00:00Z"
}
```
### Message Data Structure
```javascript
[
{
"text": "Hello, how can I help?",
"role": "assistant",
"timestamp": 1696000000000
},
{
"text": "I need help with returns",
"role": "user",
"timestamp": 1696000005000
}
]
```
### Accessing Storage
```javascript
// Get conversation ID
const conversationId = sessionStorage.getItem('spectrum-chat-conversation-id');
// Get token data
const tokenDataStr = sessionStorage.getItem('spectrum-chat-token');
const tokenData = tokenDataStr ? JSON.parse(tokenDataStr) : null;
// Get messages
const messagesStr = sessionStorage.getItem('spectrum-chat-messages');
const messages = messagesStr ? JSON.parse(messagesStr) : [];
// Clear storage
sessionStorage.removeItem('spectrum-chat-conversation-id');
sessionStorage.removeItem('spectrum-chat-token');
sessionStorage.removeItem('spectrum-chat-messages');
```
---
## Error Types
### Error Response Structure
```typescript
{
text: string; // User-friendly error message
role: string; // Always "assistant"
error: string; // Error code/type
sources?: null; // Always null for errors
}
```
### Error Codes
| Error Code | HTTP Status | Description | User Message |
|------------|-------------|-------------|--------------|
| `network_error` | N/A | Network/connection failure | "Unable to connect to chat service..." |
| `origin_not_allowed` | 403 | Domain not in allowed list | "This domain is not authorized..." |
| `https_required` | 403 | HTTP used in production | "This chat service requires HTTPS..." |
| `origin_mismatch` | 403 | Origin doesn't match conversation | "Session security error..." |
| `forbidden` | 403 | Generic forbidden error | "Access denied. Contact support." |
| `conversation_expired` | 404 | Conversation not in cache | "Conversation expired. Starting new..." |
| `invalid_site_key` | 404 | Site key invalid/disabled | "Chat service is unavailable." |
| `token_expired` | 401 | JWT token expired | "Session expired. Please try again." |
| `moderation_flagged` | 200 | Content flagged | Custom message from API |
| `server_error` | 500+ | Server error | "An error occurred. Try again later." |
| `unknown_error` | Any | Unexpected error | "An unexpected error occurred..." |
### Error Handling Example
```javascript
// Custom element
const widget = document.querySelector('spectrum-chat');
const deepChat = widget.shadowRoot.querySelector('deep-chat');
deepChat.addEventListener('response', (event) => {
const response = event.detail;
if (response.error) {
console.error('Error type:', response.error);
console.log('User message:', response.text);
// Handle specific errors
switch (response.error) {
case 'origin_not_allowed':
// Contact admin to add domain
break;
case 'token_expired':
// Token will auto-refresh and retry
break;
case 'conversation_expired':
// New conversation will start automatically
break;
}
}
});
```
---
## TypeScript Definitions
### Configuration Types
```typescript
interface SpectrumChatConfig {
// Required
apiUrl: string;
siteKey: string;
// Security
useJWT?: boolean;
tenantId?: string;
// Features
enableCitations?: boolean;
title?: string;
introText?: string;
showIntro?: boolean;
// Styling
primaryColor?: string;
userColor?: string;
aiColor?: string;
fabIcon?: string;
fabColor?: string;
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
width?: string;
height?: string;
panelBorderRadius?: string;
panelShadow?: string;
// Advanced
debug?: boolean;
maxMessages?: number;
browserStorage?: boolean;
customStyles?: string;
enableResponseInterceptor?: boolean;
}
```
### Token Data Types
```typescript
interface TokenData {
token: string;
session_id: string;
expires_at: string; // ISO 8601 timestamp
}
```
### Response Types
```typescript
interface ConversationResponse {
text: string;
role: 'assistant' | 'user';
conversation_id?: string;
sources?: Source[] | null;
error?: string | null;
}
interface Source {
index: number;
title: string;
url: string;
}
```
### Error Response Types
```typescript
interface ErrorResponse {
text: string; // User-friendly message
error: string; // Error code
}
type ErrorCode =
| 'network_error'
| 'origin_not_allowed'
| 'https_required'
| 'origin_mismatch'
| 'forbidden'
| 'conversation_expired'
| 'invalid_site_key'
| 'token_expired'
| 'moderation_flagged'
| 'server_error'
| 'unknown_error';
```
### Global API Types
```typescript
interface SpectrumChatGlobal {
// Configuration
getConfig(): SpectrumChatConfig;
updateConfig(config: Partial<SpectrumChatConfig>): void;
// Widget control
open(): void;
close(): void;
isOpen(): boolean;
getWidget(): HTMLElement | null;
// Session management
getConversationId(): string | null;
getSessionId(): string | null;
getTokenData(): TokenData | null;
isTokenValid(): boolean;
initializeSession(): Promise<TokenData | null>;
clearSession(): void;
// Lifecycle
reinitialize(): void;
}
```
### Custom Element Types
```typescript
interface SpectrumChatElement extends HTMLElement {
// Methods
open(): void;
close(): void;
isChatOpen(): boolean;
updateConfig(config: Partial<SpectrumChatConfig>): void;
refreshStyles(): void;
hideIntro(): void;
// Properties
shadowRoot: ShadowRoot;
}
```
---
## Usage Examples
### Example 1: Basic Integration
```html
<spectrum-chat
api-url="https://api.example.com/api/v1/conversations"
site-key="pub_customer_a1b2c3d4"
title="Help Center">
</spectrum-chat>
```
### Example 2: With JWT and Custom Styling
```html
<script>
window.SpectrumChatConfig = {
apiUrl: 'https://api.example.com/api/v1/conversations',
siteKey: 'pub_customer_a1b2c3d4',
useJWT: true,
title: 'Customer Support',
primaryColor: '#2563eb',
userColor: '#3b82f6',
aiColor: '#2563eb',
fabIcon: '💬',
enableCitations: true
};
</script>
<script src="https://unpkg.com/@spectrumsense/spectrum-chat@latest/dist/spectrum-chat.js"></script>
```
### Example 3: Programmatic Control
```javascript
// Wait for widget to load
document.addEventListener('DOMContentLoaded', () => {
const chat = SpectrumChatGlobal;
// Check status
console.log('Token valid:', chat.isTokenValid());
console.log('Conversation ID:', chat.getConversationId());
// Open on button click
document.getElementById('help-btn').addEventListener('click', () => {
chat.open();
});
// Clear on logout
document.getElementById('logout-btn').addEventListener('click', () => {
chat.clearSession();
});
// Monitor state
document.addEventListener('spectrum-chat-opened', () => {
console.log('Chat opened');
// Track analytics
});
});
```
### Example 4: Error Handling
```javascript
const widget = document.querySelector('spectrum-chat');
const deepChat = widget.shadowRoot.querySelector('deep-chat');
deepChat.addEventListener('response', (event) => {
const response = event.detail;
if (response.error) {
console.error('Error:', response.error);
// Custom error handling
if (response.error === 'origin_not_allowed') {
alert('Please contact support to enable chat on this domain.');
}
} else {
console.log('Response:', response.text);
// Display citations if available
if (response.sources && response.sources.length > 0) {
console.log('Sources:', response.sources);
}
}
});
```
---
## Browser Compatibility
### Required Features
- ✅ Web Crypto API (for SHA256 hashing)
- ✅ sessionStorage / localStorage
- ✅ Fetch API
- ✅ ES6+ JavaScript (arrow functions, const/let, async/await)
- ✅ Custom Elements v1
- ✅ Shadow DOM
### Supported Browsers
- ✅ Chrome 88+
- ✅ Firefox 85+
- ✅ Safari 14+
- ✅ Edge 88+
- ✅ Opera 74+
### Polyfills
For older browsers, you may need polyfills:
```html
<!-- Custom Elements polyfill -->
<script src="https://unpkg.com/@webcomponents/custom-elements@1.5.0/custom-elements.min.js"></script>
<!-- Fetch polyfill -->
<script src="https://unpkg.com/whatwg-fetch@3.6.2/dist/fetch.umd.js"></script>
```
---
## Support
For questions or issues:
- 📚 Documentation: [SECURITY_IMPLEMENTATION.md](./SECURITY_IMPLEMENTATION.md)
- 📚 Migration: [MIGRATION_GUIDE.md](./MIGRATION_GUIDE.md)
- 🔧 Debug: Enable `debug="true"` in widget
- 📧 Support: support@spectrumsense.com
---
**Last Updated:** October 6, 2025
**Version:** 1.0.0