ReferralMD Reports Assistant  /  Install the widget
Embeddable Widgets

Install the Reports Assistant

The assistant ships as two embeddable widgets sharing the same brain (POST /api/ask): an inline ask bar that sits in the page like a data tool, and a floating chat bubble like an Intercom messenger. Both are one-script-tag installs, isolated in a shadow root so styles never conflict with the host page.

1Pick a form factor and add the snippet

Option A — inline ask bar (embed.js) · recommended for reports pages. Renders in the page flow, so it reads as a reporting tool and stays away from the support chat’s corner. Place the div where the bar should appear (on the RMD reports pages: between the filter row and the first report card). Replace HOST with the assistant server’s origin.

<!-- where the ask bar should render -->
<div id="rmd-reports-ask"></div>

<!-- the widget — answers stream from HOST/api/ask -->
<script src="https://HOST/embed.js" defer></script>

Option B — floating chat bubble (embed-chat.js). The launcher-and-panel chat, for pages without a competing chat widget. No mount div needed — it appends itself to <body>:

<script src="https://HOST/embed-chat.js" defer></script>
⚠️ Don’t stack chat bubbles. If the page already shows the support chatbot in the bottom-right corner, either use Option A, or move this one with data-position="bottom-left". Two bubbles in one corner will overlap.

Either way, that’s the whole install — the widget mounts itself when the page loads.

2Configure (optional)

Defaults work out of the box. Override with data attributes on the script tag:

AttributeApplies toWhat it doesDefault
data-api both Base URL of the assistant server (where POST /api/ask lives). the script tag’s own origin
data-target ask bar CSS selector of the element the widget mounts into. #rmd-reports-ask
data-position chat bubble Corner for the launcher: bottom-right or bottom-left. bottom-right

For deeper customization — placeholder text or the suggestion chips — define a global before the script tag (window.RMDReportsAsk for the ask bar, window.RMDReportsChat for the chat bubble, which also accepts title and greeting):

<script>
  window.RMDReportsAsk = {
    placeholder:  "Ask about your referrals…",
    suggestions: [
      "How many referrals did we get this month?",
      "Who are our top referring providers?"
    ]
  };
</script>
<script src="https://HOST/embed.js" defer></script>

Data attributes win over the global when both set the same option.

3Check the server side

The widget is UI only — questions are answered by the assistant server (node src/server.js), which runs the agent loop server-side so AWS/Bedrock credentials and the ReferralMD API key never reach the browser.

4Run as the signed-in user

Today (demo): the assistant server signs every ReferralMD API call with a single, hardcoded HMAC key (RMD_API_KEY / RMD_API_SECRET from .env). Every question — no matter who asks — runs as that one account and sees that account’s data. Fine for a demo; not acceptable in production, where answers must respect the signed-in user’s organization, locations, and permissions.

Production: forward the user’s own session. The widget lives on a page where the user is already signed in to ReferralMD, so their referralMD session cookie and X-XSRF-TOKEN already exist in the browser. The plan is to ride that session instead of the shared key:

browser (signed-in RMD user)
   │  fetch("/assistant/api/ask", { credentials: "include" })
   │  → the user's own referralMD cookie + XSRF token ride alongassistant server (same domain, or proxied under /assistant/*)
   │  reads Cookie + x-xsrf-token off the INCOMING request
   │  runs the agent loop with that per-request session
   ▼
ReferralMD API — the query executes as the signed-in user,
with their org scoping and permissions. No shared key involved.
🔒 Until per-user sessions are wired in, don’t expose the widget to real users. With the shared HMAC key, every visitor would see whatever the key’s account can see — a data scoping hole, and the key’s account effectively bypasses per-user audit trails.
💡 What renders in an answer: streamed “thinking” steps while the agent works, the answer itself, charts built from the report data (never drawn by the LLM), and source links to the exact report pages the numbers came from. Follow-up questions keep conversational context; “New conversation” resets it.
⚠️ Keep the support chat separate. The ask bar renders inline in the page flow and never floats over the lower-right corner; the chat-bubble option must be positioned away from the support chatbot (data-position="bottom-left"). Don’t mount either widget inside the support chat’s container.
Open the ask-bar demo → Open the chat-bubble demo → Original chat demo page