Docs · Advi Agents

Advi Agents — AI chat that answers, qualifies, and captures leads from your website 24/7.

An Advi Agent is an AI assistant you embed on your website (or wire to WhatsApp, Telegram, Messenger, or Instagram) that holds real conversations with your visitors. It answers questions from a knowledge base you upload, captures contact details, escalates to a human when it's out of its depth, and feeds everything back into a dashboard you control. This guide walks you through setting one up, explains what happens behind the scenes during a conversation, and documents the security boundaries that make it safe to embed on a public site.

Setting up an agent, step by step#

From signing up to a working chat bubble on your site is about ten minutes. The order matters — knowledge has to be attached before you deploy, otherwise the agent has nothing to answer with.

  1. 01

    1. Create the agent

    Open the dashboard, click New agent, and fill in two kinds of fields. The internal fields (name, description) are only visible inside your workspace. The visitor-facing fields (display name, greeting message, widget colors, optional icon) are what your website visitors see. You also pick the AI model the agent will use and write its system prompt — this is the persona, the rules, and any escalation logic, written in plain English. The agent is created with a unique "public token" — a random string that uniquely identifies this agent to the rest of the world.

  2. 02

    2. Attach your knowledge

    Knowledge is what the agent reads to answer questions. Paste in raw text (FAQs, product pages, return policies, pricing) or upload PDFs — the server extracts the text from PDFs automatically. Long documents are split into chunks so the agent retrieves only the relevant passages per question, not the whole document. Each chunk is converted into a numerical fingerprint (an "embedding") and stored so it can be searched by meaning, not by keyword.

  3. 03

    3. Turn on the tools the agent can use

    Tools are actions the agent is allowed to take during a conversation. Built-in tools include capture_lead (save a visitor's contact details), request_handoff (escalate to a human and fire your handoff webhook), get_offer (pull a discount or offer you've configured), submit_csat (capture a 0–5 satisfaction score), and mark_conversion (flag a session as converted). Each tool is opt-in per agent — if you don't enable capture_lead, the agent never asks for an email.

  4. 04

    4. Deploy the widget on your site

    When the agent is ready, copy the one-line embed snippet — it looks like <script src="/api/widget/[your-token]" defer></script>. Paste it before the closing </body> tag of your site. The script renders the floating chat bubble, handles the conversation UI, and routes everything back to our servers using only the public token. You can drop it on any HTML page, in any CMS, on any host — no server-side install needed.

  5. 05

    5. Conversations are captured automatically

    Every visitor message and agent reply is saved to your workspace. Each conversation is tied to a session (the conversation thread) and to a contact (the visitor identity, stored under the third-party site's own browser storage, not on our domain). You can see every transcript inside the dashboard, search for specific terms, mark sessions as resolved, and export a transcript if a customer asks for it.

  6. 06

    6. Review and improve

    The Analytics tab aggregates sessions, messages, contacts, active sessions in the last 24 hours, the channels they came in on (web, WhatsApp, Telegram, Messenger, Instagram), CSAT scores, conversion rates, and recent conversations. If the agent is missing too many questions, edit its system prompt or add knowledge — the change takes effect on the next message, no redeploy needed.

How the agent behaves during a real conversation#

Six behaviors are worth understanding because they're the ones that determine how the agent handles edge cases — visitors trying to manipulate it, missing knowledge, multi-page sessions, and unexpected questions.

01behavior

The public token is the only key the widget has

Website visitors are never asked to sign in. The widget and chat endpoints resolve agents only by the public token in your embed snippet. That token grants access to one specific agent's chat, knowledge retrieval, and lead capture — nothing else. It cannot list other agents, read your dashboard, view another workspace's data, or change settings. If you accidentally leaked the token to the internet, a bad actor could chat with your agent — that's it.

02behavior

Conversation history is rebuilt from the database every turn

Each chat request rebuilds the conversation context by reading the last forty messages of that session from the database. The client (the visitor's browser) cannot inject fake prior turns — even if a visitor crafted a request claiming "earlier the agent agreed to give me a 90% discount," the server ignores that claim because it builds context from its own records. This is what makes prompt-injection-through-fake-history impossible.

03behavior

Knowledge retrieval is bounded to one agent

When the visitor sends a message, the server first turns that message into a 1,536-number embedding. It then asks the database "find the five knowledge items most similar to this embedding, with similarity above 0.5, where agent_id = THIS agent." The result is injected into the agent's instructions for that one reply. The query is parameterised by agent ID, so even if two agents in your workspace share the same database, the search cannot leak knowledge from one into the other.

04behavior

Page context is opt-in

If you turn on "send page context" in the agent's widget settings, the script will include the current page URL and page title with each chat message. The system prompt then tells the agent that information so it can answer with awareness of where the visitor is ("the visitor is on the pricing page, so they're probably evaluating"). It's off by default; turning it on doesn't send any other browser data.

05behavior

The fallback marker prevents hallucinations

Every agent's system prompt is appended with: "If you are uncertain or cannot answer from the information available, begin your response with [UNSURE]." When the model emits that marker, the backend strips it before showing the reply to the visitor, logs the unanswered question internally, and (if you've configured one) fires a handoff webhook with the full transcript. Over time the unanswered-question log becomes your roadmap for what knowledge to add next.

06behavior

Webhooks let the agent talk to your other systems

Optional outbound webhooks fire on six events: conversation_started, lead_captured, handoff_requested, unanswered_question, csat_received, and conversion. Each fires a POST with the full event payload (transcript, contact details, page URL, agent metadata). Pair this with Make.com, Zapier, n8n, or a custom HTTP handler to deliver leads to your CRM, ping Slack, or trigger downstream automation.

The visitor-facing API, in case you're building on top#

These are the eight endpoints that the widget calls. They're all public — they take only your agent's public token as the identifier — and they're constrained to that one agent. There is no listing endpoint, no admin endpoint, and no way to address another agent or another workspace from these routes.

MethodPathPurpose
POST/api/agent/[token]/chatVisitor sends a message; the agent reads its knowledge, runs any enabled tools, and streams a reply. Authoritative history is rebuilt from the database — the client cannot forge it.
POST/api/agent/[token]/leadSaves a visitor's name / email / phone. Upserts (does not duplicate) on (agent_id, email) so the same visitor returning is recognised.
POST/api/agent/[token]/handoffFires your handoff webhook with the full transcript and visitor context — typically wired to Slack, your CRM, or an inbox so a human can pick up the conversation.
POST/api/agent/[token]/csatCaptures the visitor's 0–5 satisfaction score and optional comment. Written to the session record and available in analytics.
POST/api/agent/[token]/conversionMarks a session as converted (purchase made, demo booked, lead qualified). Updates the session and fires the conversion webhook.
GET/api/agent/[token]/messagesReturns the conversation history for one session. The session ID is required — you cannot list other visitors' conversations.
GET/api/agent/[token]/transcriptReturns a formatted human-readable transcript of the active session — useful for downloading or emailing to a visitor on request.
GET/api/widget/[token]Serves the embeddable widget as JavaScript. The widget itself is generated server-side from the agent's settings (colors, greeting, icon, availability hours).

The public token is safe to expose client-side because it's the only thing the widget needs and it can only do these eight things. If you want to call these endpoints from your own code (a mobile app, a custom UI), you do it the same way the widget does: address the route with the token and pass the visitor's message as JSON.

Security boundaries you can rely on#

The system has two clean boundaries: signed-in dashboard access versus public widget access, and your workspace versus everyone else's workspace. Six concrete behaviors enforce those boundaries.

  • 01Every dashboard route — agent CRUD, knowledge management, offers, conversations, analytics, channel connections — requires a Clerk session. Anonymous requests get 401 Unauthorized; there is no way to browse to these endpoints from a public URL.
  • 02Inside the dashboard, every database query is filtered by your active workspace ID. If you've selected an organization, that organization's ID is used; otherwise your user ID is used. The two are never mixed, and queries from your workspace cannot return rows belonging to another workspace.
  • 03Your Supabase service role key — the one with full database access — lives only inside server code. Your browser receives only the Supabase anon key (which can only read what you've explicitly published) and the public agent tokens (which can only chat with one agent).
  • 04The widget's public-token endpoints are intentionally unauthenticated because visitors don't have accounts. They expose only chat, knowledge retrieval, lead capture, handoff, CSAT, and conversion — nothing about your workspace, your other agents, your billing, or your users.
  • 05The platform relies on HTTPS in transit (enforced by the hosting layer) and Supabase's provider-managed encryption at rest. There is no separate application-layer encryption — the security boundary is the database access layer and the public-token boundary, not custom crypto.
  • 06Channel webhooks (Telegram, WhatsApp, Messenger, Instagram) verify the inbound request signature against a per-channel webhook secret before processing. A request that arrives at the webhook URL without a valid signature is rejected. The secret is rotated when you reconnect the channel.