The key in your widget is public. That is not the problem.
Every chat widget on every website works the same way: a key sits in a script tag, in the page source, readable by anyone who presses Ctrl-U. It cannot be hidden and no vendor hides it. What separates them is whether that key is worth anything to the person who copies it.
The key only works on domains you list
Add the hostnames you embed on and the key stops authenticating from anywhere else — the browser sends its Origin on every widget request and it is checked against your list before anything is answered. Someone who copies your snippet gets a refusal on their own site rather than a working assistant billed to you.
Try changes without exposing a key at all
The preview inside the dashboard runs on a short-lived session issued to your logged-in account, not on a publishable key. You can rewrite a greeting, change the colour or test a question against your real content without a key existing anywhere a visitor could read it.
Shared reports are scoped, dated and revocable
A read-only analytics link can be scoped to one assistant rather than the whole workspace, and it carries a ceiling on how far back a viewer may look — asked for a wider window, the page serves less data rather than refusing. Every link expires on its own, and you can revoke one before it does.
What the publishable key can and cannot do
It authenticates one assistant to answer questions. It is not an account credential: it cannot read your conversations, reach your dashboard, change a setting, see a lead, or touch billing. Only its SHA-256 hash is stored on our side, and you can rotate it from the assistant’s screen whenever you like.
So the realistic abuse is narrow and worth naming precisely: someone lifts your snippet, embeds your assistant on their own site, and spends your monthly message allowance answering questions for their visitors out of your content. Not a breach. Just your quota, and your content, working for somebody else.
A new key allows every origin until you tell it otherwise. We would rather print that here than let you assume the opposite. The list is empty when a key is created, and an empty list means the key answers from anywhere — the same as every other widget you have installed. Adding the one or two hostnames you actually embed on takes about a minute and is the single highest-value minute available on that screen.
Matching is exact, and there are no wildcards
This is the part that surprises people, so it is better read here than discovered on a live site. Each entry is compared exactly against the hostname the browser reports. example.com does not cover www.example.com, and neither covers shop.example.com. Every hostname you embed on is its own line, up to fifty of them.
We reject *.example.com rather than accepting it, because the check underneath has no wildcard support — a stored wildcard would be a line that never matches anything, sitting in a security setting looking like protection. Some products in this category do support wildcards. Ours is the stricter behaviour and it costs you a few extra lines; you should know that before you choose, not after.
Paste whatever you have — a full URL, a scheme, a trailing path, a port — and the field reduces it to the hostname and shows you what it is about to save before you commit. Anything it cannot reduce is refused with the reason, because “invalid domain” tells you nothing you can act on, and the usual response to an error you cannot act on is to give up and leave the key open.
How to check any vendor, including this one
This takes five minutes and settles the question for whatever product you are looking at. Do it to us too.
- Open your own site, view source, and find the key in the widget snippet. It will be there. If a vendor tells you their key is secret, that is the answer to a different question.
- Copy the whole snippet into a blank HTML file and open it from somewhere else — a scratch file on your desktop, or any host that is not your site.
- Ask the widget a question. If it answers, that key currently works from any site on the internet, and so would a copy taken by anyone else.
- Add your real hostnames to the restriction list, then reload the scratch file and ask again. It should now refuse there and keep working on your own site.
Step four is the one that matters. A setting that changes nothing when you test it is not a control, and this is the only way to tell the two apart from outside.
What we do not do yet
A security page listing only what works is an advertisement. These are the gaps we would want to know about if we were buying, stated the same way we state them to the firms already asking.
- Conversations are stored in our database and readable by members of your workspace. We do not yet publish a fixed retention period, and there is no self-serve delete for a single conversation.
- The domain restriction is per key and opt-in. Nothing forces a new assistant to have one, and nothing nags you into it beyond this page.
- We hold no third-party security certification. There is no SOC 2 report to send you, and we would rather say that than describe ourselves as enterprise-grade and hope the question does not come up.
If you need any of those in writing before you can proceed, ask us and we will tell you exactly where each one stands the week you ask.
Run the four steps on your current widget
Whatever you find, it is worth knowing. If you want to run them against ours, the free plan needs no card.