iframe mode

Embed a trend dashboard with a plain iframe tag. The 5-minute integration.

The simplest way to embed a trend dashboard is a plain <iframe> tag. Two steps:

  1. Your backend mints a token via POST /api/embed/token.
  2. Your frontend renders <iframe src="https://app.trend.dev/embed/dashboards/<id>?token=<jwe>">.

If your app is server-rendered (Rails, Django, Laravel, Next.js SSR), the mint happens in the same request that renders the page — no separate frontend fetch.

1. Get an API key

Embed → API keys → New API key. You’ll see the plaintext once; store it in your secrets manager as TREND_EMBED_API_KEY. Format: trnd_emb_<43 random chars>.

Warning

This key is a server-to-server credential. Never send it to the browser. If a browser could see it, an attacker could mint arbitrary tokens for any customer.

2. Mint a token (your backend)

POST https://app.trend.dev/api/embed/token
Authorization: Bearer trnd_emb_...
Content-Type: application/json

{
  "externalId": "acme-corp",
  "attributes": { "company_id": "acme-corp" }
}

Response:

{
  "token": "eyJhbGciOiJkaXIi...",
  "expiresAt": 1735939200
}

Node.js:

const res = await fetch('https://app.trend.dev/api/embed/token', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.TREND_EMBED_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    externalId: currentCustomer.id,
    attributes: { company_id: currentCustomer.id },
  }),
})
const { token } = await res.json()

Python:

import os, requests

res = requests.post(
    "https://app.trend.dev/api/embed/token",
    headers={
        "Authorization": f"Bearer {os.environ['TREND_EMBED_API_KEY']}",
        "Content-Type": "application/json",
    },
    json={
        "externalId": current_customer.id,
        "attributes": {"company_id": current_customer.id},
    },
)
token = res.json()["token"]

3. Render the iframe (your frontend)

<iframe
  src="https://app.trend.dev/embed/dashboards/<DASHBOARD_UUID>?token=<TOKEN>"
  width="100%"
  height="600"
  frameborder="0"
></iframe>

Get the dashboard UUID from the dashboard’s ellipsis menu once you’ve toggled Embed on.

Token lifetime

Tokens are valid for 1 hour from mint. Two ways to handle expiry:

  • Mint per pageview (simplest). Your backend mints a fresh token every time the parent page loads. Zero session state.
  • Cache + refresh (higher-traffic). Cache the token per customer for ~50 minutes, mint a fresh one before it expires.

Either way, when a token expires, the iframe shows an "Invalid or expired embed token" page. Refresh the parent page — the fresh mint fixes it.

Prefilling variables from the URL

Any dashboard variable can be prefilled by appending var_<name>=<value> to the iframe URL:

<iframe
  src="https://app.trend.dev/embed/dashboards/<uuid>?token=…&var_country=US&var_tier=premium"
  width="100%" height="600"
></iframe>

Values that look like JSON arrays (e.g. ["a","b"]) parse as arrays; everything else stays as a string. For live filter updates from a parent SPA without reloading, use the web component — iframes can't take runtime attribute changes.

Demo customers (free, watermarked)

Any customer toggled to Demo in Embed → Customers → Registered is excluded from billing AND renders with a diagonal "DEMO" watermark across every chart. Use for sales demos, dev/QA environments, or internal previews. Details: Overview → Pricing.

Error paths

ErrorCauseFix
401 Invalid API keyAPI key wrong / revokedRegenerate in Embed → API keys
403 Embed is not enabled for this workspaceWorkspace lost the embed feature flagCheck billing
404 Dashboard not foundDashboard doesn’t exist, doesn’t belong to the workspace, or embed_enabled is offToggle Embed on the dashboard
400 Missing required attributes: XA dataset in the dashboard references {{trend.attributes.X}} but the token didn’t supply XAdd the attribute to your mint call