Skip to main content

Build a custom Insights dashboard

The Insights section ships one fixed hub page plus a set of purpose-built surfaces (retention, funnels, deliverability, LLM spend, and so on). Where those pages stop, the Dashboard Builder starts: it is the no-code composition surface at Insights → Dashboard Builder (/insights/dashboards) that lets you arrange the metrics that already exist behind the per-pillar endpoints into a layout of your own, and share that layout as a signed, embeddable link. This guide covers the builder mechanics — the palette, the grid, widget configuration, layout validation, and the share/embed flow. For how to read the individual Insights surfaces (retention curves, journey paths, topic intelligence, and the rest), see Read the Insights dashboards.

What a widget is

Every widget in the palette maps to one read-only metric endpoint the API already serves — message volume, deliverability, voice quality, CDP health, agent QA, LLM spend, burn rate, carbon, and more. The builder never invents a new query: placing a widget means “render the output of that existing endpoint inside my layout.” When the layout is later rendered, each tile fetches its own backing endpoint with the normal authenticated, tenant-scoped request, so a dashboard can never widen the data access the widget’s source endpoint already enforces. Because widgets reference the live endpoint catalog, a widget only exists in the palette when its backing metric is live for your tenant — if a surface you expected is missing, check that pillar’s data is actually flowing.

The widget palette

The palette groups widgets by category (Messaging, Deliverability, Voice, CDP, Agents, Quality, Spend, Sustainability) and each entry shows its visualization type — stat, line, bar, table, or gauge — so you know what shape the tile will take before you add it. The current catalog:

Create a dashboard

  1. Open Insights → Dashboard Builder in the console (visible to the owner, admin, developer, and viewer roles).
  2. Set a Dashboard name and pick the grid column count — 6, 8, 12, 16, or 24 columns. 12 is the default; use more columns when you want finer placement control.
  3. From the Widget palette on the left, click a widget to drop it onto the canvas. A dashboard can hold up to 50 widgets.
  4. For each placed widget use the editor card on the right to:
    • override the title (leave blank to keep the widget’s own name),
    • adjust width (1 up to the column count) and height (1–24 row units) with the steppers,
    • reorder tiles with the up/down controls, or remove them.
  5. When the layout reads right, click Validate layout. Validation is a dry-run against the API: it checks the layout shape, clamps coordinates, de-duplicates tile ids, and confirms every required parameter is set. On success the canvas adopts the normalized layout the server returned.
Your in-progress draft autosaves to this browser’s local storage on every edit, so closing or refreshing the page never loses work. The draft is per-browser — it does not sync across devices or teammates. Clear empties the canvas after a confirmation.

Configure a widget

Configuration happens per tile, in the editor card on the right. Every widget has a size (width and height in grid units, up to your column count and 24 row units) and an optional title override. Beyond that, each widget exposes the parameters its backing endpoint accepts:
  • window — the look-back window for the metric, one of 24h, 7d, 30d, or 90d. Most widgets accept it.
  • channel — an exact-match channel filter, one of sms, whatsapp, rcs, email, voice, or telegram. Accepted by the messaging, deliverability, and sentiment widgets.
  • Period or day-count parameters — the spend family takes a billing month (YYYY-MM) or a day count; the burn-rate, spend-series, and carbon widgets take a window in days (default 30).
  • Required object parameters — some widgets bind to a specific object: the Queue live state widget needs a queue id, and the Agent QA scorecard widget needs an agent id. Required parameters are marked with an asterisk in the widget editor; the canvas warns and the Validate layout button stays disabled until every required value is supplied.
Enum-constrained parameters (like window and channel) accept only their listed values — validation rejects anything else.

Validate, don’t guess

Validation runs the same normalizer the API uses on a saved or shared layout, so a layout that validates is one the embed renderer will render unchanged. The builder also adopts normalized coordinates back onto the canvas, so what you see after validation is exactly what a recipient of the dashboard will see.

Validate a layout over the API

