JavaScript SDK
@elaras/chat-sdk is a zero-dependency TypeScript SDK that wraps the Elaras Chat API. Use it when you want to build a completely custom chat UI without the widget.
Installation
npm install @elaras/chat-sdk
Quick start — streaming
import {ChatClient} from '@elaras/chat-sdk'; const client = new ChatClient({chatbotKey: 'cbt_your_key_here'}); const sessionId = client.getOrCreateSessionId(); for await (const event of client.stream(sessionId, 'What are your opening hours?')) { if (event.type === 'delta') { process.stdout.write(event.content); // stream tokens to the UI } else if (event.type === 'done') { console.log('\nCredits used:', event.credits_used); } else if (event.type === 'error') { console.error('Error:', event.message); } }
Creating a client
import {ChatClient} from '@elaras/chat-sdk'; const client = new ChatClient({ chatbotKey: 'cbt_your_key_here', // apiUrl defaults to 'https://api.elaras.ai' apiUrl: 'https://api.elaras.ai', });
Options
| Option | Type | Required | Description |
|---|---|---|---|
chatbotKey | string | Yes | Your public chatbot key (cbt_...) |
apiUrl | string | No | Override the API base URL. Defaults to https://api.elaras.ai |
Methods
getConfig()
Fetches the chatbot's public configuration — name, greeting, appearance settings, and lead capture setup. Called automatically by stream() if needed; you only need to call it directly if you want to read config values before starting a conversation.
const config = await client.getConfig(); console.log(config.name); // "Aria" console.log(config.greeting_message); // "Hi! How can I help?" console.log(config.collect_leads); // true console.log(config.appearance?.primary_color); // "#00C4A7"
Returns: ChatbotConfig
interface ChatbotConfig { id: string; name: string; avatar_url?: string | null; greeting_message: string | null; collect_leads: boolean; lead_prompt: string | null; appearance: { primary_color?: string; position?: 'bottom-right' | 'bottom-left'; bubble_text?: string; powered_by?: boolean; theme?: 'light' | 'dark' | 'auto'; } | null; triage_questions: { ask_name: { enabled: boolean; question: string }; ask_email: { enabled: boolean; question: string }; custom: { question: string }[]; } | null; }
stream(sessionId, message)
Sends a message and returns an async generator that yields streaming events as the AI responds. Uses a WebSocket connection for real-time token delivery.
for await (const event of client.stream(sessionId, 'Tell me about your plans.')) { switch (event.type) { case 'delta': // A new token arrived — append to the current message appendToUI(event.content); break; case 'done': // Response complete console.log('Message ID:', event.message_id); console.log('Credits used:', event.credits_used); break; case 'error': console.error('Error code:', event.code); console.error('Error message:', event.message); break; } }
Event types:
| Event | Fields | Description |
|---|---|---|
delta | content: string | Next token chunk from the AI |
done | message_id: number, credits_used: number | Response complete |
error | message: string, code?: string | An error occurred |
send(sessionId, message)
Sends a message and waits for the complete AI response synchronously (no streaming). Useful for server-side or simple integrations where you do not need real-time delivery.
const result = await client.send(sessionId, 'What are your prices?'); console.log(result.response); // Full AI response text console.log(result.message_id); // Database ID of the saved message console.log(result.credits_used); // Credits consumed
Returns:
interface CompletionResult { message_id: number; response: string; credits_used: number; }
getOrCreateSessionId()
Returns the current session UUID from localStorage, or generates a new one if none exists. Call this once when your chat component mounts.
const sessionId = client.getOrCreateSessionId(); // e.g. "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
The session ID is stored in localStorage under elaras_session_{chatbotKey} and persists across page reloads.
clearSessionId()
Removes the session UUID from localStorage, causing the next call to getOrCreateSessionId() to generate a fresh session. Use this for a "start over" button.
client.clearSessionId(); const freshSessionId = client.getOrCreateSessionId(); // New UUID
getSession(sessionId)
Fetches the session and its full message history from the API.
const session = await client.getSession(sessionId); for (const msg of session.messages) { console.log(`[${msg.role}] ${msg.content}`); }
Returns:
interface Session { session: string; // Session UUID messages: ChatMessage[]; } interface ChatMessage { id: number; session_id: string; role: 'user' | 'assistant' | 'system'; content: string; credits_used: number | null; feedback: 'up' | 'down' | null; created_at: string; }
clearSession(sessionId)
Deletes all messages in the session on the server. The session UUID remains valid — the next message will start a fresh conversation.
await client.clearSession(sessionId);
submitLead(sessionId, lead)
Associates an email address (and optional name) with the session. Triggers the lead.captured webhook event.
await client.submitLead(sessionId, { email: '[email protected]', name: 'Jordan', // optional });
submitTriage(sessionId, answers)
Submits pre-chat triage answers collected before the conversation begins.
await client.submitTriage(sessionId, [ {type: 'name', question: 'What is your name?', answer: 'Jordan'}, {type: 'email', question: 'What is your email?', answer: '[email protected]'}, {type: 'custom', question: 'What can we help you with?', answer: 'Billing question'}, ]);
Each answer has these fields:
| Field | Type | Values |
|---|---|---|
type | string | 'name' | 'email' | 'custom' |
question | string | The question text |
answer | string | The user's answer |
submitFeedback(messageId, rating)
Records thumbs-up or thumbs-down feedback for an AI response.
await client.submitFeedback(42, 'up'); // thumbs up await client.submitFeedback(42, 'down'); // thumbs down
Full example — streaming chat UI (vanilla JS)
import {ChatClient} from '@elaras/chat-sdk'; const client = new ChatClient({chatbotKey: 'cbt_your_key_here'}); const sessionId = client.getOrCreateSessionId(); const messagesEl = document.getElementById('messages')!; const inputEl = document.getElementById('input')! as HTMLInputElement; const sendBtn = document.getElementById('send')!; // Load history on mount const session = await client.getSession(sessionId); for (const msg of session.messages) { appendMessage(msg.role, msg.content); } sendBtn.addEventListener('click', async () => { const text = inputEl.value.trim(); if (!text) return; inputEl.value = ''; appendMessage('user', text); const aiEl = appendMessage('assistant', ''); for await (const event of client.stream(sessionId, text)) { if (event.type === 'delta') { aiEl.textContent += event.content; } else if (event.type === 'error') { aiEl.textContent = 'Something went wrong. Please try again.'; } } }); function appendMessage(role: 'user' | 'assistant', content: string): HTMLElement { const el = document.createElement('div'); el.className = `message message--${role}`; el.textContent = content; messagesEl.appendChild(el); messagesEl.scrollTop = messagesEl.scrollHeight; return el; }
Error handling
All methods throw a ChatError on non-2xx responses:
import {ChatClient, ChatError} from '@elaras/chat-sdk'; try { const result = await client.send(sessionId, 'Hello'); } catch (err) { if (err instanceof ChatError) { console.error(err.message); // Human-readable message console.error(err.code); // Error code (if provided) console.error(err.status); // HTTP status code } }
