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 Share is disabled for embed customers in this workspaceThe workspace hasn’t enabled share for embedToggle Allow share for embed customers in Embed settings
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
trend