Page API reference
The embed has no SDK package. Your page talks to it through the loader’s script tag, one configuration object you define, and one control object the loader defines.
Script tag
Section titled “Script tag”<script src="https://embed.bunkhouse.ai/embed.js" data-public-key="pk_YOUR_SITE_PUBLIC_KEY"></script>Load it with a classic <script src> tag (not a module, not injected inline) before your application’s entry script.
| Attribute | Purpose |
|---|---|
data-public-key |
Required. The site’s publishable key. |
data-session-endpoint |
Server mint mode: your same-origin endpoint that creates the session. |
data-hints-url |
Fallback hints path, used only when the site has no hints path configured. Must be same-origin. |
nonce |
Applied to the scripts and styles the embed adds, for nonce-based Content Security Policies. |
The loader is a singleton: a second copy of the tag is ignored, and a second tag with a different data-public-key is reported as an installation error.
Navigation without a page load
Section titled “Navigation without a page load”The embed keeps working across navigation that rewrites the page without loading a new document, such as Turbo Drive, htmx boost, Livewire wire:navigate and Blazor enhanced navigation. Its launcher and pane live in one element directly under <html>, so replacing <body> leaves them in place. If your framework removes that element or rewrites the <html> attributes, the embed puts back its element and --agent-embed-width on its own. The open pane, transcript and session are kept. If the element was removed, the agent’s code sandbox restarts: code that was running at that moment fails and the agent is told, and the next code it runs uses a new sandbox. If your page keeps removing the element, the embed stops restoring it and reports an error in status.error.
Navigation does not change the signed-in user. Call resetSession() on sign-in, sign-out and account switch, as you would with full page loads.
window.AgentEmbedConfig
Section titled “window.AgentEmbedConfig”Define this object before the loader. Every field is optional.
| Field | Type | Purpose |
|---|---|---|
getIdentityToken |
() => string | Promise<string> |
Identity-token mode: return a token your backend signed for the current user. Its presence selects this mode. |
getAuthHeaders |
({ operationId, url, method }) => Record<string, string> | Promise<...> |
Extra headers, such as a CSRF token, for the assistant’s calls to your API. Called only after the destination is authorized; values never reach the model or sandbox. Cookie, host and browser-controlled headers are refused. |
sensitiveFields |
string[] |
Additional field names whose values are treated as sensitive. |
layoutTarget |
CSS selector | Your app’s normal-flow wrapper; while the pane is open on desktop, it reserves the pane’s width as right margin. |
onWrite |
(write) => void | Promise<void> |
Called after each direct API write that succeeded or has an unknown outcome, so you can refresh your UI. Receives { skillId, transport: "api", status, method, origin, path }, never request or response bodies. |
Session mode is chosen when a session starts: getIdentityToken if defined, otherwise data-session-endpoint if set, otherwise anonymous.
window.AgentEmbed
Section titled “window.AgentEmbed”The loader defines a frozen, read-only window.AgentEmbed as soon as it runs; the pane itself loads on first open. Before then, stop() does nothing and resetSession() drops what was observed so far.
| Member | Purpose |
|---|---|
open() |
Open the pane. |
close() |
Close the pane. |
stop() |
Stop the current run. |
resetSession() |
Drop the session and anything observed for the current user. Call on sign-in, sign-out and account switch. |
destroy() |
Remove the launcher and pane, restore the page’s fetch/XHR and delete window.AgentEmbed. |
status |
Read-only snapshot, below. |
status has these fields:
| Field | Values |
|---|---|
state |
idle, thinking, executing, awaiting_approval, completed, failed or cancelled |
open |
true while the pane is open |
sessionKind |
signed, anonymous or null before a session exists |
skillCount |
Number of skills currently available |
error |
Latest error message, or null |
Layout
Section titled “Layout”When the pane opens, closes or is resized, the embed sets the --agent-embed-width CSS custom property on <html> to the width it occupies (0px when closed) and dispatches an agentembed:resize event on window with detail.width in pixels:
window.addEventListener("agentembed:resize", (event) => { console.log("Assistant pane width", event.detail.width);});.app-toolbar { margin-right: var(--agent-embed-width, 0px); }