FruxonDocs

Embed Widget

Drop a Fruxon agent into your own website as a chat widget for anonymous visitors

The Embed Widget puts one of your agents on your own website as a chat bubble. Visitors don't sign in to Fruxon — they open the widget, type, and talk to the agent. It's the public, anonymous front door to an agent: support deflection on a docs site, a product assistant on a landing page, a concierge on a storefront.

Under the hood it's a small loader script that mounts a sandboxed <iframe>; the iframe talks to a dedicated anonymous gateway that's scoped to exactly one agent by a publishable embed key.

The widget runs against the agent's Production budget and revision — embedded traffic is real production traffic. Sessions are anonymous visitors, not Fruxon users or participants you manage by hand.

How it fits together

 your site ──script──▶ iframe (chat UI) ──HTTPS──▶ Fruxon embed gateway ──▶ agent
            embed key                 session token        (one agent, anonymous)
PieceWhat it is
Embed configA per-agent configuration that mints a publishable key and sets the origin allowlist, greeting, suggested prompts, and theme.
Publishable key (emk_…)Goes in your page's HTML. Like a Stripe publishable key, it's not a secret — it only opens an anonymous session against one agent, gated by the origin allowlist.
Session tokenMinted when a visitor opens the widget. Short-lived (15 minutes, auto-refreshed), pinned to one session + agent + visitor. The page never sees it — only the iframe does.
GatewayA public, unauthenticated-to-open endpoint set that drives the conversation: open a session, send a turn, stream replies, poll history, refresh, close.

Configuring an agent for embedding

An embed config lives under an agent and carries:

FieldMeaning
Publishable keyThe emk_-prefixed key you put in the embed snippet. Globally unique; rotate it to invalidate the old one.
EnabledMaster switch. A disabled config rejects new sessions while keeping past history.
Allowed originsThe web origins permitted to embed the widget — e.g. https://example.com. A single * allows any origin. An empty list allows none.
GreetingThe first message shown when the panel opens.
Suggested promptsQuick-start chips a visitor can tap instead of typing.
ThemeAn opaque client theme blob (colors, launcher icon, position, locale) interpreted by the widget, not the server.

The origin allowlist is hygiene, not a hard security boundary. A browser reports its origin honestly, but a non-browser client can spoof it — so the allowlist keeps your widget off other people's sites, but the publishable key plus the agent's tools and budget are your real blast-radius controls. Scope the embedded agent's tools to what an anonymous visitor should be able to reach, and keep its Production budget capped.

Anonymous visitors

Each browser that opens the widget becomes an anonymous participant bound to that one agent. A visitorKey persisted in the browser gives a returning visitor conversational continuity. These anonymous identities are garbage-collected automatically (reaped ~30 days after creation), so the widget doesn't accumulate stale identities — embedded traffic stays self-cleaning.

Today, embed configs are created and managed through the API (the endpoints below); the in-product management screen and the Fruxon-hosted loader script are rolling out. If you want to embed an agent now, create a config via the API and reach out to Fruxon for the loader URL.

Embedding on your site

The widget ships as a loader script that injects a cross-origin, sandboxed iframe. You embed it one of two ways.

Script tag — paste one line into your page and configure it with data- attributes:

<script
  src="<your Fruxon widget loader URL>"
  data-fruxon-embed-key="emk_your_publishable_key"
  data-fruxon-position="br"
></script>

data-fruxon-position is br (bottom-right, default) or bl (bottom-left). The loader renders the launcher bubble and lazy-loads the chat iframe on first open.

npm SDK — for single-page apps, initialize programmatically:

import { FruxonChat } from '@fruxon/chat-widget';

const widget = FruxonChat.init({ embedKey: 'emk_your_publishable_key', position: 'br' });
widget.on('message', () => { /* … */ });
// widget.open() / .close() / .toggle() / .destroy()

Both paths mount the same iframe and expose open / close / toggle controls (the script-tag build via the global window.FruxonChatWidget). The agent, greeting, suggested prompts, and theme all come from the embed config the key resolves to — you don't pass them in the snippet.

You configure only the publishable key (and optional position) on your page. Everything else is server-side on the embed config, so you can re-theme the widget or change its greeting without touching your site's HTML.

Delivery: streaming with a polling fallback

The widget is SSE-first: after a visitor sends a turn, the iframe holds an event stream and the agent's reply, typing indicators, and status events arrive live. If the stream drops, the widget falls back to polling the message history (with backoff) and reconnects — so a flaky network degrades gracefully instead of hanging. The session token auto-refreshes before it expires.

API

The widget is served by two endpoint groups.

Public gateway — Swagger tag Embed Widget, base v1/embed/sessions. The first call is anonymous; every later call carries the session bearer token.

EndpointDoes
POST v1/embed/sessionsOpen a session from a publishable key (validates the key + origin, mints the session token)
POST …/{session}/turnsSend a visitor turn (queued; the reply arrives on the stream)
GET …/{session}/streamServer-Sent Events: reply, typing, status, blocked, failed
GET …/{session}/messagesPoll message history (fallback / gap-fill), with a since cursor
POST …/{session}:refreshRe-mint the session token with a fresh TTL
POST …/{session}:closeClose the session

Management CRUD — Swagger tag Embed Configs, under v1/{tenant}/agents/{agent}/embedConfigs. Requires your normal agent scopes (agents:read / agents:write).

EndpointDoes
POST · GET …/embedConfigsCreate / list embed configs for an agent
GET · PUT · DELETE …/embedConfigs/{id}Read, update, delete a config
POST …/embedConfigs/{id}:rotateKeyRotate the publishable key (invalidates the old one)

See the API Reference for full request and response shapes.

Next steps

  • Agents — build the agent the widget talks to
  • Cost & Budgets — cap the Production budget embedded traffic draws on
  • Tools & Skills — scope what an anonymous visitor's agent can reach
  • Observability — embedded sessions appear in the agent's Execution History

On this page