Quickstart
Get tenant-scoped customer analytics running in your SaaS in 10 minutes.
curl.
Read these five once and the rest of the docs becomes much easier to scan.
Get your API key
Go to Settings > API Keys and create a new key with Admin scope.
For a fast first walkthrough, one admin key is enough for every step below. In production, use an ingest key for events and keep your admin key only on a trusted backend for dashboard and embed-session calls.
Copy the key — it's shown only once.
Send your first event
curl -X POST https://emban.sidelabs.dev/v1/events \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"events": [{
"tenant_id": "customer_1",
"event_name": "api.call",
"timestamp": "2026-03-29T12:00:00Z",
"user_id": "user_1",
"string_props": {"endpoint": "/chat", "model": "gpt-4"},
"numeric_props": {"tokens": 150, "latency_ms": 230}
}]
}'
Response: {"accepted":1,"status":"ok"}
Auto-create a customer dashboard
curl -X POST https://emban.sidelabs.dev/v1/discover/auto-create \
-H "Authorization: Bearer YOUR_API_KEY"
Emban scans your events and generates a tenant-scoped dashboard with KPIs, trends, and customer-facing breakdowns.
Publish the dashboard
Dashboards start as drafts. Publish to make it available via embed:
curl -X POST https://emban.sidelabs.dev/v1/dashboards/YOUR_DASHBOARD_ID/publish \
-H "Authorization: Bearer YOUR_API_KEY"
Use the dashboard_id from step 3.
Create a signed tenant-scoped session
From your backend, create a short-lived signed session for the customer viewing the published dashboard. This is an admin-scoped action and the tenant boundary for the embedded analytics surface:
curl -X POST https://emban.sidelabs.dev/v1/embed-sessions \
-H "Authorization: Bearer YOUR_ADMIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tenant_id": "customer_1",
"dashboard_id": "YOUR_DASHBOARD_ID",
"expires_in": 3600
}'
Response includes embed_url — a signed URL valid for 1 hour.
That URL is scoped to tenant_id=customer_1 and the published dashboard_id, so the embedded dashboard shows only that customer's data.
Embed in your app
Option A: iframe
<iframe src="EMBED_URL" width="100%" height="600"
style="border:none; border-radius:4px"></iframe>
Option B: browser helper for resize and programmatic control around the tenant-scoped embed
<div id="analytics"></div>
<script src="https://emban.sidelabs.dev/sdk/emban-embed.js"></script>
<script>
const dash = Emban.create({
container: '#analytics',
embedUrl: 'EMBED_URL'
});
dash.on('ready', () => console.log('Dashboard loaded'));
</script>
Option C: React wrapper for the signed iframe path if your frontend already uses React or Next.js
import { EmbanEmbedFrame } from '@emban/embed-helper/react';
<EmbanEmbedFrame
embedUrl="EMBED_URL"
containerStyle={{ minHeight: 600 }}
/>
If you need native widget-level composition instead of a mounted iframe surface, continue with the React guide and @emban/react.
The browser helper and iframe React wrapper handle auto-resize, theme sync, and runtime session swapping, but the signed tenant-scoped session is still the core integration boundary.
Commands and events
Once you have a signed embed_url, there are two browser-side layers to understand: commands the host page can send into the embed, and events the embed sends back out.
/v1/events. Browser runtime events such as ready, filter, period-change, and drill travel through the signed embed session after the dashboard is mounted.
| Direction | Examples | What it means |
|---|---|---|
host -> embed | setFilters, setTheme, reload | Your app drives the published dashboard from outside the iframe. |
embed -> host | ready, resize, filter, period-change, drill, error | The dashboard reports state and interaction back to your app. |
// Host page -> embed runtime
{
"_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"
}
// Embed runtime -> host page
{
"_emban": true,
"type": "ready",
"dashboardId": "dash_123"
}
{
"_emban": true,
"type": "filter",
"period": "7d",
"filters": { "model": "gpt-4" },
"numericRanges": {},
"dateRanges": {}
}
{
"_emban": true,
"type": "drill",
"dimension": "endpoint",
"value": "/chat",
"action": "apply"
}
If you want the full browser contract, start with Embed Runtime, then go to the React guide or Next.js guide. The public live demo shows the same commands and events against a real signed session.
What's next
- Event schema — structure your data
- Embed runtime — understand the browser-side contract after the signed session is mounted
- Tenants — isolate customer data
- Dashboards — understand widgets, filters, draft state, and what actually gets published
- Permissions — control what each customer sees
- React guide — use the React wrapper for signed embeds
- Next.js guide — create sessions on the server and drive the embed from a client component
- Alpha readiness checklist — launch gate, stop-ship risks, and first-week metrics