The BrokerBot chat widget is one script tag. This guide covers embedding it, signing your members in automatically with SSO, and telling the agent what page the visitor is on.
Embed the widget
Copy the snippet from your widget’s settings in BrokerBot, or add it yourself:
<script
src="https://cdn.brokerbot.ai/widget.js"
data-widget-id="YOUR_WIDGET_ID"
async
></script>
| Attribute | Required | Description |
|---|---|---|
data-widget-id |
Yes | Your widget ID. |
data-sso-token |
No | One-time SSO token that signs the member in. See Single sign-on. |
data-auto-context |
No | Set to "false" to stop sending the page URL and title. See Page context. |
data-mode |
No | fab (default): floating button in the bottom-right corner. input: inline “Ask anything” bar that opens a full-page chat. headless: no launcher; your page opens and closes the chat. See Headless mode. |
data-target |
No | CSS selector the input bar mounts into, for example #chat-launcher. |
data-assistant-id is still accepted for older snippets. If both are set, data-widget-id is used.
Site builders that use iframes (Wix, Squarespace)
HTML embed blocks on these platforms run inside an iframe, so the full-page chat can’t open over your page on its own. Add a loader script to the parent page too. In Wix, add it under Settings → Custom Code → Body - End:
<script src="https://cdn.brokerbot.ai/widget.js" data-role="loader"></script>
Then put the normal widget snippet, with data-mode="input", inside the HTML embed block. The loader shows nothing itself. It opens the full-page chat when the embedded widget asks for it.
Single sign-on (SSO)
If your members are already signed in to your site, you can sign them in to the widget too. They skip the prechat form, and their chat history stays with their BrokerBot account.
- Your server asks BrokerBot for a one-time token for the signed-in member.
- You put that token in the page as
data-sso-token. - The widget exchanges the token for a session, and the member lands in chat already signed in.
Rules
- Server-side only. The request uses your BrokerBot API key. Never send the key to the browser.
- Your team only. An API key can only issue tokens for members of the team it belongs to, including its sub-teams. The team comes from the key; nothing in the request can change it.
- Existing members only. The member must already be on your team in BrokerBot. Unknown emails or phone numbers are rejected, never created.
- Short-lived and single-use. A token expires 5 minutes after it’s issued and works once. Issue a new one on every page render, and never cache it.
- Tied to your widgets. A token only works on a widget that belongs to the same team, and only for a member of that widget’s team.
- One page load per token. The widget session an SSO token opens lives in memory only; it is never written to
localStorage. Reloading or leaving the page ends it, so mint a fresh token for every page load.
1. Issue a token
HTTP
curl -X POST https://api.brokerbot.ai/auth/generate-token \
-H "Authorization: Bearer $BROKERBOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]"}'
Request body:
| Field | Type | Description |
|---|---|---|
email |
string | Member’s email. Send email, phone, or both. |
phone |
string | Member’s phone number, in any common format. It is normalized to E.164. |
If both are sent, the member is looked up by email.
Response (200):
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"expiresAt": 1790725200
}
expiresAt is a Unix timestamp in seconds.
| Status | Meaning |
|---|---|
400 |
Missing or invalid email or phone, or the body isn’t JSON. |
401 |
Missing or invalid API key. |
404 |
No member of your team matches this email or phone. |
422 |
The member has no email address. Widget sign-in needs one. |
TypeScript / JavaScript
The brokerbot package wraps the same endpoint:
npm install brokerbot
import { BrokerBot, BrokerBotError } from "brokerbot"
const brokerbot = new BrokerBot({ apiKey: process.env.BROKERBOT_API_KEY! })
try {
const { token, expiresAt } = await brokerbot.generateToken({
email: "[email protected]"
})
} catch (error) {
if (error instanceof BrokerBotError) {
console.error(error.status, error.message)
}
}
new BrokerBot() also accepts baseUrl (default https://api.brokerbot.ai) and a custom fetch.
2. Render the token into the page
<script
src="https://cdn.brokerbot.ai/widget.js"
data-widget-id="YOUR_WIDGET_ID"
data-sso-token="{{ token }}"
async
></script>
The widget reads the token when it loads, then removes the attribute from the page.
3. What the visitor sees
- Sign-in works: chat opens already signed in, with no prechat form. If the browser still holds a session or chat history for a different person, the widget clears it first.
- Sign-in fails (expired, already used, or wrong team): the widget shows the normal prechat form, so the visitor can still chat.
- Page reload: the SSO session is gone. If the new page has a fresh
data-sso-token, the member is signed straight back in; otherwise they see the prechat form.
4. Sign the member out
When the member logs out of your site, sign them out of the widget too:
window.BrokerBotWidget?.logout()
This revokes the widget session, clears the member’s chat from the browser, and returns the widget to the prechat form. Call it on shared computers especially, so the next person doesn’t chat as the previous member.
Page context
The widget tells the agent which page the visitor is on, so answers can use it (for example, “tell me about this listing”).
Automatic context
By default, each message includes:
| Key | Example |
|---|---|
url |
https://example.com/listings/123?tab=photos#gallery |
pathname |
/listings/123 |
search |
?tab=photos (only when present) |
hash |
#gallery (only when present) |
title |
The page’s document.title (only when present) |
Route changes in single-page apps (history.pushState, replaceState, back/forward, and hash changes) are picked up without any extra code.
Automatic context sends the full URL, query string included. If your URLs can contain tokens, codes, or personal data, turn it off and send only what you need through setContext.
To turn it off, add data-auto-context="false" to the script tag or call:
window.BrokerBotWidget.setAutoContext(false)
Custom context
Send your own fields with setContext:
window.BrokerBotWidget.setContext({
section: "Listings",
listingId: "12345",
officeName: "Chicago - Lincoln Park"
})
- Each call replaces the previous custom context.
setContext(null)clears it. - Custom fields override automatic ones with the same key.
- Values must be strings, numbers, or booleans. Other values are dropped.
- Limits: 20 keys, keys up to 64 characters, and values up to 500 characters (longer strings are truncated).
window.BrokerBotWidget exists once widget.js has loaded. If the script tag uses async, call it after the script’s load event.
Context is shown to the agent as information about the page, not as instructions. Visitors can see and change anything in the page, so don’t use it for permissions or secrets.
Control the widget from your page
window.BrokerBotWidget lets your page open and close the chat:
window.BrokerBotWidget.open() // show the chat panel
window.BrokerBotWidget.close() // hide it
window.BrokerBotWidget.isOpen() // true or false
The widget fires events on window when the panel opens or closes, whether your code or the visitor did it:
window.addEventListener("brokerbot:open", () => {
// for example, update your own "Chat" button
})
window.addEventListener("brokerbot:close", () => {})
open(), close(), and the events work in every mode. In input mode, open() shows the full-page chat (on the parent page when the widget is inside an iframe embed), and close() dismisses it.
Open a document in chat
Pass a document from the Knowledge Search API to start a chat about it:
window.BrokerBotWidget.open({
document: { id: "doc_123", name: "Commission Split Policy.pdf" }
})
- The widget starts a new chat and asks the agent to open the document. The agent receives the document’s ID and name as page context and loads it from the knowledge base by ID.
- The agent only loads documents the visitor can see. If they can’t, it tells them they don’t have access. The
nameyou pass is only used for the opening message. - Anonymous visitors only see documents visible to the widget. Use SSO so members can open documents shared with them.
- Starting a new chat clears the document.
Headless mode
Headless mode shows no launcher button. The chat stays hidden until your page calls open(), so you can use your own button or trigger it from your own UI:
<script
src="https://cdn.brokerbot.ai/widget.js"
data-widget-id="YOUR_WIDGET_ID"
data-mode="headless"
async
></script>
<button id="ask-brokerbot">Ask BrokerBot</button>
<script>
document.getElementById("ask-brokerbot").addEventListener("click", () => {
window.BrokerBotWidget?.open()
})
</script>
The panel has a close button in its header, and your page can also call close().