PLAI.chat drops into any website or web app as a chat bubble, a docked side panel, or an inline panel. Your visitors get 300+ models with no signup. You get no build step, no npm package, and no cookies added to your page.
Opens a short form right here — no account, no sales call. Prefer email? Use the
support form instead.
The chat bubble in the corner of this page is the widget itself. Go on, ask it something.
Pick the options, hit Run on this page, and the widget re-mounts live in the mode you chose. The snippet below is exactly what you paste into your own HTML.
The demo key above is locked to plai.chat — copying it to another domain
will not work, which is exactly the protection your own key gets.
A full AI chat, not a scripted FAQ bot. The same engine that runs plai.chat: 300+ models behind one interface, streaming answers, markdown, code blocks, Mermaid diagrams and live HTML previews.
Anonymous chat on the free model chain, gated by a Cloudflare Turnstile bot check. No account, no email, no password — nothing between the visitor and their first question.
The widget sets nothing on your domain. The visitor session is a bearer token inside the iframe's own partitioned storage, and conversations stay in the visitor's browser.
The launcher lives in a closed shadow root and the chat is a cross-origin iframe. Total isolation both ways — your styles stay yours, ours stay ours.
Under 640px the panel goes fullscreen and the layout switches to the mobile design automatically. Nothing for you to configure.
plai.open(), close(), toggle(), destroy() and an
on() event hook — so your own button can open the chat.
One script tag. No npm package, no bundler, no framework requirement, no server component on your side. It works on WordPress, Webflow, Next.js and hand-written HTML alike.
Change data-mode and nothing else. Everything above the fold in the builder writes it for you.
| Mode | What it does | Use it for |
|---|---|---|
| bubble | A round launcher in the bottom-right corner. Clicking it opens a panel that overlays the page; your content never moves. | Marketing sites, documentation, support pages. The default. |
| dock | A column pinned to the right edge that pushes your page content aside, with a drag handle to resize. The width is remembered per site. | A permanent assistant inside a SaaS app, next to the user's work. |
| inline | Mounts into an element you supply via data-target. No launcher, no overlay, no push — it
is simply part of your layout. |
A help centre page, a landing page section, an in-app tab. |
An embed key is public by design — it ships in your page source, so anyone can read it. That is why it is not treated as a secret: it is bound to an origin allowlist instead.
Content-Security-Policy: frame-ancestors header naming your domains, and the server
independently refuses to serve the widget, mint a session, or answer a message when it can see the framing
site is not on the list. Copying your key to another domain gets a 403, not a working widget.The widget also cannot read your page. It is a cross-origin iframe: no access to your DOM, your
localStorage, or your users' session with your app. Everything that crosses that boundary is an
explicit message we document.
When you embed the widget, you are the controller of your visitors' data and we are your processor. We publish a standard Article 28 Data Processing Agreement covering exactly that, including the sub-processor list and a 30-day notice on any change to it. A countersigned copy is available on request.
We would rather tell you the boundary than have you discover it after launch.
| Capability | Status |
|---|---|
| Bubble, dock and inline layouts | ✓ live |
| Anonymous visitor chat, free model chain | ✓ live |
| Per-key origin allowlist, server-enforced | ✓ live |
| Markdown, code, Mermaid diagrams, HTML preview | ✓ live |
open() / close() / toggle() / events | ✓ live |
| Sign-in inside the widget, and moving a chat into the full app | in development |
| Custom system prompt, your colours, your greeting | in development |
| Page awareness — the assistant knows which page it is on | in development |
| Owner-paid usage with a hard monthly budget and auto-pause | in development |
| Tools your page registers, executed in the visitor's own session | planned |
Keys are issued by hand right now, which means you get a short conversation with us instead of a signup form — and we set the allowlist, layout and defaults up for you. Two ways to start it: (a small form, opens in place) or the support form. Either way, tell us the domain you want the widget on.
The loader is a few kilobytes with no dependencies, served with a defer attribute so it never
blocks rendering. The chat iframe itself is created only when the widget is opened — in bubble mode a visitor
who never clicks pays for one small script and nothing else.
You will need https://plai.chat in your script-src and frame-src.
That is the whole requirement — no inline scripts, no unsafe-eval.
Yes: window.plai.open(). The loader queues calls made before it finishes booting, so you can
wire it up anywhere on the page without worrying about ordering.
The free chain by default, which rotates as better free-tier models appear — see the model list. Visitors who sign in with their own account can switch to premium models and pay per use.
Yes, and it is currently per IP address, which can be tight behind a corporate NAT where an entire office shares one address. Per-key and per-visitor limits are in development. Tell us if you expect that traffic shape and we will raise the ceiling for your key.
That is the case it was designed for — dock mode exists for it. Restricting the widget to your own logged-in users, using a signed identity you issue, is on the roadmap above.
Two routes, both go to the same inbox: , or use the support form. Tell us the domain (or domains) you want it on — we create the key, set the allowlist, and send you back the finished snippet.
Tell us your domain and what the assistant should help with. We will send back a key and a snippet you can paste in one sitting.
Opens a short form on this page. You can also use the support form, or ask the chat bubble in the corner what the widget can do.