Now in early access·Start your 14-day free trial →
By Your Side
Sign inBook a demoStart free trial

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>.

HTML
<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

AttributeRequiredDescription
data-keyYesPublic embed key (bys_pk_…). Safe to ship in HTML; security comes from the origin allowlist.
data-brainYesBrain API base URL, for example https://api.byourside.ai. A trailing slash is trimmed.
data-agentNoAgent id. Usually left empty: the key is already bound to one assistant. Set it to force a specific assistant.
data-nameNoTitle shown in the widget header. Defaults to the business name returned by the brain.
data-grad-startNoGradient start color, hex only (e.g. #6F6BEA).
data-grad-endNoGradient end color, hex only (e.g. #2F73F2).
data-colorNoConvenience 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.

JavaScript
// 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

Request
POST {brain}/widget/session
Origin: https://yourdomain.com
Content-Type: application/json

{ "key": "bys_pk_...", "agentId": "", "mode": "chat" }   // mode: "chat" | "call"
Response
// 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 start

Send a chat message

Read-only: the answer is grounded in the business knowledge. No spend, no side effects.

Request
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!" } ] }
Response
{ "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 helloofferanswerbye 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 Origin is 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 403 and the widget will not function.

Framework snippets

Next.js

TSX
// 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-src your By Your Side app domain (where widget.js is served).
  • connect-src your brain URL over https and wss (for chat and the voice call).
  • style-src https://fonts.googleapis.com and font-src https://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.

Instruction for an AI coding agent
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)