Monetize Analytics with Subscription Tiers
Introduction
Turn your embedded analytics into a revenue driver by offering different capabilities at each subscription tier. Basic users get view-only dashboards, Pro users can explore and customize, and Enterprise users get AI-powered insights.
| Plan | Capabilities |
|---|---|
| Basic | View dashboards |
| Pro | View + Explore data |
| Enterprise | View + Explore + Ask AI |
This approach lets you:
- Create upsell opportunities — Users see the value of higher tiers through feature limits
- Match pricing to value — Charge more for self-service exploration and AI
- Reduce support load — Higher-tier users answer their own questions
How it works
You control capabilities through two mechanisms:
- Portal contents — Including datasets enables exploration; omitting them creates a view-only experience
- Embed payload settings — The
settings.ai.enabledflag controls Ask AI access
Basic: Portal (dashboards only) → View only
Pro: Portal (dashboards + datasets) → View + Explore
Enterprise: Portal (dashboards + datasets) + AI enabled → View + Explore + Ask AI
Step-by-step implementation
Step 1: Create a portal for each tier
Each tier gets its own portal. The key difference is whether you include datasets.
EmbedPortal basic_portal {
objects: [
overview_dashboard,
// No datasets = view-only experience
]
}
EmbedPortal pro_portal {
objects: [
overview_dashboard,
sales_analytics,
customer_insights,
sales_data, // Dataset enables exploration
]
}
EmbedPortal enterprise_portal {
objects: [
overview_dashboard,
sales_analytics,
customer_insights,
executive_summary,
sales_data, // Dataset enables exploration
operations_data, // Dataset enables exploration
]
}
Why datasets matter:
- Without datasets, users can only view pre-built dashboards
- With datasets, users can click into charts, change groupings, add filters, and save custom views
- Ask AI also requires datasets to answer questions
Step 2: Select portal and features in your backend
Map each subscription plan to its portal, and enable AI for Enterprise users.
const PLAN_PORTAL_MAP = {
basic: 'basic_portal',
pro: 'pro_portal',
enterprise: 'enterprise_portal',
};
function generateEmbedUrl(user) {
const embed_payload = {
object_name: PLAN_PORTAL_MAP[user.plan],
object_type: 'EmbedPortal',
embed_user_id: user.id,
embed_org_id: user.orgId,
settings: {
ai: {
enabled: user.plan === 'enterprise', // Only Enterprise gets Ask AI
}
},
exp: Math.floor(Date.now() / 1000) + 3600,
};
const token = jwt.sign(embed_payload, EMBED_SECRET, { algorithm: 'HS256' });
return `https://holistics.io/embed/${EMBED_KEY_ID}?_token=${token}`;
}
Step 3: Embed in your frontend
The frontend code is the same regardless of tier — all the logic is in your backend.
<iframe
src="<%= generateEmbedUrl(currentUser) %>"
width="100%"
height="600"
frameborder="0"
></iframe>
Multi-tenant data isolation
In a SaaS application, you'll also want each customer to see only their own data. Combine portal selection with row-level permissions using user_attributes.
function generateEmbedUrl(user) {
const embed_payload = {
object_name: PLAN_PORTAL_MAP[user.plan],
object_type: 'EmbedPortal',
embed_user_id: user.id,
embed_org_id: user.orgId,
user_attributes: {
client_id: [user.clientId], // Each client sees only their data
},
settings: {
ai: {
enabled: user.plan === 'enterprise',
}
},
exp: Math.floor(Date.now() / 1000) + 3600,
};
const token = jwt.sign(embed_payload, EMBED_SECRET, { algorithm: 'HS256' });
return `https://holistics.io/embed/${EMBED_KEY_ID}?_token=${token}`;
}
This ensures:
- Portal selection controls which dashboards and features they get (based on subscription)
- Row-level permissions controls which data they see (based on their client/tenant ID)
For setup details, see the Row-level Permission guide.
Additional features by tier
Beyond the core view/explore/AI progression, you can gate other features:
| Feature | How to enable | Typical tier |
|---|---|---|
| Personal workspace | permissions.enable_personal_workspace: true | Pro+ |
| Shared workspace | permissions.org_workspace_role: 'editor' | Enterprise |
| Email subscriptions | settings.allow_data_subscribe: true | Pro+ |
| Data export | permissions.allow_dashboard_export: true | Pro+ |
function generateEmbedUrl(user) {
const embed_payload = {
object_name: PLAN_PORTAL_MAP[user.plan],
object_type: 'EmbedPortal',
embed_user_id: user.id,
embed_org_id: user.orgId,
permissions: {
enable_personal_workspace: user.plan !== 'basic',
org_workspace_role: user.plan === 'enterprise' ? 'editor' : null,
allow_dashboard_export: user.plan !== 'basic',
},
settings: {
ai: { enabled: user.plan === 'enterprise' },
allow_data_subscribe: user.plan !== 'basic',
},
exp: Math.floor(Date.now() / 1000) + 3600,
};
const token = jwt.sign(embed_payload, EMBED_SECRET, { algorithm: 'HS256' });
return `https://holistics.io/embed/${EMBED_KEY_ID}?_token=${token}`;
}
Related guides
- Role-based portal access — Show different dashboards to different user roles
- Interactive embedding — Enable data exploration features
- Ask AI — Set up AI-powered analytics
- Parameters reference — Full list of embed payload options