Raw markdown

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

OptionTypeRequiredDescription
chatbotKeystringYesYour public chatbot key (cbt_...)
apiUrlstringNoOverride 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:

EventFieldsDescription
deltacontent: stringNext token chunk from the AI
donemessage_id: number, credits_used: numberResponse complete
errormessage: string, code?: stringAn 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:

FieldTypeValues
typestring'name' | 'email' | 'custom'
questionstringThe question text
answerstringThe 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 } }