Roxels/ docs
embed

Install the embed

The embed is a single script served from https://app.roxels.ai/embed.js. It's unversioned and loaded live — once you include it, every fix and improvement ships automatically.

The three install styles

Pick the one that matches your control needs.

Style 1: One script tag, autoinit

The simplest path. The script reads its own data-* attributes and initializes itself. Roxels renders a floating button; the user clicks it to start.

<script src="https://app.roxels.ai/embed.js" data-template-key="rk-your-embed-key"></script>

Optional data-* attributes:

<script
  src="https://app.roxels.ai/embed.js"
  data-template-key="rk-your-embed-key"
  data-person-name="Ada Lovelace"
  data-external-id="user_123"
  data-view="checkout"
></script>
  • data-person-name — Display name for the participant (passed to the agent).
  • data-external-id — Your stable identifier for this user (returned in onComplete, used for session resumption).
  • data-view — Page identifier used by the persistent launcher's visibility rules.

Style 2: Manual init

You control when initialization happens — useful for SPAs that mount the embed after a route change, or when you want to pass callbacks.

<script src="https://app.roxels.ai/embed.js"></script>
<script>
  Roxels.init({
    templateKey: "rk-your-embed-key",
    personName: "Ada Lovelace",
    externalId: "user_123",
    onComplete: (results) => {
      console.log("Conversation complete:", results);
    },
    onUnderstanding: (data) => {
      console.log("Goal data captured:", data);
    },
    onClose: () => console.log("widget closed"),
    onError: (error) => console.error("widget error:", error),
  });
</script>

After init, the floating button appears (if the template has a persistent launcher configured). The user clicks it to open a conversation.

Style 3: Programmatic start

You skip the floating button entirely and call start() whenever you want. Best for triggering conversations from your own UI — a button you control, a form submission, a route transition.

<script src="https://app.roxels.ai/embed.js"></script>
<script>
  document.querySelector("#start-call").addEventListener("click", () => {
    const call = Roxels.start({
      templateKey: "rk-your-embed-key",
      display: "modal",
      personName: "Ada Lovelace",
      externalId: "user_123",
    });
    call.on("complete", (results) => {
      console.log("done:", results);
    });
  });
</script>

For full headless control (no UI from Roxels at all), use display: "none" and read Headless mode.

Init options

These can be passed to Roxels.init(), Roxels.start(), Roxels.open(), or set as data-* attributes (kebab-case).

Option Type Description
templateKey string Your rk_… embed key. Required unless you pass sessionId.
sessionId string An existing session id (server-side created). Skips template-key session creation.
personName string Display name for the participant.
externalId string Your stable identifier for this user.
view string Page identifier used by launcher visibility rules.
display "modal" | "compact" | "none" Presentation. Defaults to "modal".
onUnderstanding function Called on each goal-data update.
onComplete function Called when the conversation finishes with the final result.
onClose function Called when the widget closes (any reason).
onError function Called on any embed-level error.
onGoalTransition function Called when a goal commits or the active goal changes.
fabAnchor string | HTMLElement CSS selector or element to anchor the floating button to.
fabContainer string | HTMLElement Container element for the floating button.

Server-side session creation

If you want to create the session in your backend (more control, no embed key on the client), use the REST API to create a session, then pass the sessionId to the embed:

<script src="https://app.roxels.ai/embed.js"></script>
<script>
  // sessionId came from your backend
  Roxels.start({ sessionId: "sess_abc123", display: "modal" });
</script>

This path uses your server's bearer token (sk_…) to create the session and never exposes a publishable key to the browser. Useful when you want to encode trusted context into the session before the user joins.

Domain allowlisting

Embed keys are scoped to the origins you whitelist when you create the key. If your page is at https://example.com and your key isn't allowlisted for that domain, the session-creation call fails. Allowlist all origins where the widget runs (production, staging, http://localhost:3000 during dev).