Embed Runtime
The embed runtime is the browser-side contract that starts after your backend creates a signed embed_url. It is how your host page and the mounted dashboard talk to each other.
Keep the boundaries clean:
POST /v1/embed-sessions is the server-side API that mints a short-lived tenant-scoped session. The runtime described here is what happens after the browser mounts that signed embed.
Concept map
Use this row to jump between the product data model, the browser contract, and the isolation rules around it.
Data
Events
Start with ingestion if you still need to shape the data model that powers the dashboard.
Browser
Embed Runtime
How the host page and mounted dashboard talk after the signed session is live.
Isolation
Tenants
See how the signed session stays customer-scoped without cloning dashboards per account.
Surface
Dashboards
Understand which published surface the runtime is actually mounting and controlling.
Control
Permissions
Layer drill, hidden widgets, locked filters, and period bounds on top of the runtime.
Lifecycle
- Server: your backend calls
/v1/embed-sessionsand receives a signedembed_url. - Host page: your frontend mounts the published dashboard with raw
<iframe>, the browser helper, or<EmbanEmbedFrame />. - Host -> embed: the host page may send commands such as
setFilters,setTheme, orreload. - Embed -> host: the dashboard reports
ready,resize,filter,period-change,drill, anderror. - Session rotation: if your backend mints a fresh signed URL, the helper can swap it in place through
setEmbedUrl()without remounting the wrapper.
Host -> embed commands
The host page can drive the mounted dashboard through a small postMessage contract.
{
"_emban": true,
"type": "setFilters",
"filters": {
"period": "7d"
}
}
{
"_emban": true,
"type": "setTheme",
"theme": {
"primaryColor": "#0f9d58",
"backgroundColor": "#f7f9f7",
"cardBackground": "#ffffff",
"cardBorder": "#d8e2d9",
"textColor": "#101513",
"mutedColor": "#5d6c63"
}
}
{
"_emban": true,
"type": "reload"
}
| Command | Payload | Description |
|---|---|---|
setFilters | { period, dimensions?, numericRanges?, dateRanges? } | Updates active period and filter state inside the mounted dashboard. |
setTheme | { primaryColor, backgroundColor, cardBackground, cardBorder, textColor, mutedColor } | Applies host-driven theme tokens to the published embed. |
reload | {} | Forces a fresh data load without minting a new signed session. |
Embed -> host events
The embedded dashboard reports lifecycle, state changes, and user interaction back to the host page.
{
"_emban": true,
"type": "ready",
"dashboardId": "dash_123"
}
{
"_emban": true,
"type": "resize",
"height": 712
}
{
"_emban": true,
"type": "filter",
"period": "7d",
"filters": { "model": "gpt-4" },
"numericRanges": {},
"dateRanges": {}
}
{
"_emban": true,
"type": "period-change",
"previousPeriod": "30d",
"period": "7d"
}
{
"_emban": true,
"type": "drill",
"dimension": "endpoint",
"value": "/chat",
"action": "apply"
}
{
"_emban": true,
"type": "error",
"message": "Couldn't refresh this dashboard"
}
| Event | Payload | Description |
|---|---|---|
ready | { dashboardId } | Fires when the embed runtime is ready and the dashboard is connected. |
resize | { height } | Reports the current iframe height for host-side auto-resize. |
filter | { period, filters, numericRanges, dateRanges } | Reports the full active filter state after a change or refresh. |
period-change | { previousPeriod, period } | Reports period transitions from inside the embedded dashboard. |
drill | { dimension, value, action } | Reports drill apply, clear, or detail actions. |
error | { message } | Reports a failed refresh or other runtime error. |
Helper vs raw iframe
The raw iframe runtime posts the events above. The helper SDK adds a host-side convenience layer around that runtime.
- Raw iframe: mount the signed
embed_urland handle browser messages yourself. - Browser helper or iframe React wrapper: gives you methods such as
setFilters(),setTheme(),reload(), andsetEmbedUrl(). - Helper-only event:
session-swappedis emitted by the helper whensetEmbedUrl(nextSignedUrl)replaces the current signed URL. The iframe runtime does not post that event by itself.
Why this matters: tenant isolation still stays server-side in the signed session. The browser runtime exists to control and observe the published dashboard after mount, not to move trust boundaries into the client.
Choosing the integration surface
Most teams should choose the integration surface based on how much browser control they want to own, not on how many SDKs exist.
Option 1
Raw iframe
Use this when you want the smallest possible integration surface and you are comfortable handling
postMessage, resize, and session rotation yourself.
Option 2
Browser helper or iframe React wrapper
Use this when the product still wants the signed iframe model, but your host app needs simpler commands, event subscriptions, and in-place session swapping.
Option 3
Native React SDK
Use
@emban/react when you want widget-level or dashboard-level rendering without an iframe boundary. That is a different surface from the signed iframe runtime described on this page.
Decision shortcut: if you are embedding one published dashboard into a customer portal, stay on the signed iframe path. Reach for the helper before you reach for raw browser events. Reach for the native React SDK only when your product needs dashboard widgets as part of the host UI, not just a mounted analytics surface.
Where to validate it
- Live demo — inspect real commands and events against a seeded signed session
- React guide — use
@emban/embed-helper/reactaround the iframe path - Next.js guide — mint sessions server-side and drive the runtime from a client component
- API Reference — see the same contract next to the server-side
/v1/embed-sessionsendpoint