Documentation
Widget developer reference
The complete embed contract for the By Your Side widget. For the friendly walkthrough, see Add the widget. This page is the technical detail for developers and AI coding agents.
The one-tag install
The widget is a single script. It appends a floating launcher to the page, rendered inside a Shadow DOM so it cannot affect, or be affected by, your site's CSS. Place it just before </body>.
<script src="https://www.byourside.ai/widget.js"
data-key="bys_pk_xxxxxxxxxxxx"
data-brain="https://api.byourside.ai"
data-name="By Your Side"
data-grad-start="#6F6BEA"
data-grad-end="#2F73F2"></script>The loader is served from your By Your Side app domain, and the snippet generated in your dashboard already contains the correct src, data-key, and data-brain for your account. Treat the values below as the contract, not as copy-paste credentials.
Data attributes
| Attribute | Required | Description |
|---|---|---|
data-key | Yes | Public embed key (bys_pk_…). Safe to ship in HTML; security comes from the origin allowlist. |
data-brain | Yes | Brain API base URL, for example https://api.byourside.ai. A trailing slash is trimmed. |
data-agent | No | Agent id. Usually left empty: the key is already bound to one assistant. Set it to force a specific assistant. |
data-name | No | Title shown in the widget header. Defaults to the business name returned by the brain. |
data-grad-start | No | Gradient start color, hex only (e.g. #6F6BEA). |
data-grad-end | No | Gradient end color, hex only (e.g. #2F73F2). |
data-color | No | Convenience alias for data-grad-start. |
Color values are validated as #hex (3 or 6 digits). Anything else is dropped and the default brand gradient is used. data-key and data-brain are both required, or the widget logs an error and does nothing.
Programmatic install
When the script is injected by code (so document.currentScript is null), read config from window.BYourSideWidget instead. Set it before the loader runs. Script attributes win over this object when both are present.
// Set the config BEFORE the loader runs, then inject the loader.
// Useful in SPAs or when document.currentScript is null.
window.BYourSideWidget = {
key: "bys_pk_xxxxxxxxxxxx",
brain: "https://api.byourside.ai",
name: "By Your Side",
// optional:
// agent: "", // agent id (the key is usually already bound to one)
// gradStart: "#6F6BEA",
// gradEnd: "#2F73F2",
// color: "#6F6BEA", // alias for gradStart
};
const s = document.createElement("script");
s.src = "https://www.byourside.ai/widget.js";
document.body.appendChild(s);What it renders
- A floating launcher button (bottom-right), opening a panel with a welcome view, a chat thread, and a voice-call view.
- Everything lives in a Shadow DOM on a single host element, so there is no global CSS bleed in either direction.
- The voice call asks for a callback email or phone before connecting, then negotiates WebRTC audio with the assistant.
Endpoints it calls
You do not call these yourself, the loader does. They are documented so you know what network traffic to expect and what to allow in a CSP. All are authed by the embed key plus the Origin header.
Start a session
POST {brain}/widget/session
Origin: https://yourdomain.com
Content-Type: application/json
{ "key": "bys_pk_...", "agentId": "", "mode": "chat" } // mode: "chat" | "call"// chat
{ "ok": true, "businessName": "Acme Co", "sessionToken": "..." }
// call (mode: "call") adds a short-lived, scoped call token
{ "ok": true, "businessName": "Acme Co",
"callToken": "...", "scope": "assistant", "rtcPath": "/rtc" }
// failure
{ "ok": false, "error": "forbidden" } // bad key or origin not allowed
{ "ok": true, "callError": "call_unavailable" } // chat works, call could not startSend a chat message
Read-only: the answer is grounded in the business knowledge. No spend, no side effects.
POST {brain}/widget/message
Origin: https://yourdomain.com
Content-Type: application/json
{ "key": "bys_pk_...", "agentId": "",
"question": "Do you ship internationally?",
"sessionToken": "...",
"history": [ { "role": "user", "content": "hi" },
{ "role": "assistant", "content": "Hello!" } ] }{ "answer": "Yes, we ship to most countries..." }Voice call
For mode: "call", the widget opens a WebSocket at the brain host with the http scheme swapped for ws, on the returned rtcPath (default /rtc). It exchanges hello → offer → answer → bye messages and a non-trickle SDP offer (ICE gathered before sending). Microphone permission is required, and it must start from a user gesture.
Auth and origins
- The embed key is a public key. It is meant to be visible in client HTML.
- Security is the origin allowlist: a key only works when the request's
Originis on the list you set in the dashboard. The www and root hosts are both added for you. - Pages served from a non-allowed origin (including localhost, unless you add it) get a
403and the widget will not function.
Framework snippets
Next.js
// app/layout.tsx (or any layout that wraps every page)
import Script from "next/script";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
<Script
src="https://www.byourside.ai/widget.js"
strategy="afterInteractive"
data-key="bys_pk_xxxxxxxxxxxx"
data-brain="https://api.byourside.ai"
data-name="By Your Side"
/>
</body>
</html>
);
}Google Tag Manager
New Tag → Custom HTML → paste the HTML snippet → trigger on All Pages. Note that GTM must itself load on the allowed domain.
Content-Security-Policy
If your site sends a CSP, allow these sources:
script-srcyour By Your Side app domain (wherewidget.jsis served).connect-srcyour brain URL overhttpsandwss(for chat and the voice call).style-srchttps://fonts.googleapis.comandfont-srchttps://fonts.gstatic.com(the widget imports one webfont).
Hand this to an AI coding agent
A single, self-contained instruction. Paste it into your coding tool (Claude, Cursor, and so on) after replacing the placeholder key.
Add the By Your Side website widget to this project.
1. Insert this exact tag just before the closing </body> tag so it loads on
every page. In a framework (Next.js, etc.) use the framework's script
mechanism in the root layout instead of editing raw HTML.
<script src="https://www.byourside.ai/widget.js"
data-key="bys_pk_REPLACE_WITH_REAL_KEY"
data-brain="https://api.byourside.ai"
data-name="By Your Side"></script>
2. Do not change data-brain. Replace only the data-key with the real public
embed key (starts with bys_pk_). The key is safe to ship in client HTML.
3. The widget only loads when the page is served from a domain that was added
to the key's allowlist in the By Your Side dashboard. Localhost will not
load unless it was allowed. Add the production domain to the key.
4. If a Content-Security-Policy is present, allow:
- script-src https://www.byourside.ai
- connect-src https://api.byourside.ai wss://api.byourside.ai
- font-src https://fonts.gstatic.com
- style-src https://fonts.googleapis.com (the widget imports one webfont)