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.

AttributeValuesDefaultMeaning
data-voicelens-embedve_…requiredThe embed token.
data-themelight, dark, autosaved configColour mode. auto follows the viewer's system preference.
data-bg, data-surface, data-text, data-brand, data-accenthex colour (#0f766e or 0f766e)saved configPalette overrides for page background, cards, text, primary and accent colours.
data-fontCSS font-family listsaved configOverrides the interface font.
data-transparent1saved configTransparent page background so your page shows through.
data-langen, de, es, ar, tr, itembed locale, else browserInterface language. Arabic renders right-to-left.
data-heightpixels480Initial height before the first resize message.
data-min-heightpixels240The iframe never shrinks below this.
data-originURLorigin the script was loaded fromOnly for self-hosted or staging environments.
data-titletextVoiceLens dashboardAccessible title on the iframe.
data-scrolloffonBy 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));
EventdetailMeaning
voicelens:readyThe 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.

GET/api/embed/config

Workspace name, optional title, theme, enabled features (recentCalls, topFaults, activity, callDetail, transcript, audio, slots, coverage), allowed origins, locale and whether branding is shown.

GET/api/embed/analytics/summary

Same shape as the workspace summary, sanitised.

GET/api/embed/conversations

Recent completed calls as summaries.

GET/api/embed/conversations/{id}

A sanitised analysis; transcript, slots and coverage only when those features are enabled.

GET/api/embed/conversations/{id}/audio

Audio 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.