Quick Start
Get your EchoAI assistant running in under 2 minutes with these simple steps.
Include the EchoAI SDK script in your HTML file before the closing </body> tag.
<script src="https://cdn.echoaichat.com/sdk/echo-sdk.js"></script> Create a new EchoSDK instance with your assistant identifier.
const echoWidget = new EchoSDK({
container: '#echo-chat',
assistantIdentifier: 'dovjmm372762'
}); #echo-chat.
Installation
Complete HTML example to get you started quickly.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Website</title>
</head>
<body>
<!-- Your website content -->
<!-- EchoAI Chat Container -->
<div id="echo-chat" style="height: 500px;"></div>
<!-- EchoAI SDK -->
<script src="https://cdn.echoaichat.com/sdk/echo-sdk.js"></script>
<script>
const echoWidget = new EchoSDK({
container: '#echo-chat',
assistantIdentifier: 'dovjmm372762',
height: '100%'
});
</script>
</body>
</html> Live Preview
Configure the widget options below and see changes in real time. The generated code updates automatically.
No-code Data Attributes
You don't have to write any JavaScript. If the SDK script finds an element with the data-echo-container attribute, it auto-initializes from the element's data-echo-* attributes and exposes the instance as window.echoInstance.
<!-- The SDK auto-initializes from this element. No JavaScript needed. -->
<div
data-echo-container
data-echo-assistant-identifier="dovjmm372762"
data-echo-height="500px"
data-echo-theme="pink"
data-echo-auto-focus="true"
data-echo-text-input-placeholder="Ask me anything..."
></div>
<script src="https://cdn.echoaichat.com/sdk/echo-sdk.js"></script> The same approach works for a floating button.
<!-- Floating button via data attributes -->
<div
data-echo-container
data-echo-assistant-identifier="dovjmm372762"
data-echo-floating-enabled="true"
data-echo-floating-position="bottom_right"
data-echo-floating-tooltip="Chat with us!"
></div>
<script src="https://cdn.echoaichat.com/sdk/echo-sdk.js"></script> data-echo-container. For multiple widgets on one page, use the JavaScript constructor (new EchoSDK(...)) for each. The full attribute list is in the Data Attribute Reference below.
Core Options
Essential configuration options for your EchoAI widget.
| Option | Type | Description |
|---|---|---|
container Required | string | Element | CSS selector or DOM element where the chat will be mounted |
assistantIdentifier Required | string | Your unique assistant identifier from the EchoAI dashboard |
height Optional | string | number | Widget height (e.g., "500px", "100%", 500) |
autoFocus Optional | boolean | Auto-focus input field on load. Default: true |
theme Optional | string | Color theme: pink (default), purple, blue, green, amber. Invalid or absent values fall back to pink. |
mode Optional | 'full' | 'preview' | Desktop only: 'preview' shows a welcome screen with starter questions and a start button. Mobile always uses preview. See Display Modes. |
header Optional | object | { enabled: boolean } — show a header bar. Off by default for embedded; always on for the floating button. |
userContext Optional | string | Additional context about the user (max 1000 chars). See User Context. |
urlContextOptions Optional | object | Pass the current page URL to the AI. See URL Context. |
starterQuestions NEW | Array | Override default starter questions (max 5). See Starter Questions. |
floatingButton Optional | object | Render as a floating launcher instead of an inline widget. See Floating Button. |
textConfig Optional | object | Customize UI strings. See Text Customization. |
onError Optional | function | Error callback: (error: Error) => void |
Text Customization
Customize UI text with the textConfig option.
JavaScript const echoWidget = new EchoSDK({
container: '#echo-chat',
assistantIdentifier: 'dovjmm372762',
textConfig: {
inputPlaceholder: 'Ask me anything...',
sourcesLabel: 'Knowledge Sources',
searchingText: 'Searching...',
toolsText: 'Processing...',
loadingText: 'Thinking...'
}
});
Property Type Description inputPlaceholder string Placeholder text for the input field sourcesLabel string Label for knowledge sources section searchingText string Text shown while searching toolsText string Text shown while processing tools loadingText string Text shown while loading response startButtonLabel string Label for the start button in preview mode (default: Start chat)
Starter Questions
Override default starter questions to customize the initial chat experience.
What are Starter Questions?
Starter questions appear when users first open the chat, providing quick conversation starters. Override them via the SDK for page-specific customization.
Basic Usage
JavaScript const echoWidget = new EchoSDK({
container: '#echo-chat',
assistantIdentifier: 'dovjmm372762',
starterQuestions: [
{ question: 'What are your pricing plans?' },
{ question: 'How do I get started?' },
{ question: 'Can I see a demo?' }
]
});
Behavior
- Maximum 5 questions — Additional questions are ignored
- Max 200 characters — Longer text is truncated
- Empty array
[] — Hides all starter questions - Undefined — Uses default questions from dashboard
Page-Specific Example
JavaScript // Dynamic questions based on current page
function getStarterQuestions() {
const path = window.location.pathname;
if (path.includes('/pricing')) {
return [
{ question: 'Compare pricing plans' },
{ question: 'Do you offer discounts?' },
{ question: "What's included in each plan?" }
];
}
if (path.includes('/docs')) {
return [
{ question: 'How do I install the SDK?' },
{ question: 'Show me code examples' }
];
}
// Use dashboard defaults
return undefined;
}
const echoWidget = new EchoSDK({
container: '#echo-chat',
assistantIdentifier: 'dovjmm372762',
starterQuestions: getStarterQuestions()
});
Note
SDK-provided questions override dashboard settings. Changes in your dashboard won't affect pages using overrides.
User Context
Pass metadata about the current user or session to the AI assistant. The context is injected into the AI's system prompt, enabling personalized responses without users repeating information.
How it works
The AI receives your context as known metadata and will use it to answer questions directly — without calling knowledge retrieval tools. For example, if you pass a user's plan tier, the AI can immediately answer "What plan am I on?" from context alone.
Plain Text
JavaScript const echoWidget = new EchoSDK({
container: '#echo-chat',
assistantIdentifier: 'dovjmm372762',
userContext: 'Company size: 50-100 employees, Industry: Healthcare, Plan: Pro'
});
JSON Format (Recommended)
For structured data, use JSON.stringify(). This gives the AI clearly labeled fields to reference.
JavaScript // Structured context with JSON (recommended)
const user = await fetchCurrentUser();
const echoWidget = new EchoSDK({
container: '#echo-chat',
assistantIdentifier: 'dovjmm372762',
userContext: JSON.stringify({
userId: user.id,
membershipTier: 'gold',
companySize: '50-100 employees',
accountAge: '2 years',
cartItems: 3,
rewardPoints: 1250
})
});
Dynamic Context
Build context from your application state at initialization time.
JavaScript // Dynamic context based on application state
function buildContext() {
const user = getCurrentUser();
const cart = getCartState();
return JSON.stringify({
name: user.firstName,
plan: user.subscription.plan,
cartTotal: cart.total,
itemCount: cart.items.length,
preferredLanguage: user.locale
});
}
const echoWidget = new EchoSDK({
container: '#echo-chat',
assistantIdentifier: 'dovjmm372762',
userContext: buildContext()
});
Limits & Rules
Aspect Detail Max length 1000 characters — exceeding throws an error Type String only (plain text or JSON) Scope Per conversation thread — set at creation, cannot be updated mid-conversation Validation Enforced both client-side (SDK) and server-side (API)
Best Practices
Do - Use identifiers instead of full names (
userId: "user_123") - Include non-sensitive metadata: plan tier, company size, preferences
- Use JSON format for structured data
- Only include data that improves AI responses
Don't - Include passwords, SSN, or credit card numbers
- Store highly sensitive PII
- Include data users wouldn't want the AI to know
- Pass API keys or credentials
URL Context
Give the AI awareness of the page the visitor is on, so it can ground answers in the current URL. Use urlContextOptions to enable auto-detection or pin a specific URL.
Current default: disabled autoDetect currently defaults to false. URL context is only sent when you explicitly set autoDetect: true or provide a customUrl. (This is a temporary default; the SDK will return to auto-detecting by default in a future release.)
JavaScript const echoWidget = new EchoSDK({
container: '#echo-chat',
assistantIdentifier: 'dovjmm372762',
urlContextOptions: {
// Pass the current page URL to the AI so it can ground answers in
// the page the visitor is looking at. Currently disabled by default.
autoDetect: true,
// Or pin a specific URL regardless of the actual page:
// customUrl: 'https://example.com/pricing'
}
});
Property Type Description autoDetect boolean When true, sends window.location.href as context. Default: false. customUrl string A specific URL to send instead of the actual page. Takes precedence over autoDetect.
Display Modes & Header
Control how the inline widget opens and whether it shows a header bar.
Preview mode
In preview mode the widget first shows a welcome screen with starter questions and a start button, instead of an open input. The visitor clicks the button to begin. On desktop this is opt-in; on mobile the chat always starts in preview.
JavaScript const echoWidget = new EchoSDK({
container: '#echo-chat',
assistantIdentifier: 'dovjmm372762',
mode: 'preview',
textConfig: {
startButtonLabel: 'Start chatting'
}
});
Header bar
The header is hidden by default for the embedded widget. Turn it on with header.enabled. The floating button always shows a header (with a close button).
JavaScript const echoWidget = new EchoSDK({
container: '#echo-chat',
assistantIdentifier: 'dovjmm372762',
header: {
enabled: true
}
});
Preview vs. floating
Preview mode is about the embedded widget's first screen. The floating button is a separate launcher that opens the full chat in a popup. For the in-product preview feature, see Preview Mode.
Programmatic Control
Hold a reference to the instance you create with new EchoSDK(...), or use window.echoInstance when the widget was auto-initialized from data attributes. The instance exposes these methods.
Method Signature Description resetThread (options?: { userContext?: string }) => Promise<boolean> Ends the current conversation and starts a fresh thread. Optionally sets new context for the new thread. Resolves to true on success. setUserContext (context: string | undefined) => void Updates the context used by the next new thread. Validated against the 1000-char limit. Context is fixed for a thread's lifetime, so call this before resetThread(). getUserContext () => string | undefined Returns the currently configured user context. update (options: EchoSDKOptions) => void Merges new options into the instance and re-renders (e.g. change theme or text on the fly). mount (container: string | HTMLElement) => boolean Mounts (or re-mounts) the widget into a container. Returns false if the container can't be found. unmount () => void Removes the widget and cleans up the DOM, the floating button, and event listeners.
Reset the conversation
JavaScript // Reset the conversation and start a fresh thread
await window.echoInstance.resetThread();
// Reset and set new context for the new thread at the same time
await window.echoInstance.resetThread({
userContext: 'Plan: Pro, just upgraded'
});
Update the user context
JavaScript // Update the context that the next new thread will use.
// Note: context is fixed for the lifetime of a thread — call this
// before resetThread() so the new thread picks up the change.
window.echoInstance.setUserContext('Plan: Pro, cart items: 3');
// Read back the current context
const ctx = window.echoInstance.getUserContext();
// Then start a new thread that uses it
await window.echoInstance.resetThread();
Update options on a live instance
JavaScript // Update options on a live instance (re-renders the widget)
window.echoInstance.update({
theme: 'blue',
textConfig: { inputPlaceholder: 'How can we help?' }
});
Mount and unmount
JavaScript // Remove the widget entirely (cleans up the DOM and listeners)
window.echoInstance.unmount();
// Re-mount it into a (new) container
window.echoInstance.mount('#echo-chat');
Events
The SDK dispatches custom events on window. Listen with window.addEventListener('echo:...', handler). The most useful for integrations are echo:error and echo:reset-thread; the rest support mobile keyboard and expand/minimize behavior.
JavaScript // Catch errors raised by the auto-initialized instance
window.addEventListener('echo:error', (event) => {
console.error('Echo error:', event.detail.error);
});
// React when the conversation is reset
window.addEventListener('echo:reset-thread', (event) => {
console.log('New thread started with context:', event.detail.userContext);
});
// Mobile: the on-screen keyboard opened or closed
window.addEventListener('echo:keyboard-state', (event) => {
console.log('Keyboard open:', event.detail.open);
});
Event Direction Detail / Purpose echo:error emitted detail.error — dispatched by the auto-initialized instance when an error occurs. echo:reset-thread emitted detail.userContext — fired when a new thread is started via resetThread(). echo:keyboard-state emitted detail.open — the on-screen keyboard opened/closed (mobile). echo:viewport-resized emitted The visual viewport changed size (mobile). echo:expanded emitted The chat expanded to full screen (mobile). echo:minimized emitted The chat returned from full screen (mobile). echo:request-expand listened Dispatch this to ask the chat to expand to full screen (mobile). echo:request-minimize listened Dispatch this to ask the chat to leave full screen (mobile).
Data Attribute Reference
Every data-echo-* attribute the auto-initializer reads from the data-echo-container element. Each maps to a constructor option of the same meaning.
Attribute Maps to Notes data-echo-container Required — Marks the element as the auto-init target and the mount container. data-echo-assistant-identifier assistantIdentifier Your assistant identifier from the dashboard. data-echo-title title Optional title. data-echo-description description Optional description. data-echo-height height e.g. 500px, 100%. data-echo-theme theme pink, purple, blue, green, amber. Invalid/absent → pink. data-echo-auto-focus autoFocus Only the string "true" enables it via attributes. data-echo-text-input-placeholder textConfig.inputPlaceholder Input placeholder text. data-echo-text-sources-label textConfig.sourcesLabel Knowledge Sources label. data-echo-text-searching textConfig.searchingText Searching text. data-echo-text-tools textConfig.toolsText Tools processing text. data-echo-text-loading textConfig.loadingText Loading text. data-echo-floating-enabled floatingButton.enabled Set to "true" for floating-button mode. data-echo-floating-position floatingButton.position bottom_right | bottom_left | top_right | top_left. data-echo-floating-icon floatingButton.icon Custom launcher icon URL. data-echo-floating-tooltip floatingButton.tooltip Tooltip on hover. data-echo-floating-badge floatingButton.badgeCount Parsed as an integer. data-echo-floating-width floatingButton.width Popup width. data-echo-floating-height floatingButton.height Popup height. data-echo-user-context userContext Max 1000 chars. data-echo-url-context-auto-detect urlContextOptions.autoDetect Any value other than "false" enables it (when the attribute is present). data-echo-url-context-custom-url urlContextOptions.customUrl Pin a specific URL. data-echo-starter-questions starterQuestions JSON array, e.g. [{"question":"..."}]. Max 5. data-echo-header-enabled header.enabled Present and not "false" → header on.
Code Examples
Common integration patterns for different use cases.
Embedded Widget
JavaScript const echoWidget = new EchoSDK({
container: '#echo-chat',
assistantIdentifier: 'dovjmm372762',
height: '600px',
autoFocus: true,
textConfig: {
inputPlaceholder: 'Ask me anything...',
sourcesLabel: 'References'
}
});
With User Context
JavaScript // Personalize based on logged-in user
const user = getCurrentUser();
const echoWidget = new EchoSDK({
container: '#echo-chat',
assistantIdentifier: 'dovjmm372762',
userContext: `Name: ${user.name}, Plan: ${user.plan}`,
starterQuestions: [
{ question: 'How do I upgrade my plan?' },
{ question: "What's new in my account?" }
]
});
Full Configuration
JavaScript const echoWidget = new EchoSDK({
container: '#echo-chat',
assistantIdentifier: 'dovjmm372762',
height: '100%',
autoFocus: true,
textConfig: {
inputPlaceholder: 'How can I help you today?',
sourcesLabel: 'Knowledge Sources',
searchingText: 'Searching...',
toolsText: 'Processing...',
loadingText: 'Generating response...'
},
userContext: 'Pro user, prefers detailed answers',
urlContextOptions: {
autoDetect: false
},
starterQuestions: [
{ question: "What's new this week?" },
{ question: 'Show me advanced features' },
{ question: 'API integration guide' }
],
onError: (error) => {
console.error('Echo SDK error:', error);
}
});
Troubleshooting
The most common integration issues and how to resolve them.
Symptom Likely cause Fix Widget doesn't appear Wrong assistantIdentifier, an internal (non-public) assistant, or the container element doesn't exist yet. Verify the identifier in the dashboard, make sure the assistant is the public type, and initialize after the container is in the DOM (script before </body>, or use the data-attribute auto-init). Container not found error The CSS selector passed to container matches nothing. Check the selector and that the element exists when new EchoSDK() runs. Listen for echo:error or pass an onError callback. Styles look wrong / clash with my site The widget is fully isolated in a Shadow DOM, so your page CSS can't reach inside it — and vice versa. This is by design. Use the theme option (and textConfig for labels) rather than trying to override styles from your page. Font looks different from my site The SDK loads its own font (Inter) inside the Shadow DOM for a consistent look. Expected behavior. The widget renders its own typography independent of the host page. Conversation persists across reloads (or won't reset) The thread ID is stored in localStorage so the conversation survives navigation. Call window.echoInstance.resetThread() to start a fresh conversation. This is intentional continuity, not a bug. userContext exceeds maximum length The context string is longer than 1000 characters. Trim the context. Prefer identifiers and compact JSON over long prose — see User Context. AI doesn't seem to know the current page URL context is disabled by default. Set urlContextOptions.autoDetect: true (or a customUrl) — see URL Context. SDK fails to load Network/CDN issue or a blocked request. Confirm the script URL is reachable and not blocked by a content-security policy or ad blocker. Handle failures gracefully with onError / echo:error.
Still stuck?
See the FAQ & troubleshooting hub, or the no-code Embedding on Website guide.