Skip to main content
The web widget is a chat launcher you add to your site with a single script tag. A visitor clicks it, types, and is answered by the same agent that runs your outreach and answers inbound WhatsApp — same knowledge base, same policies, same voice, and the same shared inbox when it hands off to a person. Nothing about it is a separate support bot with its own configuration to keep in sync. What is different from WhatsApp is who the visitor is: nobody signs in, so there is no phone number and no email address until the conversation produces one.

Install

Copy the snippet from the Boom app — Settings → Channels → Web widget → your widget — and paste it before the closing </body> tag of every page that should show the widget. It looks like this:
Copy it rather than typing it. The origin in the snippet is pinned by the deployment you are looking at, so a hand-written one will point at the wrong environment. The install key in that URL is public — it ships in your page source, and it has to. It identifies the widget; it does not authorize anything. What controls where your widget may be embedded is the origin list below.
async is deliberate. The script does not block your page, and the launcher button appears a moment after the rest of the page has painted.

Allow your site’s origin

A widget only renders on origins you list, and the list starts empty. Add every origin that will host it under Allowed origins on the same settings page. Matching is exact string equality, on the origin a browser actually sends: So https://example.com does not cover https://www.example.com, and a staging domain needs its own entry.
A widget with an empty origin list installs cleanly and never opens. The launcher button appears — the script that draws it does not know which site loaded it — and clicking it produces an empty panel. If that is what you are seeing, this list is the first thing to check.

If your site sets a Content-Security-Policy

Two directives need our origin. Add them to whatever your site already sends:
script-src covers both the snippet above and the launcher bundle it loads. frame-src covers the chat panel, which is an iframe served from our origin. You do not need a connect-src entry. The panel makes its own network requests, but it makes them from inside that iframe, so they are governed by our policy rather than your page’s. The launcher itself — the button and the greeting bubble, which are the only parts living in your document — makes no requests at all. Serve the page over HTTPS. The widget’s session cookie is Secure, so a visitor on an http:// page will not keep a conversation across reloads.

Customize how it looks

The settings page is a live canvas with the widget drawn on a stand-in for your own site, and the settings beside it in four groups. Switch the canvas between desktop and mobile, and between the open panel and the collapsed launcher, to see what a visitor gets. You pick one accent colour and Boom derives the rest, so the text drawn on it stays legible whatever you choose. Launcher — the button visitors click: Panel — the window that opens: Words — everything a visitor reads: the panel title, the greeting, the composer’s hint text, and up to four one-tap suggested questions shown on an empty panel. Every piece of copy is per-language — English, Spanish, and Portuguese — and the visitor gets the language their browser asks for, falling back to English for anything you leave blank. A suggested question left blank in one language simply does not appear for those visitors.
A suggested question is the message. Tapping one sends that exact text as the visitor’s first message, so write them the way a customer would ask, and expect the agent to answer them the way it answers anything else — they are not scripted replies.
Below the composer the panel shows a “Powered by Boom” link. That line is not configurable.
The panel does not tell visitors on its own that they are talking to an AI. Where you need that disclosure — the EU AI Act asks for it wherever it is not otherwise obvious — put it somewhere you control. The greeting is the natural place: it is the first thing a visitor reads, and it is yours to write in all three languages.

What a visitor’s session is

A visitor is anonymous. The only thing tying somebody who comes back to the transcript they left is a cookie on our origin, set the moment they send a first message and good for 30 days. That cookie is Partitioned (CHIPS), which has two consequences worth knowing:
  • It survives in browsers that block ordinary third-party cookies, which is now most of them.
  • It is scoped to your site. The same person visiting two different customers of ours is two unrelated visitors, and the same widget embedded on two of your own domains keeps two separate conversations. The widget is not a cross-site identity.
A visitor who blocks cookies for our origin can still use the widget, but every message starts a new conversation, and the panel is empty again after a reload. There is no login to fall back on.

