Roxels/ docs
getting started

Quickstart

By the end of this page you'll have a working Roxels conversation embedded on a page you control.

You'll need

  • A Roxels account at app.roxels.ai.
  • A template, created from the dashboard.
  • An embed key (also called a publishable key, starts with rk_).
  • A page on your site where you can add a <script> tag.

Steps

1. Create a template

Sign in at app.roxels.ai. From the dashboard, create a new template. The template defines what the conversation is about — greeting, goals to capture, language, voice. You can iterate on it later.

2. Generate an embed key

In the template's settings, generate an embed key. It starts with rk_.

Embed keys are domain-allowlisted: you list the origins that are allowed to start a session with the key. Set the allowlist to the domains where the widget will run (e.g. https://example.com, http://localhost:3000 during development).

3. Add the embed script

On the page where the widget should appear, add:

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

A floating button appears in the bottom-right corner. Click it to start a conversation.

4. Customize (optional)

If you want to pass an identity through, or customize the button, initialize manually instead of relying on the data-attribute autoinit:

<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);
    },
  });
</script>

See the JS API reference for every option.

What you'll have

A working voice conversation embedded on your site, governed by the template you authored in the dashboard. The widget handles microphone capture, audio playback, and the LiveKit connection — your page never touches WebRTC.

Common first stop: microphone permissions

If the widget loads but the microphone is blocked, your host is sending a Permissions-Policy header that doesn't allow the embedded iframe to use the microphone. The fix is a one-line header change — see Microphone permissions.

Next steps

  • Build your own UI instead of using the widget? See Headless mode.
  • Customize the floating button (when it shows, what it says, where it sits)? See Persistent launcher.
  • Receive results in your backend? See Webhooks.
  • Author templates programmatically? See Templates and the REST API.
  • Use Claude Code or Cursor to set things up? See MCP.