Chat Widget
Put one of your agents on your own website with a single script tag — origin-locked, rate-limited, and rendered in an iframe so nothing leaks either way.
A widget publishes one agent to one or more websites. Visitors chat with it without signing in to anything.
<script src="https://your-install/embed/v1.js" data-key="pk_..." async></script>That is the whole integration. Create the widget under Settings → Widgets, pick the agent, add the sites allowed to embed it, and copy the tag.
How it renders
The loader creates an iframe and talks to it. It deliberately does not draw the chat into your page, and the reasons are worth knowing because they are what makes it safe to paste onto a customer-facing site:
- Your page cannot read the conversation or the visitor's token. The iframe is a separate browsing context with no access from the host page. A widget drawn into your own DOM would hand both to any script on that page — including anything your analytics or tag manager loaded.
- Neither stylesheet can reach the other. No shadow-DOM gymnastics, no reset stylesheet, no specificity war with your site's CSS.
- No CORS surface at all. The chat inside the frame is same-origin with the SynapseOrch app, so it calls the API the ordinary way.
The loader is hand-written JavaScript with no build step, because it is served to every visitor of every site that embeds a widget.
Who is allowed to embed it
The public key says which widget. The origin allow-list says whether the page asking for it may have it, and it is the only thing standing between a scraped key and your model bill.
It is enforced twice, because the two points fail in opposite directions:
Content-Security-Policy: frame-ancestorson the embed page. The browser refuses to paint the frame, so a key pasted onto a site you did not allow shows nothing at all and never makes a request. This is the strong one.- A server-side check, for the cases a browser cannot be trusted to make.
The key is public, the allow-list is the credential
pk_... appears in the HTML of every page that embeds the widget, so treat it
as public by design. Anyone who copies it still cannot use it anywhere you
have not listed. If a key is being abused from an allowed origin, Rotate
key issues a new one and invalidates the old.
Rate limits
The allow-list is the front door. Limits are the floor underneath it, for what the door cannot cover: a forged Referer, a script driving a browser on a page you do allow, or simply a popular site where the traffic is legitimate and still more than you meant to pay for.
| Counter | Limit | Answers |
|---|---|---|
| Messages per visitor IP | 20 in 5 minutes | One person hammering the widget |
| New conversations per visitor IP | 30 in 5 minutes — starting one, or starting over | Someone cycling sessions to dodge the first |
| Messages per day, per widget | 500 by default, set on the widget; 0 means no cap | The bill you agreed to |
Windows are fixed rather than sliding, so a burst right on a boundary can briefly double the rate — the price of one counter increment instead of a sorted set per caller.
Where Redis is configured the counters are shared across processes; a single-process install uses an in-process counter, which is correct for one process. The cap on the settings screen is always enforced by something.
Appearance
A closed vocabulary, not free CSS — the widget renders on somebody else's website, and every option has to keep looking right at 320px wide, in both colour schemes, next to whatever else is on the page.
| Option | Values |
|---|---|
| Theme | auto, light, dark |
| Font | system, sans, serif, rounded, mono |
| Header | accent, neutral |
| Launcher | bubble, logo |
| Position | right, left |
| Accent | A preset, or your own hex |
| Logo | Up to 128 KB |
No webfonts, deliberately. Every font above is a stack the visitor's device already has, so it costs zero bytes and makes no third-party request. Pulling a webfont would mean your visitors requesting a file from a third party — a live GDPR problem in the EU, where sites have been ruled against for exactly that.
Use Preview to see changes against a real conversation before publishing.
On SynapseOrch Cloud, widgets come with the Solo plan and above, and on a narrower screen the preview sits below the settings rather than beside them.
What visitors can use
A visitor does not get the agent's tools. Under What visitors can use, tick the tools a visitor's turn may use — nothing is ticked until you tick it, and anyone on the sites you allowed can make the agent use a ticked tool, so a read-only one reads your files and data for them. Each tool carries a badge for what it does: Changes data, Reaches outside, Reads your data, Does not say what it does. The list saves with the widget.
The list holds for everything a visitor's turn reaches — the agent, its helpers, and every step of a workflow agent's run. A Team agent answers a visitor with its lead alone: its members never run on a visitor's turn. It only narrows: ticking a tool the agent does not have grants nothing. The task list and skills are always there. A tool whose tool policy would ask first is refused for a visitor, since nobody on your site can approve it.
A visitor's turn never uses the agent's memory — no index, no memory tools, no trace — so nothing a visitor says enters it. Synapse AI's own agents cannot be published on a widget.
Knowledge's search_knowledge and read_knowledge are listed when the agent has a knowledge base open to visitors — Visitors may search it, in the base's settings. A visitor's answer carries no [K#] labels. See Widgets and channels.
What visitors get
A visitor gets a session and a token scoped to that widget, and history within their own session. They cannot reach anything else in your workspace — the widget endpoints are a separate, narrow surface, unrelated to the API keys that drive /api/v1 and /api/v2. A visitor talking to a workflow agent sees the run's answer, never each step's output.
A visitor who clicks to another page on your site mid-reply still gets the answer: the reply runs on, and the widget on the next page picks it up where it was.
If the agent's model fails, or a workflow agent's run fails, the visitor sees "Something went wrong. Please try again." — never the provider's error or the run's, which are about your workspace. Their history keeps the question, answered (The model failed before answering.) or (The workflow failed before answering.).
When you point a widget at another agent, a visitor who comes back is told This chat was updated, so a new conversation has started., and keeps whatever they had typed. A reload recovers the same way. For your own client of the widget endpoints: a call made with the old conversation answers 409 with code: "widget_updated", and POST /api/widget/restart starts the new one (it counts against the new-conversation limit above).
Messaging
SynapseOrch can connect to messaging platforms so agents can receive messages and send responses directly in your team's chat tools. Set up a channel once and users can chat with your agents without opening the SynapseOrch UI.
Google Workspace
Self-hosted SynapseOrch connects to Google Workspace — Gmail, Calendar, Drive, Docs, Sheets, Slides, Forms, Tasks and Contacts — through your own Google Cloud OAuth client and a Google Workspace MCP server.