Sending images

A visitor can attach an image — PNG, JPEG, GIF or WebP, up to 4 MB, four per message. An image on its own is a message; no caption is required. The agent can read it. It receives a written description of the image plus any text found in it, which is what lets it answer about a screenshot of an error, a photo of a receipt, or a picture of the wrong item that arrived. It does not see the picture itself, so an image whose meaning depends on fine detail is better described in words as well. Your agent can send images back, from the assets you have given it — the same library it draws on for WhatsApp. So can a person replying from the shared inbox.
Images only, in both directions. A PDF, a video or an audio file is refused rather than sent: the panel has no way to show one, and a reply that arrived with the file silently missing would be worse than a refusal you can see. On the inbox side the paperclip only offers image files for a widget conversation, and a reply that somehow carries anything else is marked as failed rather than delivered without it.
Anyone who can open your site can upload to the widget — there is no login. It is rate limited per visitor and per widget, every file is checked to be a real image regardless of what it claims to be, and nothing larger than 4 MB is stored. Treat what arrives as untrusted, exactly as you would a message.

Controlling the widget from your page

The snippet installs one global. It works from the moment the tag runs, so you can call it from a button in your own header without waiting for anything to load:
To start a conversation from your own UI, for example an “Ask about this order” button, send a first message on the visitor’s behalf:
send opens the chat and posts the text as the visitor. It only works from a real click or keypress: called from a timer or on page load it is ignored, so no script on your page can write to the chat without the visitor asking. Re-running the snippet is safe. A single-page app that re-executes it on a route change gets the widget that is already there, not a second button.

Proactive help (copilot)

Proactive help is in early access. Contact us to have it turned on for your organization; until then, the In-app expert tab does not appear.
The copilot notices when a visitor seems stuck in your app and offers help: after 30 seconds without a click, or right after they click the same button three times without anything changing, it shows a short message next to the chat button, labelled as an AI assistant, and can draw a ring around the button that helps. Clicking that button works exactly as before. It can also walk a visitor step by step toward a goal, one control at a time. The message is one you write: the widget’s Playbooks page holds them, each describing a situation (“the library has no papers yet”) and what to say. You switch it on and choose how it shows up in the widget’s settings, on the In-app expert tab:
  • Corner notice (the default): the message appears as a card next to the chat button.
  • Island: a small dark tab docked on the edge of the screen, separate from the chat button. Visitors can drag it to any edge. It picks the quietest way to say each message, from the playbook and what is on screen: a single line that comes out of the tab when there is nothing to point at, a ring on the control when the control says it all, a short card when it can guide the visitor, a choice of two or three when it can’t tell which you meant, and only a dot while the visitor is typing. A situation you mark as a warning stays until acted on. Tapping the tab opens a card with the current message or step and a question box; sending a question opens the chat with it, or, with the expert agent on, the expert answers it in the island. With nothing pending, the card also offers up to three things to do on that screen: the situations you gave a short label (and a goal), and picking one starts its guide. Its cards can be Light (the default) or Dark, and you can add a small “How it works” link to your own help page. Its Presence is Always there (the default) or Only when it can help: then the tab stays out of sight until it has something to say (a suggestion, a guide step or an answer) and goes again once that is dealt with, so nothing rests on your page.
