Drop-in AI chat
for any website.
Answers from your own docs. Captures leads while it talks. One script tag, pasted once — no build step on the client's side.
<script src="https://conversekit-widget.pages.dev/widget.js" data-bot-id="YOUR_BOT_ID" defer></script>
The chat bubble in the corner is the real widget, running on this page.
How it works
Three steps, and the third one never ends
Onboarding a client is a row in a table and a script tag. There is no per-customer deploy, no rebuild, and nothing to install on their side.
Give it something to say
Paste a business description, services, hours and an FAQ — or point it at a URL and let it read. Longer material becomes a knowledge source: chunked, embedded and searched at question time.
Paste one tag
The snippet goes anywhere before the closing body tag. The widget styles itself from the bot's own brand colour and only answers on the origins you allow.
It answers, and it listens
Replies stream token by token. When a visitor shows intent, the model collects a name, email or phone number mid-conversation and files it as a lead you can export.
AI providers
Eleven vendors, one interface
Most vendors speak the OpenAI chat-completions shape, so they are configuration rather than code — one adapter, many entries. Only Anthropic, Google and Workers AI need their own translation layer. Switching vendor is a dropdown, per bot.
It runs on nothing
Groq for chat and Cloudflare Workers AI for embeddings run the entire loop — ingest, retrieve, answer — at no cost. That is the platform default, and it is verified rather than theoretical.
Bring your own key
Each bot can carry its own vendor credentials, or fall back to the platform's. Keys are write-only through the API: once stored, they are redacted from every response and the UI shows the last four characters.
Streaming, with a net
Replies arrive over SSE. If the stream fails for any reason — a proxy, an extension, a vendor hiccup — the widget silently retries against the buffered endpoint, and the visitor sees an answer either way.
Knowledge
Answers from your documents, not from the internet
Text, markdown and URLs become a searchable corpus. At question time the query is embedded, matched against that bot's chunks by cosine similarity, and the best passages are assembled into the prompt with their sources.
Tuned per bot
The number of passages retrieved, a similarity floor and chunk size are per-bot settings, not global constants. A dense product manual and a short FAQ do not want the same retrieval.
Retrieval never fails the visitor
A bot with no corpus, or an embedding vendor having a bad minute, falls back to the plain knowledge-base prompt instead of failing the turn. A degraded answer beats an error message.
Inspect what it found
The dashboard shows the chunks a document produced and lets you reindex a source after editing it, so "why did it say that?" is a question you can actually answer.
Multi-tenant
Built for someone running this for other people
One Worker and one Pages site serve an unlimited number of client bots. Isolation is enforced in the database, not in application code that a future refactor can quietly drop.
Row-level security
Every tenant-scoped table carries an RLS policy keyed off the signed-in user's memberships. Two organizations cannot see each other's bots, leads or conversations — proven by a test that authenticates as one org and asks for the other's ids directly.
Origin lock
Each bot carries a list of allowed origins, normalised and matched exactly — scheme and port included. A request from anywhere else is refused with a 403 before the model is ever called.
Signed sessions
Conversation ids are minted and signed by the server. The widget never invents one, because a guessable id would let anyone replay it and read another visitor's transcript.
Install
One tag. Any site.
Create a bot in the dashboard, fill in what it should know, then paste this with your own bot id.
<script src="https://conversekit-widget.pages.dev/widget.js" data-bot-id="YOUR_BOT_ID" defer></script>