Integration guide

Add the assistant with one line

Paste a script tag on the client’s website. The chat opens in an isolated iframe, answers only from that client’s own content, and cites its sources.

Quickstart

  1. Crawl the client website with ingest enabled (backend Swagger, Admin · Crawl, with auto_ingest: true). Its pages become the assistant’s knowledge base.
  2. Create the site. This prints the snippet with its site token:
bash
cd apps/api
pnpm site create --tenant <tenant id> --name "Client name" \
    --domain https://www.client.com --domain https://client.com
  1. Paste the snippet before </body> on every page:
html
<script src="https://<widget host>/widget.js" data-site-token="st_…" async></script>

That is the whole snippet: colour, side, title and greeting live in the site’s configuration and change without touching the client’s website. Optional attributes override them on one page only:

html
<script src="https://<widget host>/widget.js" data-site-token="st_…"
  data-position="bottom-left"        <!-- bottom-right|-left|-center, top-…, left-center, right-center -->
  data-offset="24"                   <!-- px from the screen edge -->
  data-width="400" data-height="640" <!-- largest panel size: px, %, vw, vh, rem -->
  data-container="#chat"             <!-- show the chat inside this element, no launcher -->
  data-title="Support" data-subtitle="We reply in seconds"
  data-greeting="Hi! How can I help?" data-placeholder="Ask anything…" data-avatar-text="M"
  data-accent-color="#F05A2A" data-accent-text-color="#fff"
  data-background-color="#fff" data-chat-background-color="#f6f7fb"
  data-text-color="#1f2937" data-muted-color="#6b7280" data-border-color="#e5e7eb"
  data-radius="rounded"              <!-- square | rounded | pill -->
  data-font="Inter"                  <!-- a Google Font name -->
  async></script>

Colours accept any plain CSS colour; anything else is ignored. Answers are formatted (lists, bold, links) and cite their sources; the visitor can expand the chat to full screen.

Custom attributes

A page can also pass its own key-value pairs to the chatbot, for example the signed-in visitor’s plan. The site declares which names it accepts in the admin panel (Widget → Custom attributes); any other data-* attribute is ignored. An accepted value can be used as {{name}} in the chatbot’s instructions and in the widget’s title, subtitle, greeting and placeholder.

html
<script src="https://<widget host>/widget.js" data-site-token="st_…"
  data-plan="pro"                    <!-- declared as "plan" in the admin panel -->
  data-company="Acme"                <!-- declared as "company" -->
  async></script>

Instructions:  The customer works at {{company}} and is on the {{plan}} plan.
Greeting:      Hi! How can we help {{company}} today?

Each value is cleaned (no line breaks or braces) and cut to the length set for it, and a name with no value falls back to its default. Values are personalisation only: anyone can edit a page, so never use one to decide what a visitor may see. From React, pass attributes={{ plan: "pro" }} to ChatbotWidget, or attributes to MyraChat.init.

Keys

Every website has a default key, and you can add named keys (Widget → Embed keys), each with its own allowed origins: one for the live site, one for staging. A key can be copied as ready-made embed code, rotated (the old token keeps working for 24 hours) or revoked (the widget disappears from pages that use it).

Configure a site

bash
pnpm site update <site_id> --position left --color "#F05A2A" \
    --title "Ask Client" --greeting "Hi! How can I help?"
pnpm site update <site_id> --prompt "You are Client's friendly assistant." --top-k 6
pnpm site update <site_id> --messages-per-day 5000 --tokens-per-day 1000000
pnpm site update <site_id> --disable            # assistant off, launcher stays
pnpm site rotate <site_id> --grace-hours 24     # new token; old one stops after 24 h
pnpm site revoke <site_id>                       # the widget removes itself

Changes apply within seconds on every server. A custom prompt sets the assistant’s persona; the rules that keep answers grounded in the client’s content and cited are always added.

JS API

The script defines window.MyraChat:

js
MyraChat.open();    // e.g. from your own "Chat with us" button
MyraChat.close();
MyraChat.toggle();
MyraChat.destroy(); // remove the launcher and the chat from the page

// Without data-* attributes: load widget.js, then pass the same options in camelCase.
MyraChat.init({ siteToken: 'st_…', position: 'bottom-left', accentColor: '#F05A2A' });

React and Next.js sites can use the package instead of the script tag:

tsx
npm install @myra-technolabs/chatbot-widget

import { ChatbotWidget } from '@myra-technolabs/chatbot-widget';

<ChatbotWidget siteToken="st_…" widgetUrl="https://<widget host>" position="bottom-left" />

How it stays safe

The site token is public
It only selects your site. Anyone can read it in your page source, and that is fine: it grants nothing on its own.
Your domains only
The server checks the browser’s Origin against the domains registered for the site. Other websites get no widget.
Short visitor sessions
After that check each visitor gets an anonymous session that expires within an hour and is renewed automatically.
Limits built in
Rate limits per visitor, per site and per IP, plus daily quotas, keep abuse and cost in check.

The widget talks only to the chat API. It never sees the backend, a service key or an admin key, and it never decides which tenant’s content is searched: the server takes that from the site.

Troubleshooting

No launcher appearsCheck the browser console. “not allowed for this site token” means this domain is not in the site’s allowed domains; add it with `pnpm site update <site_id> --domain https://…`.
The widget disappearedThe site was revoked or archived, or the token was rotated and its grace period ended (HTTP 410). Use the current snippet.
“Too many messages”A visitor hit the per-minute rate limit. It clears by itself after the time shown.
“Not available right now”The assistant is switched off for the site, or the site used up its daily quota. It resets at 00:00 UTC.
Answers say “No relevant info found”Nothing in the site’s knowledge base matched. Check that the site was crawled and ingested for this tenant.