Validate layout is a dry-run POST /api/v1/analytics/dashboards/validate — stateless, and it writes nothing. Send a name, the grid column count, and the placed widgets with their parameters; the endpoint clamps coordinates, de-duplicates instance ids, and allow-lists the params. A small two-widget request:
On success you get back the normalized layout — the exact snapshot the builder adopts and the embed page renders:
A malformed layout answers 400 with a human-readable reason naming the widget or parameter at fault — the same message the builder shows inline when validation fails.

Filters and drill-down

The builder itself is a composition surface, so its filter controls live on the widget’s parameters: the window and channel parameters above are the per-tile filters you apply before sharing. For the wider, range-aware filter experience — the explicit date range, channel and region filters, and the row-level drill-down into carriers, countries, and error codes — open the fixed Analytics surface (Insights → Analytics), which is the canonical explorer the hub links to. The Messaging insights widget is the drill-down you embed: it renders the same per-carrier, per-country, and per-error-code histogram the Deliverability surface drills into, so a shared dashboard can carry that breakdown without granting console access.

Share and embed

Minting a share link is a governance action on the API (the link anyone with the URL can open exposes tenant metrics), so Share & embed is restricted to the owner and admin roles; the button only renders for them, and the API rejects the request for other roles.
  1. Fill in the dashboard name and every required widget parameter (the button stays disabled until those are set).
  2. Click Share & embed.
  3. Pick a lifetime — 1, 7, 30, 60, or 90 days (the default is 30, and the API clamps every request to 1–90 days) — optionally a title override, and Generate link.
  4. Copy either:
    • the Embed URL, which opens a public, white-label page rendering the dashboard, or
    • the Embed snippet, a ready-made <iframe> pointing at that URL to drop into an intranet, portal, or backing-app page.
The signed link embeds the layout snapshot, your tenant scope, and the expiry inline — there is no server-side save step, and the link keeps working until it expires. Anyone with the link can view the dashboard until then; to rotate access you generate a new link (the old one remains valid until its expiry). The embed page renders the composition plus your white-label branding — the named metric tiles laid out on your grid, under your logo and colors — not the live metric values. That page is intentionally view-only: the signed token cannot call authenticated per-widget data endpoints. Use it for “here is the dashboard layout with our branding”, while operators who need live numbers open the builder (or the matching Insights surface) in the console. An invalid, malformed, or expired token returns a friendly “invalid or expired” page (the resolver answers 410/422), a burst of opens answers 429, and any other fault surfaces as a service-unavailable notice — the recipient never sees a raw error. Owners and admins can mint the link directly against POST /api/v1/analytics/dashboards/share — the same call Share & embed runs. Pass the validated layout, an optional lifetime, and an optional white-label title; the API clamps ttl_days to 1–90 days (default 30):
The response carries the signed token and the surfaces built from it — the white-label embed page and a ready-to-paste iframe:
Share embed_url or paste iframe_html; api_url is the raw JSON resolver the embed page consumes. The token rides inside the URL, and each link carries its own expiry — revoke access by generating a new link and retiring the old one (the published link stays valid only until its expires_at).

Limits and failure modes

Where exports live

The builder itself composes and shares layouts — it is not a data-export surface. If you need a spreadsheet or an image of the numbers, use the export affordance on the individual Insights metric page (for example the Deliverability and Link-tracking surfaces ship CSV/workbook exports), or pull the same endpoints the widgets call through the Analytics API and export from your own tooling. A dashboard link answers “show someone the composition,” not “hand them a file of the data.”

How this fits with the other Insights guides

  • Read the Insights dashboards — what each fixed Insights surface answers and how to read it (cross-channel KPIs, retention curves, journey paths). This guide covers the complementary dashboard-building mechanics: the palette, layout, and share flow.
  • Insights API reference — the endpoint shapes behind the fixed surfaces (the widget catalog reuses the same read-only family).
  • Scheduled reports — recurring email digests, when you need the numbers pushed to you rather than composed on a page.