Add Yar to your site in one script tag
A streaming, source-cited support chat that answers from your own documents. No build step, no dependencies — copy four lines, and a chat bubble appears in the corner of your page.
01Quick start
This is the whole integration. Paste it before </body> on any page — a plain HTML site, WordPress, Webflow, whatever you're running.
<script src="http://87.107.105.247:8001/static/yar-chat.js"></script>
<script>
YarChat.init({
host: 'http://87.107.105.247:8001',
kb_id: 'your-knowledge-base-id',
publishable_key: 'pk_live_...',
});
</script>
02Get your knowledge base ID and publishable key
Everything here happens once per site. Two ways to do it — pick whichever fits your workflow. Both produce the same credentials.
Option A — the dashboard
Go to /dashboard/register/ and give your business a name. You'll get a secret key (starts with sk_live_) — copy it somewhere safe now, it's shown exactly once and is your login for the dashboard. Log in, create a knowledge base, and upload whatever you want the assistant to answer from (PDF, DOCX, HTML, TXT). Open the knowledge base and copy its ID out of the address bar — the UUID right after /knowledge-bases/.
Option B — pure API, no browser required
Everything above has a JSON equivalent, so you can wire up a new customer's account entirely from a script or your own backend.
1. Register a tenant — this single call creates your account and hands back your secret key. It's shown only in this response, so save it immediately.
curl -X POST http://87.107.105.247:8001/api/v1/tenants/ \
-H "Content-Type: application/json" \
-d '{"name": "Acme Corp", "slug": "acme-corp"}'
{
"id": "3f9a1c...",
"name": "Acme Corp",
"slug": "acme-corp",
"is_active": true,
"created_at": "2026-07-08T12:00:00Z",
"secret_key": "sk_live_..."
}
2. Create a knowledge base — authenticate with the secret key as a Bearer token from here on:
curl -X POST http://87.107.105.247:8001/api/v1/knowledge-bases/ \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"name": "Support Docs"}'
The response's id is your kb_id — save it for the snippet below.
3. Upload a document to that knowledge base (repeat per file):
curl -X POST http://87.107.105.247:8001/api/v1/knowledge-bases/kb_id/documents/ \ -H "Authorization: Bearer sk_live_..." \ -F "file=@handbook.pdf"
Upload returns 202 immediately; the document is chunked, embedded, and indexed in the background. Poll GET /api/v1/knowledge-bases/{kb_id}/documents/{doc_id}/ until its status field reads indexed.
4. Create a publishable key — safe to embed in public HTML, it can only open a chat session:
curl -X POST http://87.107.105.247:8001/api/v1/tenants/tenant_id/api-keys/ \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{"tier": "publishable"}'
The response's key field is your pk_live_... — drop it straight into the widget snippet.
Authorization: Bearer sk_live_... is required on every tenant, API key, knowledge base, and document endpoint except the initial registration call — and a secret key only ever works against the tenant it was issued for.
03Add the widget
Same snippet as the quick start, with your real values filled in. That's the entire integration — the bubble, panel, streaming, and error handling are all built in.
<script src="http://87.107.105.247:8001/static/yar-chat.js"></script>
<script>
YarChat.init({
host: 'http://87.107.105.247:8001',
kb_id: '3f9a1c...',
publishable_key: 'pk_live_9kD...',
title: 'Ask us anything',
});
</script>
Using React, Vue, or a bundler instead of a plain script tag? See the notes section for the ESM import.
Configuration options
| Option | Default | Description |
|---|---|---|
host | — required | Your Yar server origin. |
kb_id | — required | Knowledge base the widget queries. |
publishable_key | — required | Your pk_live_* key. |
title | "Chat" | Header text in the widget panel. |
placeholder | "Ask a question..." | Input box placeholder text. |
position | "bottom-right" | "bottom-right" or "bottom-left". |
theme | {} | CSS variable overrides — see below. |
Theming
Pass a theme object to match your brand. Anything you don't set keeps its default.
YarChat.init({
host: '...', kb_id: '...', publishable_key: '...',
theme: {
'--yar-primary': '#16a34a', // bubble, header, send button
'--yar-bg': '#ffffff', // panel background
'--yar-text': '#111827', // message text
'--yar-radius': '12px', // corner rounding
'--yar-width': '380px', // panel width
},
});
The panel automatically goes full-screen below 440px viewport width, so mobile doesn't need separate handling.
Controlling the widget
YarChat.init() returns a controller, in case you want a custom "chat with us" button instead of relying on the built-in bubble:
const chat = YarChat.init({ /* ... */ });
chat.open(); // open the panel
chat.close(); // close the panel
chat.destroy(); // disconnect and remove from the page
What visitors see
| Situation | Shown in the panel |
|---|---|
| Connecting | "Connecting…", input disabled |
| Connected | Status clears, input enabled |
| Brief network drop | "Reconnecting… (1/3)" with backoff, then (2/3), (3/3) |
| Reconnect attempts used up | "Could not connect. Please refresh." |
| Wrong or revoked key | "Invalid API key." |
| A secret key was used by mistake | "Publishable key required." |
| Assistant temporarily unavailable | Inline error, input re-enabled so the visitor can retry |
Notes
Using a bundler (React, Vue, Next.js)
import YarChat from '@yar/chat-widget'
useEffect(() => {
const chat = YarChat.init({ host: '...', kb_id: '...', publishable_key: '...' })
return () => chat.destroy()
}, [])
87.107.105.247:8001) while a permanent domain is set up. It works everywhere today, but browsers will eventually want a matching HTTPS origin if your own site is served over HTTPS — ask us if that's blocking you and we'll move this up.