embed.js reference
Every attribute the embed loader understands, the window.VoiceLensEmbed API, the postMessage protocol, and the public embed endpoints behind it.
embed.js is the small loader that turns a placeholder element into an embedded VoiceLens dashboard. It is served from https://voicelens.app/embed.js, weighs a few kilobytes, has no dependencies and can be loaded async. Create the embed and its token (ve_) as described in Embedded dashboards.
Basic usage
<div data-voicelens-embed="ve_…"></div>
<script src="https://voicelens.app/embed.js" async></script>On load, and whenever new matching elements are added to the page, the loader replaces each [data-voicelens-embed] element's content with an iframe pointing at https://voicelens.app/embed/<token> and keeps its height in sync with the content.
Attributes
All attributes are optional except the token. Values override the embed's saved configuration for that placement only.
| Attribute | Values | Default | Meaning |
|---|---|---|---|
data-voicelens-embed | ve_… | required | The embed token. |
data-theme | light, dark, auto | saved config | Colour mode. auto follows the viewer's system preference. |
data-bg, data-surface, data-text, data-brand, data-accent | hex colour (#0f766e or 0f766e) | saved config | Palette overrides for page background, cards, text, primary and accent colours. |
data-font | CSS font-family list | saved config | Overrides the interface font. |
data-transparent | 1 | saved config | Transparent page background so your page shows through. |
data-lang | en, de, es, ar, tr, it | embed locale, else browser | Interface language. Arabic renders right-to-left. |
data-height | pixels | 480 | Initial height before the first resize message. |
data-min-height | pixels | 240 | The iframe never shrinks below this. |
data-origin | URL | origin the script was loaded from | Only for self-hosted or staging environments. |
data-title | text | VoiceLens dashboard | Accessible title on the iframe. |
data-scroll | off | on | By default the loader scrolls the embed's top into view when the viewer opens or leaves a call; off disables that. |
Example with a light theme matched to a portal:
<div
data-voicelens-embed="ve_…"
data-theme="light"
data-brand="#0f766e"
data-accent="#f59e0b"
data-font="Inter, system-ui, sans-serif"
data-lang="de"
data-min-height="400"
></div>JavaScript API
The loader exposes a small global once it has run:
window.VoiceLensEmbed.version; // "1"
window.VoiceLensEmbed.init(root); // scan `root` (or the document) for new placeholders;
// rarely needed, a MutationObserver does this for you
window.VoiceLensEmbed.setTheme(element, { // re-theme one placement without reloading
theme: "dark",
brand: "#6366f1",
accent: null, // null clears an override; omitted keys keep their value
});setTheme accepts the theme keys theme, bg, surface, text, brand, accent, font and transparent and posts them to the iframe, which re-themes in place. Use it when your portal has its own dark-mode toggle. The script is safe to include more than once.
Events on the placeholder
The loader re-dispatches the iframe's messages as DOM CustomEvents on the placeholder element, so you can react without touching postMessage:
const el = document.querySelector("[data-voicelens-embed]");
el.addEventListener("voicelens:ready", () => console.log("dashboard loaded"));
el.addEventListener("voicelens:resize", (e) => console.log("height", e.detail.height));
el.addEventListener("voicelens:navigate", (e) => console.log("view", e.detail.view));| Event | detail | Meaning |
|---|---|---|
voicelens:ready | The dashboard has loaded. | |
voicelens:resize | { height } | Content height changed; the loader already set the iframe height (respecting data-min-height). |
voicelens:navigate | { view } | The viewer opened or left a call inside the embed. |
Under the hood the iframe posts voicelens:ready, voicelens:resize and voicelens:navigate to the host, and the host posts voicelens:theme back; messages are only accepted from the embed's origin.
Public endpoints behind the embed
The iframe calls these with the token in X-Embed-Token. They are listed for transparency; you would not normally call them yourself.
/api/embed/configWorkspace name, optional title, theme, enabled features (recentCalls, topFaults, activity, callDetail, transcript, audio, slots, coverage), allowed origins, locale and whether branding is shown.
/api/embed/analytics/summarySame shape as the workspace summary, sanitised.
/api/embed/conversationsRecent completed calls as summaries.
/api/embed/conversations/{id}A sanitised analysis; transcript, slots and coverage only when those features are enabled.
/api/embed/conversations/{id}/audioAudio stream, only when the audio feature is enabled.
Requests are refused when the page's origin is not in the embed's allowed list, when the token is revoked or expired, and beyond 240 requests per minute per token.
Content Security Policy
If your portal sets a CSP, allow the embed origin:
frame-src https://voicelens.app;
script-src https://voicelens.app;The embed itself sends Content-Security-Policy: frame-ancestors * and relies on the token's allowed-origins list for access control, so framing works from any of your configured origins without further headers on your side.