API reference
Chatoshi
The main class. One instance manages one chat.
const chat = new Chatoshi({
partnerKey: 'your-partner-key',
container: '#chat-container'
});
Constructor
new Chatoshi(options: ChatoshiInitOptions)
Throws if partnerKey is missing, or if mode is 'default' and no container was provided. See Errors below.
Methods
on(eventName, callback)
Subscribes to an event. Returns the instance, so calls can be chained.
chat.on('app:ready', () => console.log('ready'))
.on('popup:open', () => console.log('opened'));
off(eventName, callback?)
Removes a specific listener, or all listeners for the event when no callback is given. Chainable.
const handler = () => console.log('opened');
chat.on('popup:open', handler);
chat.off('popup:open', handler);
chat.off('popup:open');
open() / close() / toggle()
Open, close, or toggle the popup or drawer. Only meaningful in those modes.
sendMessage(message, requestId?)
Sends a message as if the user typed it. requestId is an arbitrary string echoed back in message:send:response, so you can correlate the reply. Queued until app:ready if the chat hasn't loaded yet.
const requestId = `order-${Date.now()}`;
chat.sendMessage('What is the BTC price?', requestId);
chat.on('message:send:response', (data) => {
if (data.requestId === requestId && data.success) {
console.log('Delivered, session:', data.sessionId);
}
});
newConversation(message?, requestId?)
Starts a fresh conversation, discarding the current one. With a message, it's sent as the first message. Queued like sendMessage().
chat.newConversation();
chat.on('session:new:response', (data) => {
if (!data.success) {
console.error('Failed to start conversation:', data.error);
}
});
getPopup()
Returns the Popup instance in popup mode, otherwise null.
getDrawer()
Returns the Drawer instance in drawer mode, otherwise null.
getWidget()
Returns the widget instance for the current mode, otherwise null. Useful when you need widget-level APIs without checking the mode first.
isReady()
Returns whether the instance has been initialized (the iframe created). For "the chat app is ready to talk", listen to the app:ready event instead.
destroy()
Tears down the chat: removes all DOM elements, the iframe, and every event listener.
Popup
Accessed via chat.getPopup() in popup mode.
| Method | Description |
|---|---|
open() | Opens the popup |
close() | Closes the popup |
toggle() | Toggles the popup |
isOpen() | Whether the popup is currently open |
getElements() | DOM elements the popup created: { popupWrapper, toggleWrapper } |
destroy() | Removes the popup from the DOM |
Drawer
Accessed via chat.getDrawer() in drawer mode.
| Method | Description |
|---|---|
open() | Opens the drawer |
close() | Closes the drawer |
toggle() | Toggles the drawer |
isOpen() | Whether the drawer is currently open |
getElements() | DOM elements the drawer created: { drawerWrapper, drawerOverlay } |
destroy() | Removes the drawer from the DOM |
Events
Subscribe with on().
Lifecycle
app:ready: the chat app finished loading. Messages queued before this point are delivered now.
chat.on('app:ready', () => console.log('ready'));
Messages
message:sent: the user submitted a message.
interface MessageSentPayload {
chatId: string;
personality: string;
characterCount: number;
}
message:received: the AI response fully arrived.
interface MessageReceivedPayload {
chatId: string;
personality: string;
}
session:new:response: the app acknowledged newConversation().
message:send:response: the app acknowledged sendMessage().
Both share this payload:
interface ActionResponsePayload {
requestId?: string;
success: boolean;
sessionId?: string;
error?: string;
}
Popup and drawer
popup:open, drawer:open: fired with { firstOpened: boolean } when the widget opens. firstOpened is true the first time it opens.
popup:close, drawer:close: fired when the widget closes.
Types
ChatoshiInitOptions
interface ChatoshiInitOptions {
partnerKey: string;
container?: HTMLElement | string;
containerStyle?: Record<string, string | number>;
containerClass?: string | string[];
mode?: 'default' | 'full' | 'popup' | 'drawer' | 'core';
theme?: 'light' | 'dark' | 'system';
popupOptions?: PopupOptions;
drawerOptions?: DrawerOptions;
splashScreen?: boolean | { customHTML?: string | HTMLElement };
colors?: IColorOptions | { default?: IColorOptions; dark?: IColorOptions };
customLogo?: string | { dark: string; light: string };
customView?: boolean;
transparent?: boolean;
preset?: string;
}
PopupOptions
interface PopupOptions {
width?: string;
height?: string;
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
customToggleButton?: string | HTMLElement;
containerClass?: string | string[];
}
DrawerOptions
interface DrawerOptions {
width?: string;
position?: 'left' | 'right';
closeButtonDisabled?: boolean;
containerClass?: string | string[];
resizable?: boolean;
resizeOptions?: {
minWidth?: number;
maxWidth?: number;
};
transparent?: boolean;
}
IColorOptions
interface IColorOptions {
primary?: string;
secondary?: string;
background?: string;
border?: string;
text?: string;
ring?: string;
}
What each option does is covered in Configuration.
Errors
The constructor throws with a clear message when the options are invalid:
new Chatoshi({});
// Error: Partner Key is required for Chatoshi initialization
new Chatoshi({ partnerKey: 'pk', mode: 'default' });
// Error: Container is required for Chatoshi initialization
new Chatoshi({ partnerKey: 'pk', container: '#missing' });
// Error: Container element not found
Wrap initialization in try/catch if you want to surface failures to users:
try {
const chat = new Chatoshi({ partnerKey: 'pk', container: '#chat' });
} catch (error) {
console.error(error.message);
}