The widget exposes a JavaScript API so your own site can open the chat, jump straight to a help article or your release notes, send a message for the visitor, react when something happens in the widget, and attach details that show up beside the conversation in your inbox.
Why control the widget from your own code
The launcher button handles most situations fine, but sometimes you want the chat to appear at the right moment — after someone reads a pricing page, fills in a form, or spends a while on a help article without finding what they need. Driving the widget from your code means your site decides when to surface the conversation, and what it opens on, not just the visitor.
Common use cases:
- A "Talk to us" button in your own UI that matches your design system instead of floating over it
- A "How does billing work?" link that opens the widget directly on your billing article
- A product tour step that ends with "Got questions? Chat with us"
- A form confirmation page that opens the chat so someone can follow up
- Tagging a conversation that starts on your checkout page, so it is easy to find in the inbox
Prerequisites
You need the widget embed snippet on the page. Grab it from your agent's Deploy tab — it looks like this:
<script
src="https://chattering.ai/widget.js"
data-chattering="YOUR_AGENT_ID"
async
></script>
Paste it before the closing </body> tag on any page where you want the widget. Once the script loads, window.Chattering is available automatically — there is nothing extra to initialise.
The main methods
| Method | What it does |
|---|---|
open() |
Opens the chat panel |
close() |
Closes it |
toggle() |
Opens if closed, closes if open |
openMessages() |
Opens the panel on the visitor's conversation |
openHelp(articleId) |
Opens the Help tab; pass an article id (or its public URL slug) to open that article |
openNews() |
Opens your release notes |
openRoadmap() |
Opens your public roadmap |
reportProblem() |
Opens the report-a-problem form |
sendMessage(text, { send }) |
Sends a message as the visitor; send: false puts it in the input for them to edit first |
on(event, handler) / off(event, handler) |
Listen for widget events (see below) |
hideLauncher() / showLauncher() |
Hide or show the floating launcher button |
setTags(tags) |
Tags for the next conversation this visitor starts |
setAttributes(details) |
Key–value details shown beside the conversation in your inbox |
identify(id, data, userHash) |
Links this session to a known contact |
updateContact(data) |
Updates the identified contact's details |
track(name, data) |
Sends a product event to the contact's timeline |
clearIdentity() |
Forgets the current identity on logout |
Every method is called on window.Chattering, for example window.Chattering.openNews(). Once the widget has loaded its settings on a page where it is switched off, openMessages(), openHelp(), openNews(), openRoadmap(), reportProblem() and sendMessage() return false, so your own button can fall back to something else. open() and toggle() do not return a value.
Calling the API before the widget has loaded
The widget script loads asynchronously. To call it during your own page load, add this stub right after the embed snippet — it queues calls and the widget replays them, in order, once it is ready:
window.Chattering = window.Chattering || { _q: [] };
["open", "close", "toggle", "sendMessage", "openMessages", "openHelp", "openNews",
"openRoadmap", "reportProblem", "on", "off", "hideLauncher", "showLauncher",
"setTags", "setAttributes", "identify", "updateContact", "track", "clearIdentity"].forEach(function (m) {
window.Chattering[m] = window.Chattering[m] || function () {
window.Chattering._q.push([m, [].slice.call(arguments)]);
};
});
Code examples
Open on a button click
document.querySelector('#chat-with-us').addEventListener('click', function () {
window.Chattering.open();
});
Open a specific help article
document.querySelector('#billing-help').addEventListener('click', function () {
window.Chattering.openHelp('ARTICLE_ID');
});
The article id is at the start of the article's public address: in /help/a/abc123-refunds-and-cancellations it is abc123. You can also pass the whole abc123-refunds-and-cancellations part. An id that does not match one of the published articles the Help tab loads (the first 30, in your help center's order) leaves the visitor on the article list rather than showing a blank page.
Start a conversation with a question
window.Chattering.sendMessage('Which plan includes phone support?');
To let the visitor edit the text before it goes, pass { send: false }.
Use your own launcher
window.Chattering.hideLauncher();
document.querySelector('#help-button').addEventListener('click', function () {
window.Chattering.open();
});
window.Chattering.on('unread', function (e) {
document.querySelector('#help-badge').textContent = e.count ? String(e.count) : '';
});
With the launcher hidden, the panel still closes from its own close button. The small reply preview that normally pops up beside the launcher is held back, so badge your own button from the unread event instead.
Tag conversations and attach details
window.Chattering.setTags(['checkout']);
window.Chattering.setAttributes({ orderId: 'A-1042', cartValue: 89 });
Tags are applied when the visitor's next conversation starts, and behave like any other tag: you can search and filter by them, and use them in rules. Details are sent with every message — the latest value of each key wins — and appear under From your site in the inbox. Values can be text, numbers or true/false; pass null to stop sending one (a value already saved on a conversation stays there). Up to 6 tags and 20 details.
These come from your page's code, so a visitor could change them from their own browser — use them to describe the visit, not to prove who someone is. For that, use identify with identity verification.
Events
| Event | When it fires | What the handler receives |
|---|---|---|
open |
The panel opens | — |
close |
The panel closes | — |
message |
The visitor sends a message, or a reply arrives | { from: 'visitor' | 'ai' | 'team', text } |
unread |
The number of unread replies changes while the panel is closed | { count } |
window.Chattering.on('message', function (e) {
if (e.from === 'team') console.log('A person replied');
});
on returns false for an event name the widget does not send, so a typo is visible rather than silently ignored. An error thrown inside your handler is caught and never breaks the widget.
Browser compatibility
The API uses the browser's built-in fetch and Promise. JavaScript must be enabled. There is no support for Internet Explorer.
Troubleshooting
Calling a method does nothing
Check that the embed script has actually loaded. Run console.log(window.Chattering) in the browser console — if it prints undefined, the script tag is missing or blocked. View source and confirm the script tag is present with your agent's public ID in data-chattering. A Content Security Policy that blocks chattering.ai can cause a silent failure. Add chattering.ai to your script-src, connect-src, img-src and font-src directives, and allow inline styles ('unsafe-inline') in style-src, because the widget adds its own <style> tags.
The object exists but the method silently does nothing
If window.Chattering is present but a call is a no-op, you are probably talking to the pre-load stub and the widget has not finished loading — the call is queued and will run. If it never runs, check that the method name is in the stub's list above.
A method returns false
Either the widget is switched off for this page under Where the widget appears in Widget → Appearance, so there is nothing to open, or the call could not be used: an argument of the wrong type, an event name the widget does not send, or sendMessage() while an earlier message is still sending.
The agent loads but gives no replies
If the panel opens and accepts a message but the AI does not respond, check that the agent is active. Go to AI Agent in your Chattering dashboard and confirm the agent tied to your public ID shows Live and has at least one source marked ready on its Sources tab.