
Power BI Embedded: Build Analytics into Applications
Embed Power BI reports and dashboards directly into custom applications. Developer guide for tokens, SDKs, row-level security, and white-labeling.
Power BI Embedded lets you integrate interactive reports and dashboards directly into custom web applications, SaaS products, and internal portals, bringing analytics to where users already work instead of directing them to the Power BI Service. For software companies building data products and enterprises building custom portals, embedded analytics eliminates the friction of switching between applications and lets you deliver insights with your own branding and navigation. If your customers or employees need analytics inside an application they already use daily, embedding is the right approach, and it can be production-ready in 2-4 weeks with proper planning.
I have implemented Power BI Embedded for SaaS companies serving 10,000+ customers, healthcare portals displaying patient analytics for 200 clinics, and financial dashboards embedded in custom trading platforms. The technical embedding is straightforward; the challenges are capacity planning, token management, and multi-tenant security. Get those wrong and you face either spiraling costs or data leakage between customers. Our Power BI consulting services include full embedded analytics implementation with capacity right-sizing and security architecture.
Embedding Scenarios: Choose the Right Model First
Power BI supports two fundamentally different embedding approaches based on who consumes the analytics. Choosing the wrong model wastes months of development.
Embed for Your Organization (User Owns Data): End users authenticate with their own Azure AD credentials. Each user needs a Power BI Pro or Premium Per User license. The application acts as a portal that displays Power BI content the user already has access to. Best for internal applications, intranets, and employee portals where users are already licensed. Implementation is simpler because authentication is handled by Azure AD.
Embed for Your Customers (App Owns Data): The application authenticates using a service principal or master account. End users do not need Power BI licenses because capacity-based licensing covers all users. The app generates embed tokens that grant temporary access to specific reports. Best for SaaS products, customer-facing portals, and scenarios where external users should never interact with Power BI directly. This is the model I implement 80% of the time.
| Factor | User Owns Data | App Owns Data |
|---|---|---|
| End user licensing | Pro or PPU per user | None (capacity covers all) |
| Authentication | Azure AD (user's credentials) | Service principal (app's credentials) |
| User management | Azure AD groups | Your application's user system |
| Cost model | Per-user licensing | Per-capacity (fixed monthly) |
| Data security | Power BI RLS + Azure AD | RLS with effective identity in embed token |
| Best for | Internal portals, intranets | SaaS products, customer portals |
| Implementation complexity | Lower | Higher (token management, RLS) |
Architecture and Authentication
The embedding architecture involves three components: your application backend (generates embed tokens), the Power BI JavaScript SDK in the frontend (renders reports), and Power BI Service (hosts the reports and datasets).
Service Principal Setup: For App Owns Data scenarios, create an Azure AD app registration with Power BI Service permissions (Report.Read.All, Dataset.Read.All at minimum). Add the service principal to a security group enabled in the Power BI admin portal under tenant settings. The service principal needs Member access to the workspace containing the reports. I always create a dedicated service principal for embedded analytics separate from other application identities.
Embed Token Generation: Your backend calls the Power BI REST API to generate embed tokens. Tokens are short-lived (default 1 hour, configurable up to 24 hours) and scoped to specific reports, datasets, and workspaces. Always generate tokens server-side because exposing service principal credentials to the browser is a critical security vulnerability. I cache tokens server-side with a 45-minute TTL to reduce API calls.
Token Lifecycle Management: Implement proactive token refresh in your frontend. When a token approaches expiration (I trigger at 5 minutes before expiry), request a new token from your backend and call report.setAccessToken(newToken) on the embedded report object. This refreshes the token without reloading the report or losing user state (filters, selections, scroll position). The JavaScript SDK also emits a tokenExpired event as a fallback.
JavaScript SDK Integration
The Power BI JavaScript SDK (powerbi-client) handles all rendering and interaction:
Basic Embedding: Load the SDK, create a configuration object with the embed URL, access token, and report ID, then call powerbi.embed(container, config). The SDK renders the report inside your specified DOM container. The initial load typically takes 2-4 seconds depending on report complexity and capacity tier.
Event Handling: Subscribe to events for deep application integration: - loaded: report finished rendering (hide loading spinner) - error: embedding failed (display error UI, log for debugging) - dataSelected: user clicked a data point (trigger application actions) - pageChanged: user navigated to a different page (update application state) - buttonClicked: user clicked an action button (trigger workflows)
Programmatic Filtering: Apply filters based on application context. For example, automatically filter an embedded sales report to show only the logged-in customer's data. Use report.setFilters() for report-level filters or page.setFilters() for page-level. This works alongside RLS for defense-in-depth security.
Programmatic Navigation: Control which page displays, which bookmarks are active, and which visuals are visible. This lets your application UI drive the report experience rather than relying on Power BI's built-in navigation.
Row-Level Security for Multi-Tenant Embedding
RLS is critical for App Owns Data scenarios where multiple customers view the same report. Without RLS, one customer could see another customer's data. This is the most important security control in embedded analytics.
Effective Identity: When generating embed tokens, pass an effective identity that specifies the user's role and identity values. Power BI applies RLS rules based on this identity, ensuring each customer sees only their own data. The identity values come from your application's authentication system, not from Power BI.
Dynamic RLS Implementation: Define RLS roles in the semantic model with DAX filters referencing USERNAME() or USERPRINCIPALNAME(). When generating embed tokens, pass the customer identifier (tenant ID, company name, user email) as the effective identity. The DAX filter dynamically restricts data to that customer. I typically use a TenantID column in every fact and dimension table for clean multi-tenant isolation.
Testing Multi-Tenant Security: Always test RLS with the "View as Role" feature in Power BI Desktop before embedding. Verify that cross-filter interactions do not leak data between tenants. Test with edge cases like customers with no data (should show empty report, not errors) and customers with large datasets (should not timeout). I run automated security tests that verify 10 sample tenants see only their own data after every deployment.
Capacity Planning and Licensing
Embedded analytics requires dedicated capacity. Choosing the right SKU directly impacts cost and user experience:
| SKU | V-Cores | RAM | Estimated Concurrent Users | Monthly Cost (approx) |
|---|---|---|---|---|
| A1 (Embedded) | 1 | 3 GB | 5-25 | $750 |
| A2 (Embedded) | 2 | 5 GB | 25-50 | $1,500 |
| A4 (Embedded) | 4 | 10 GB | 50-200 | $3,000 |
| A5 (Embedded) | 8 | 25 GB | 200-500 | $6,000 |
| F64 (Fabric) | 8 | 25 GB | 500+ | $5,200 |
| P1 (Premium) | 8 | 25 GB | 500+ | $5,000 |
A SKUs vs P SKUs vs F SKUs: A SKUs (Azure-billed) can be paused when not in use, making them ideal for development and applications with predictable usage patterns. P SKUs (Office 365-billed) cannot be paused but include Power BI Service features for internal users. F SKUs (Fabric capacity) provide the broadest feature set including Direct Lake mode. For new projects, I recommend F SKUs. For existing implementations, A SKUs remain cost-effective for customer-facing embedding.
Capacity Sizing Method: I size capacity based on peak concurrent users, not total users. A SaaS application with 10,000 registered users might have 200 concurrent users during peak hours. Measure actual concurrency during pilot, then select the SKU that handles peak load with 30% headroom.
White-Labeling and Customization
Embedded reports can be fully customized to match your application's brand:
- Custom themes: Apply JSON themes that set colors, fonts, and visual defaults to match your brand identity
- Navigation control: Hide the default page navigation and build custom navigation in your app's UI
- Filter pane: Hide the filter pane and build application-specific filtering UX with your own controls
- Toolbar customization: Show or hide the embedded report toolbar, print, export, and bookmark controls
- CSS styling: Control the embed container dimensions, borders, background, and overflow behavior
- Loading experience: Show your own loading animation while the report renders using the SDK's loaded event
Performance Optimization Strategies
- Pre-load the Power BI SDK and embed tokens before the user navigates to the analytics page. This eliminates 1-2 seconds from perceived load time.
- Use phaseEmbedding to load report structure first, then render visuals progressively. Users see the page layout immediately while data loads.
- Implement dataset caching in Premium/Embedded capacity to reduce query latency for popular reports.
- Monitor capacity utilization with the Premium Capacity Metrics app. Alert at 70% sustained utilization.
- Consider pagination for reports with many visuals. Load one page at a time instead of pre-rendering all pages.
- Use Import mode for embedded reports whenever possible. DirectQuery adds 2-5 seconds per visual interaction.
- Implement aggregations for large datasets to maintain interactive performance.
Common Pitfalls I See in Production
- Not implementing token refresh: Tokens expire after 1 hour. Without refresh logic, users see broken reports during long sessions.
- Under-sizing capacity: Starting with A1 for 100+ concurrent users causes throttling and 10+ second load times.
- Missing RLS testing: Data leakage between tenants discovered in production is a nightmare scenario.
- Ignoring mobile: Embedded reports need responsive design. Test on tablets and phones.
- No monitoring: You need visibility into embed failures, load times, and capacity utilization from day one.
Related Resources
Frequently Asked Questions
What is the difference between Power BI Premium and Power BI Embedded?
Power BI Premium (P SKUs) is designed for internal users within your organization. It includes full Power BI Service access, deployment pipelines, dataflows, and paginated reports. Users authenticate with Azure AD and need Pro licenses for content creation (consumers get included access through Premium capacity). Power BI Embedded (A SKUs) is designed for embedding analytics into customer-facing applications. It is billed through Azure, can be paused/resumed programmatically, and supports App Owns Data scenarios where end users do not need Power BI licenses. Key differences: P SKUs cannot be paused (always running), A SKUs can be paused (cost savings). P SKUs include admin portal features, A SKUs are managed through Azure portal. For SaaS applications serving external customers, use A SKUs. For internal portals serving employees, P SKUs are typically more cost-effective.
How do I handle embed token refresh without disrupting the user experience?
Embed tokens expire after their configured lifetime (default 1 hour). To avoid disruption, implement proactive token refresh: (1) Track token expiration time on the client side, (2) Request a new token from your backend 5-10 minutes before expiration, (3) Call report.setAccessToken(newToken) on the embedded report object—this refreshes the token without reloading the report or losing user state (filters, selections, scroll position). The JavaScript SDK also emits a tokenExpired event as a fallback—handle this event to request a new token and call setAccessToken. Never let tokens expire without refresh, as the embedded report will display an error. For high-availability scenarios, pre-fetch tokens and cache them server-side with appropriate TTL. Monitor token generation API calls to avoid throttling (limit of 50 token requests per workspace per minute).
What are the common performance problems with Power BI Embedded and how do I fix them?
Common embedded performance issues: (1) Slow initial load—report takes 5+ seconds to appear. Fix: use phaseEmbedding to show skeleton UI while loading, pre-warm capacity by keeping at least one report active, optimize the semantic model (reduce columns, implement aggregations). (2) Capacity throttling—high concurrent users cause slow queries. Fix: scale up the A/P SKU, implement query caching, reduce visual count per page (target under 8 visuals). (3) Token generation latency—backend takes 1-2 seconds per token. Fix: batch token generation for multiple reports, cache tokens with appropriate TTL, use connection pooling for API calls. (4) Cross-region latency—capacity and application in different Azure regions. Fix: co-locate capacity with your application backend. (5) Large dataset queries—DirectQuery reports slow under concurrent load. Fix: switch to Import mode or implement aggregations, use incremental refresh to keep dataset current without full reload. Monitor performance with the Premium Capacity Metrics app and Azure Application Insights integrated into your embedding application.