In both styles, a guide’s steps appear in a card beside the control they refer to. It runs only when you switch it on for a widget and it has at least one playbook. Switching it off stops it, including a guide a visitor is in the middle of. Playbooks are written per page: each one lists the paths it applies to (/events/**, /settings) and the situations it watches for there. The chat and the expert are separate: in the widget’s settings you can switch the chat off and keep only the expert. The island then has no question box, since there is no chat to hand a question to. With the chat off, the chat panel and its message and upload endpoints refuse every request, including ones made directly rather than through the snippet. What it reads, from the screen the visitor is on:
  • the buttons, links, tabs and form labels, and whether they are disabled
  • headings and short labels
  • the last few pages visited and controls clicked on this tab, kept only in the tab’s session storage and sent only when the copilot decides whether to offer help
What it never reads:
  • anything anyone types into a field (it only notes whether a field is empty or filled, and not even that for passwords)
  • content inside lists and tables, where your users’ own data usually lives
  • anything inside an element you mark with data-boom-private (or the boom-private class)
  • the labels and text inside an element you mark with data-boom-pii (or the boom-pii class), and of fields for personal data such as email, phone, address, card or password fields: the expert sees only that the controls are there, reads them as [redacted], and never points at them
Emails, card numbers, IBANs, national ids (CURP, RFC, CPF, CNPJ, SSN) and phone-like numbers are masked before anything leaves the browser. Boom keeps only the page’s route shape (ids removed) and the name of the control the expert pointed to, never field values, rows, messages or anything typed. To keep a region out entirely:
If you can’t change the markup, add CSS selectors on the In-app expert tab’s Protected content card instead. Protecting sensitive data has every rule, the automatic ones included. The copilot only answers pages on your widget’s allowed origins, the same list the chat uses.

Asking the expert

The expert agent is in early access. Contact us to have it turned on for your organization. To keep it off on a page that loads the widget, set <script>window.__BOOM_EXPERT_AGENT__ = false</script> before the widget script.
With the agent on, a question typed into the island is answered there, by an AI that knows your playbooks and can see the same redacted screen the copilot sees. It answers one step at a time, rings the control it is talking about, and can start one of your guides. Turn it on in the widget’s settings, on the In-app expert tab’s Agent card:
  • Languages: which of English, Spanish and Portuguese it answers in. It answers in the page’s language when that one is on, otherwise the first one on.
  • Persona: an optional few lines on its name and tone.
  • Voice: lets visitors talk to it. A microphone button appears in the island. Until a visitor’s first call, one short line under it says that starting a call accepts the terms, linked to Boom’s Terms; starting the call accepts them. Each language has its own voice. Talking is kept short on purpose: after about 18 seconds of quiet, or two minutes at most, it says it will continue on screen and the conversation carries on in text, in the same thread. Typing a question also ends the spoken part.
  • Actions: whether it may act for the visitor.
    • Off (the default): it only guides.
    • Navigate: it may open a page by following a link on screen.
    • Confirmed: it may also click and fill fields.
    Every action asks the visitor first, in the island (“Click “Import CSV”?”, “Fill “Name” with “Q4 churn”?”, with Do it and No). Whatever the visitor or the AI asks, it never clicks anything that deletes, cancels, pays, signs out or disconnects; never follows a link off your site; and never types into passwords, payment fields, one-time codes or anything under data-boom-private.

References

The agent never writes a link itself. It can only put a link it was given on screen, as a small chip under its answer that opens in a new tab, and any web address typed into its answer is removed before it shows. Every expert has three links built in: how data is handled (https://www.useboom.ai/privacy), who processes data (https://www.useboom.ai/subprocessors) and Boom’s terms (https://www.useboom.ai/terms), which it shares when a visitor asks about privacy, the AI providers behind it, or the terms. Add your own (docs, examples, a pricing page) to the playbook YAML, up to 10, each with a note on when to share it. A situation can name the ones that belong to it:
References are saved with the playbooks, so each version keeps its own, and the playbooks page lists the current ones. Their titles and addresses are public: they are sent to the visitor’s browser with the widget. What the agent sends and keeps, on top of what the copilot reads:
  • the visitor’s question, and the AI’s answer;
  • the name of each control it pointed at or acted on, and whether the visitor said yes; never what was typed, except the value the AI itself proposed in a confirmed fill.
Conversations are kept encrypted for 30 days after the last message, then deleted. With voice on, the visitor’s audio goes to ElevenLabs to be turned into text and back into speech; ElevenLabs does not keep a recording, and the conversation’s text is the one Boom keeps.

Reporting something confusing

Where the agent is on, the island’s card has a small flag, Report something confusing. A visitor taps it, then taps the part of your page they find confusing (that tap selects it instead of using it; Esc or Cancel backs out), adds an optional one-line note and sends it. The agent also hears about it on the visitor’s next question, so it can help with that control. A report carries the element’s role and name (a button called “Sync”, say), the same redacted page structure and recent steps a question carries, the page’s path with ids masked, the screen size, the note, and the conversation it belongs to. It takes no screenshot or recording, and never a field’s value: inside a field, anything under data-boom-private, or a list or table row, only the element’s role is sent, as “protected”. Reports are kept encrypted for 30 days. A visitor can send 10 a day.

Reading the conversations

To see what visitors asked and where they got stuck, open the widget’s Playbooks page and switch to Conversations (the In-app expert tab links there too). Each row is one conversation: when it started, the visitor’s first question with the agent’s last answer under it, the language, the number of turns and an estimated cost. Opening one shows the whole exchange, with each thing the agent did on the page as one short line (“Highlighted “Export””, “Filled “Name” (visitor said yes)”); values are never shown, not even the one the AI proposed in a fill. Conversations appear once the agent is on, and go when they are deleted after 30 days. Reports are on the same page, under Reports: newest first, with the element, the visitor’s note, the page and a link to the conversation. Opening one shows the steps before it and the page’s structure, and Copy as Markdown puts it all on your clipboard for an issue or a coding agent. A conversation shows its reports above the exchange. Reading them needs the permission to read the inbox (Owner, Admin, Member, Inbox Operator and Viewer have it), since they hold what your visitors typed. Every time someone opens a conversation or a report, or lists reports, Boom records who did it.

When nothing answers

Answering is a setting, not a default, and it resolves exactly the way inbound does: per channel, falling back to your organization.
If no agent is configured to answer the widget, or the configured agent is disabled, the visitor’s message is still received and stored — it waits in the shared inbox for a person — and the panel stops waiting and offers a retry rather than spinning. Boom does not pick an agent on your behalf, because guessing which agent should speak for you is worse than staying quiet.
The agent that answers is assigned to the conversation, so the inbox always shows who is replying. Unassigning the agent from a conversation hands it to your team: the agent stops answering that visitor, and their messages wait in the inbox. It picks the conversation back up only after 7 days with no one on your team touching it, or as soon as someone sends it back to the AI. Replies a person sends from the inbox arrive in the visitor’s open panel in realtime, minutes later if that is when they are written.

Rate limits

Per visitor, 30 messages a minute and 10 image uploads a minute. Per widget, 120 first-messages and 40 uploads a minute from visitors who have no session yet — set far above a real site’s arrival rate, so they throttle a loop rather than a launch. A throttled request is refused before anything is stored. Uploads have their own allowance rather than sharing the message one, so a visitor who has just sent several images can still write about them. The expert agent has its own: per visitor, 20 questions a minute and 300 a day (counting each step it takes), and per widget 120 a minute. Voice adds 15 minutes a day per visitor and 10 conversations at once per widget. Each organization also has a daily spending cap; past it, the agent says it can’t answer questions today, and the copilot’s guides keep working. Confusion reports: 10 a day per visitor and 30 a minute per widget.

Rotating the install key

Rotate on the settings page mints a new key and invalidates the old one immediately. The snippet on your site then points at a key that no longer resolves, and the widget stops appearing until you paste the new one — so rotate when you are ready to deploy the change, not before. Rotating does not touch conversations, transcripts, or appearance.

Troubleshooting

Inbound conversations

The same answering behavior, reached from WhatsApp instead of your site.

The agent

What briefs the agent that answers, and when it hands off to a person.

Extraction

Why a cold widget conversation has a transcript but no typed fields.

Use MCP

Read widget conversations from an AI tool.