Your docs already answer
most support questions
Point this at your PDFs and your help centre, paste one script tag, and visitors get answers with citations instead of a contact form. The widget runs in a shadow root, so it cannot break your styles or be broken by them.
- Runs in a shadow root
- Use your own model keys at cost
- No card to start
Ask it something now
This is the live widget on this page's own knowledge base. Whatever you type here goes through the same retrieval and streaming path your visitors would hit.
Three steps, then it is live
Connect your material, decide how the assistant should behave, and paste one tag. Most of the work is in the first step, and the system does that part.
Connect your content
Drop in PDFs, Word docs, Markdown files, or paste your website URL. The system parses, chunks, and indexes your material for search automatically.
Tune your assistant and lead forms
Set custom system instructions, choose your brand colors, add starter prompts, and configure lead capture fields (Name, Email, Phone) for high-intent visitors.
Embed with one script tag
Copy the embed tag and paste it before your closing body tag. It works across React, Next.js, WordPress, Shopify, or plain HTML without stylesheet conflicts.
Tenant data isolation
Scoped Postgres queries and partitioned vector metadata keep each organization data strictly separated.
Model flexibility & BYOK
Use platform tokens or plug in your own OpenAI, Anthropic, or Google Gemini keys with zero token markup.
Fast token streaming
Server-Sent Events stream answers token by token with direct citations to the source documents.
Team management
Invite admins and team members with clear permission levels to manage documents and review captured leads.
Built for the awkward parts
Retrieval that finds the right passage, a widget that survives someone else's CSS, and lead capture that arrives attached to the conversation that produced it.
Hybrid RAG retrieval
Combines vector similarity search with BM25 keyword matching and a cross-encoder reranker. This helps prevent hallucinations and gives visitors direct footnotes linking to the exact source page.
// Hybrid retrieval with cross-encoder reranking
const candidates = await hybridSearch({
query: userPrompt,
tenantId: ctx.tenantId,
limit: 50
});
const rerankedChunks = await reranker.score({
query: userPrompt,
documents: candidates,
topK: 5
});
return generateStream({
context: rerankedChunks,
model: 'claude-3-5-sonnet',
citations: true
});Change it and watch it change
Colours, position, greeting, starter prompts and the lead form. The preview is the real component, not a screenshot.
Widget Configuration
<script
src="/widget.js"
data-key="embed_UdEBqR9OiuIvdGXMcdE76Pk8Wo0aejd0"
data-position="bottom-right"
data-primary-color="#2563EB"
data-theme="dark"
defer>
</script>Qchat Assistant
OnlineWork out whether the numbers help
Put in your ticket volume and see what deflection is worth against the token spend. If it does not add up for you, better to find that out here.
Estimate your monthly token usage
Estimate how many tokens you might need based on expected monthly conversations.
Projected Metrics & Savings
Pick a tier, or bring your own key
Every plan can fall back to platform credits. Bring your own provider key and you pay that provider directly, with nothing added on top.
- 100,000 Monthly Tokens
- Standard Widget
- Basic Document RAG (5 sources)
- 1 Embed Key · 2 Team Members
- Bring Your Own API Key (all providers)
- 500,000 Monthly Tokens
- Lead Capture Form & CRM
- Web Page Scraper (50 sources)
- 3 Embed Keys · 10 Team Members
- Custom Branding
- Bring Your Own API Key (all providers)
- 5,000,000 Monthly Tokens
- Unlimited Sources, Keys & Team Members
- Lead Capture Form & CRM
- Priority Support & SLA
- Dedicated Onboarding
- Bring Your Own API Key (all providers)
What keeps tenants apart
Multi-tenant support chat fails in one specific way: one customer seeing another customer's material. These are the controls that stop that, and where each one lives.
Tenant database isolation
Every query, document chunk, and chat session is filtered by tenant ID constraints in PostgreSQL. Organizations cannot see each other data.
CORS & domain allowlisting
Your embed keys only execute on authorized domains you specify. Unauthorized websites cannot load your widget or use your token balance.
AES-256 credential encryption
Custom BYOK API keys (OpenAI, Anthropic, Gemini) are encrypted at rest with AES-256-GCM before saving to the database.
Fixed-window rate limiting
Limits apply per embed key and per visitor address. Redis backs them when you configure it so the count holds across instances, and the limiter falls back to in-process counting rather than taking the API down if Redis goes away.
Shadow DOM encapsulation
Widget HTML and CSS render inside an isolated Shadow Root, keeping your website stylesheets free from style collisions.
Health checks and usage metering
A liveness endpoint reports whether the process can still reach its database, and token spend is metered per tenant with a reservation taken before generation so a burst of parallel requests cannot overrun a quota.
Claims you can go and verify
No logos and no testimonials, because we have not earned them yet. Here are the measurable things instead, each pointing at the file that implements it.
The whole embed, compressed. Measured from the build output.
One line before your closing body tag. No build step.
Applies to provider keys you bring yourself.
Bring your own key and you pay your provider directly.
The widget cannot inherit your CSS
It renders inside a shadow root, so your stylesheets and the widget stylesheets never see each other. This is the reason it drops into WordPress and Next.js the same way.
src/widget/index.tsTenant scoping is in the query, not a filter
Every read carries its tenant id in the SQL itself rather than trimming results afterwards. There is a test suite whose only job is to fail if that stops being true.
tests/tenant-isolation.test.tsYour provider keys are encrypted before they are stored
AES-256-GCM with a fresh random IV per record. The dashboard shows you a masked version and the API never returns the real one, not even to you.
src/lib/crypto.tsAnswers stream token by token
You see the first words while the model is still writing the rest, because the response is a real SSE stream rather than a finished reply replayed on a timer.
src/app/api/v1/widget/chat/route.tsRetrieved pages are treated as data, never instructions
Anything pulled from a knowledge base is fenced in document tags and the system prompt says to ignore instructions found inside them. Whoever can add a page cannot hijack the assistant.
src/lib/rag.tsRate limits are enforced per key and per visitor
A fixed window, backed by Redis when you configure it and in-process when you do not. If Redis goes away the limiter degrades instead of taking the API down with it.
src/lib/rate-limit.tsQchat is young enough that we would rather point at the code than at a wall of logos. Every claim above names the file that implements it, so you can check the ones that matter to you before you trust any of them.
The questions that come up first
Mostly about limits, keys and what happens when the model does not know something.
Under five minutes. Create your account, upload your documents (PDF, DOCX, TXT) or paste a website URL, set your brand color, and copy the script tag to your site.
Ask a person instead
If your situation is unusual, or you want to know whether this fits before you sign up, write to us here and we will answer properly.