Integrate & ship

Web embedding

Publish an agent, a swarm or a dashboard to your own site — where the visitors are anonymous, which changes what you must think about.

Open Configure → Web Embedding. You create an embed key for one agent, swarm or dashboard, restrict it to the domains you control, and paste a snippet into your page.

Setting one up

  1. 1

    Pick what to expose

    One agent, one swarm, or one published dashboard per key. Separate keys for separate placements — they can be revoked independently.
  2. 2

    Restrict the domains

    List exactly the origins allowed to load it — www.example.com, docs.example.com. Never leave this open on a key with real data behind it.
  3. 3

    Set an expiry

    Keys can carry an expiry date and be revoked or rotated later. A campaign key should outlive the campaign by days, not years.
  4. 4

    Copy the snippet

    An iframe or script tag. Paste it where the widget should appear.
html
<iframe
  src="https://your-instance.example.com/embed/agent/emk_xxxxxxxxxxxxxxxx"
  style="width:100%;height:600px;border:0"
  title="Support assistant"
></iframe>

Keys are prefixed emk_. The URL path segment matches the resource type: /embed/agent/<key>, /embed/swarm/<key> or /embed/bi/<key>.

Every field on an embed key

FieldDefaultNotes
Name1–80 characters. Your label; not shown to visitors.
resource_typeOne of agent, swarm, bi_dashboard. Fixed at creation.
allowed_domainsemptyOrigins permitted to load it. EMPTY MEANS NO DOMAIN RESTRICTION — set this.
allow_aifalseFor dashboard embeds: whether viewers may use the Ask-AI follow-up. Off by default because each question is a model call billed to you.
is_activetrueTurn off to disable the placement without deleting the key.
transcript_retention_days301–3650. How long embed conversations are kept before the scheduled purge.
expires_atnullOptional expiry.
use_count0Requests served — read-only, useful for spotting an abandoned placement.
last_used_atnullRead-only.

What an anonymous visitor can reach

This is the part worth being precise about.

AspectBehaviour
IdentityNone. There is no sign-in; every visitor is anonymous.
Data accessThe visitor has none of their own. The agent runs against the OWNER's knowledge and data, explicitly scoped to that owner.
Model costBilled to the key owner's workspace, under the owner's provider keys.
ToolsOnly what the underlying agent has enabled — an embed does not add capability.
GuardrailsThe agent's guardrails apply, including PII handling on input and output.
Which version runsFor an embedded SWARM, the published snapshot — not your working canvas. Creating the embed key publishes the current graph, and later edits stay private until you press Publish in the Deploy dialog.

That last row is the one people are surprised by, and it is deliberate: an embed sits in someone else’s page, so a half-finished edit reaching it the moment you press Save would be the worst version of that behaviour. See API & webhooks for the publish states. Embeds created before publishing existed keep serving the live canvas until you publish once.

An embed is a public surface

Anything the agent can read, a visitor can ask it to reveal — including by writing a prompt that tries to talk it out of its instructions. Before publishing, ask: if a stranger asked this agent for everything it knows, what would come back? Attach only the collections and tables the public may see, and enable only the tools they may trigger.

How access is enforced

Domain allow-list
Requests carry the browser-set Origin header, which page scripts cannot forge, and are rejected when it isn't on your list. This stops your key being lifted and used on someone else's site — but it is a browser-level control, not authentication: a non-browser client can send any header it likes.
Key lifecycle
Keys record when they were last used and from which IP, can expire, and can be revoked or rotated. Rotation keeps the link between old and new so you can see what replaced what.
Rate and concurrency limits
Per-key limits blunt scraping and runaway loops.
Budget caps
A key can carry its own spend cap — see Budgets. On a public endpoint this is the difference between a bad day and a bad invoice.

Transcripts and retention

Embed conversations are recorded so you can see what people asked and how the agent answered. Each key has a transcript retention window (30 days by default, 1–3650); a scheduled purge deletes older transcripts.

Set this deliberately. Visitors may type personal information into a public chat box, and the shortest window that still serves you is the right one. Redaction guardrails can strip recognised personal data before it is stored or sent to a provider — see Guardrails & PII.

Embedded dashboards

A published dashboard can be embedded the same way. Widgets are sanitised on the way out so the underlying queries and connection details aren't exposed — but every number on the page is visible to whoever loads it.

Visual answers in embeds

If the agent has Visual BI answers enabled, embedded chats can return a chart alongside the text. Because the visitor has no data access, the chart is generated server-side using the owner's data with the owner enforced as the tenant boundary.

What one visitor can consume

Worth knowing before you publish, because these are the numbers standing between a curious visitor — or a bot that finds the widget — and your provider bill. They are enforced server-side and counted in Postgres, so they hold across every app instance rather than per process.

LimitValueScope
Chat requests30 per minute → 429Per embed key
Dashboard “Ask AI” requests10 per minute → 429Per embed key
Resolve (widget load)60 per minutePer embed key
Messages in one conversation60Per request
Conversation size200,000 charactersPer request
SpendYour cap → 402, when ENFORCE_BUDGET_CAP is onPer embed key, and per user

Rate limits bound the pace, not the total

Thirty chat requests a minute is roughly 43,000 a day if something hammers it continuously. The rate limit stops a burst; only a budget cap on the key stops the month. Set both — and set the cap before the embed is reachable, not after the first surprise.

A swarm embed orchestrates in the visitor's browser

The graph runs client-side, but each node's call carries only the node's id — the server re-reads that node's real provider, model, prompt and tools from your stored swarm. A visitor cannot select a more expensive model, change the prompt, or reach a node you did not publish. Swarms containing a human-approval step are refused for embedding outright, since no anonymous visitor can ever release the gate.

Pre-publish checklist

  • Domains restricted to sites you control.
  • Only public-safe knowledge collections and tables attached to the agent.
  • Tools limited to what a stranger may trigger.
  • Guardrails on, with PII redaction if visitors might type personal details.
  • A budget cap on the key.
  • A transcript retention window you can justify.
  • Tested by asking the agent, in the embed, to reveal its instructions and everything it knows.