Knowledge base & forms
Let users search your knowledge base and submit ticket forms without leaving your app.
const articles = await chat.searchArticles("how do I update billing");
await chat.showArticle(articles[0].id);
await chat.showTicketForm("contact", {
prefill: { summary: "Cannot log in", severity: "high" },
});searchArticlesreturns only published, end‑user‑visible articles.- Ticket forms are one‑way intake. Submitting a form creates an issue in
your inbox (agents triage it like any other ticket) and shows the user a
confirmation screen — it does not open a chat thread and never appears in
the user's conversation list. Since there's no thread for the user to read, the
agent "Reply to customer" composer is disabled for these issues (internal
notes still work).
form:submittedfires on submit; unknown prefill fields are ignored.
AI assistant chat
When AI answers are enabled, the in‑widget search becomes a conversational AI assistant. The user types a question, presses Enter, and lands in a back‑and‑forth chat: the assistant answers from your help center, asks a clarifying follow‑up when the question is ambiguous, and keeps context as the user asks more. The source articles it used collapse into a "Related articles" dropdown at the bottom of the chat.
It behaves like a support rep trained on your public docs — and is built to be honest:
- Every reply is grounded only in your published, end‑user‑facing KB articles — internal or draft articles are never used and can never leak into a reply. Optionally scoped further to the widget's enabled KB collections.
- If the question is unclear, it asks a short clarifying question instead of guessing.
- If the docs don't cover the question, it says so plainly and offers a "Start a conversation" button to reach a human.
Conversations are saved. Each AI chat (the turns + the asker's identity and page/locale/device metadata) is persisted server‑side so your team can review what users ask and where the docs fall short. AI chats are deflections — they do not create inbox tickets; only escalating to a human does.
Enabling it. The assistant turns on when both
features flags are set (from your
install code or the widget config):
window.SupportChatSettings = {
workspaceId: "{YOUR_WORKSPACE_ID}",
widgetId: "{YOUR_WIDGET_ID}",
features: { knowledgeBase: true, aiAnswers: true }, // search → AI assistant chat
};knowledgeBaseprovides the articles the assistant is grounded in.aiAnswersturns the search bar into the assistant chat.- Set the widget's
ai.modetohuman_firstto disable the assistant and route users straight to a human. WithaiAnswersoff, the search bar stays a plain published‑article search.
Replies are generated server‑side; the widget only ever receives the final message text and the public article list. (A one‑shot, non‑conversational variant is also available programmatically at
POST /widget/v1/ai/answer.)
Where ticket forms come from
Ticket forms render out of the box in the widget — you don't build any form UI. They are data‑driven: the content of a form (its name and fields) is defined in the dashboard, while whether and when it shows can be driven from code:
- Define forms in the dashboard: Settings → Integrations → Web Widget →
Ticket forms. Create/edit/delete forms with a field builder (text, textarea,
email, select, image), toggle each form on/off, and choose which forms appear.
One‑click Bug report and Feature request templates are available.
(Equivalently via the admin API —
GET/POST/PATCH/DELETE /api/widget-admin/forms.) Form definitions cannot be authored from install code. - Image uploads (screenshots): an
imagefield lets users attach a screenshot (e.g. on a bug report). Uploads are image‑only and size‑capped, stored privately, and surfaced on the agent's issue card via short‑lived signed URLs — not shown back inside the widget. - Surface them automatically: when the
ticketFormsfeature is enabled and at least one enabled form exists, the widget home shows the forms as "Quick requests" cards near the top. The Live chat entry point ("Send us a message") stays anchored to the bottom of the home screen, and past conversations live on their own page. - Or open one from code:
chat.showTicketForm(slugOrId, { prefill })opens a specific form on demand (e.g. from a button in your app), optionally pre‑filling fields.startConversation({ formId })is also supported. - Control visibility from code: the
featuresoverride (ticketForms: false) hides the forms surface for a given page;ticketForms: trueshows it but still only renders forms that exist and are enabled server‑side.