Skip to main content
RapidDev - Software Development Agency
bolt-ai-integrationsBolt Chat + API Route

How to Integrate Bolt.new with Microsoft Power BI

Integrate Bolt.new with Microsoft Power BI Embedded by registering an Azure AD app, generating embed tokens through a Next.js API route, and embedding reports using the powerbi-client JavaScript library. Requires an Azure AD tenant and Power BI Pro or Embedded capacity license. For lightweight analytics without licensing complexity, Google Looker Studio (formerly Data Studio) is a free alternative.

What you'll learn

  • How to register an Azure AD app with the correct Power BI API permissions
  • How to authenticate with Azure AD using MSAL to call the Power BI REST API
  • How to generate Power BI embed tokens through a server-side API route
  • How to embed Power BI reports in React using the powerbi-client-react library
  • What licensing requirements are needed for Power BI Embedded versus Power BI Pro
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate14 min read45 minutesAnalyticsApril 2026RapidDev Engineering Team
TL;DR

Integrate Bolt.new with Microsoft Power BI Embedded by registering an Azure AD app, generating embed tokens through a Next.js API route, and embedding reports using the powerbi-client JavaScript library. Requires an Azure AD tenant and Power BI Pro or Embedded capacity license. For lightweight analytics without licensing complexity, Google Looker Studio (formerly Data Studio) is a free alternative.

Embedding Power BI Reports in Bolt.new Apps

Power BI Embedded lets you embed interactive Power BI reports, dashboards, and Q&A directly in your own web application. For organizations that already have Power BI reports built by analysts, embedding them in a Bolt.new app can surface those insights in a product context — inside a customer portal, an internal operations tool, or an executive dashboard — without requiring every user to have a Power BI account or access the Power BI service directly.

The embedding architecture has three components. First, an Azure Active Directory app registration provides the application identity and grants permission to call the Power BI REST API. Second, your server-side API route uses these Azure AD credentials to get an access token and call the Power BI REST API to generate an embed token — a short-lived credential specific to one report. Third, the powerbi-client JavaScript library in your React component uses the embed token to authenticate with Power BI's embedding service and render the interactive report iframe.

Licensing is the most important thing to understand before starting. There are two supported paths: Embed for your organization (users need their own Power BI Pro or Premium Per User licenses — appropriate for internal apps), and Embed for your customers (your app has a Power BI Embedded capacity SKU — appropriate for customer-facing products). If you are prototyping, either path requires at minimum a Power BI Pro trial account. For teams evaluating alternatives, Google Looker Studio is free and embeddable, though less capable than Power BI for complex enterprise reporting needs.

Integration method

Bolt Chat + API Route

Bolt generates the Power BI embedding integration through conversation. Your Next.js API route handles Azure AD authentication and calls the Power BI REST API to generate embed tokens, which are short-lived credentials that authorize the browser to render a specific report. The powerbi-client JavaScript library renders the report client-side using that token. This pattern — server-side token generation, client-side rendering — keeps Azure AD credentials secure while enabling rich embedded analytics.

Prerequisites

  • A Microsoft Azure account with permission to register Azure AD applications (Azure portal)
  • A Power BI Pro license or Power BI Embedded capacity (A1 SKU minimum for testing) — free Power BI accounts cannot generate embed tokens
  • Power BI report(s) published to a Power BI workspace (not My Workspace — must be a collaborative workspace)
  • The workspace ID and report ID from the Power BI service URL (visible when viewing the report in powerbi.com)
  • A Next.js project in Bolt.new with the @azure/msal-node and powerbi-client-react packages installed

Step-by-step guide

1

Register an Azure AD app and configure Power BI permissions

Power BI's embedding API requires an Azure AD application to authenticate API calls. Go to portal.azure.com, navigate to Azure Active Directory → App registrations → New registration. Give the app a name (e.g., 'Bolt Power BI Embed'), set the account type to 'Accounts in this organizational directory only' for single-tenant use, and click Register. Note the Application (client) ID and Directory (tenant) ID shown on the overview page. For authentication, choose between two approaches. Service principal (recommended for production): go to Certificates & secrets → New client secret, create a secret with a 24-month expiry, and copy the value immediately — it is only shown once. User principal: you use a dedicated Power BI admin account's credentials. Service principal is more secure and is the approach covered here. Next, grant API permissions. In your app registration, click API permissions → Add a permission → Power BI Service. For the 'Embed for customers' scenario using service principal, you need Delegated permissions: Report.ReadAll and Dataset.ReadAll. Click 'Grant admin consent' after adding the permissions — without this, the consent is pending and API calls will fail. Finally, enable service principal access in the Power BI admin portal. Go to app.powerbi.com → Admin portal → Tenant settings → Developer settings → 'Allow service principals to use Power BI APIs' → Enable. Also enable 'Allow service principals to create and use profiles'. Then, in your Power BI workspace, add the service principal as a Member with Contributor role: Workspace settings → Access → add the Azure AD app by name.

Bolt.new Prompt

Create a Next.js app with Power BI Embedded integration. Add POWERBI_TENANT_ID, POWERBI_CLIENT_ID, POWERBI_CLIENT_SECRET, POWERBI_WORKSPACE_ID, and POWERBI_REPORT_ID to .env.local. Create a lib/powerbi.ts file with a getPowerBIAccessToken() function that uses MSAL Node.js client credentials flow to get an Azure AD token for the Power BI API scope (https://analysis.windows.net/powerbi/api/.default).

Paste this in Bolt.new chat

.env.local
1// .env.local
2POWERBI_TENANT_ID=your_azure_ad_tenant_id
3POWERBI_CLIENT_ID=your_azure_ad_app_client_id
4POWERBI_CLIENT_SECRET=your_azure_ad_client_secret
5POWERBI_WORKSPACE_ID=your_power_bi_workspace_id
6POWERBI_REPORT_ID=your_power_bi_report_id

Pro tip: After adding the service principal to your Power BI workspace, verify it has the Contributor role — the Member role alone is not sufficient for the service principal to generate embed tokens for reports in that workspace.

Expected result: Your Azure AD app is registered with Power BI API permissions granted, the service principal is added to the Power BI workspace as a Contributor, and the four credential values are in your .env.local file.

2

Build the token generation API route

Generating a Power BI embed token requires two API calls: one to Azure AD for an access token, and one to the Power BI REST API to exchange that access token for a report-specific embed token. The embed token is scoped to a specific report (and optionally specific RLS identities) and expires after one hour. Install the required packages. Run npm install @azure/msal-node in Bolt's terminal. The MSAL Node library handles Azure AD authentication correctly and is the recommended approach over manual HTTP calls. The Power BI embed token API endpoint is POST https://api.powerbi.com/v1.0/myorg/groups/{workspaceId}/reports/{reportId}/GenerateToken. The request body specifies the access level ('view' for read-only) and optional RLS identities if your report uses row-level security. The response includes an embed token string and an expiration time. The embed token, combined with the report's embed URL (fetched from the Power BI REST API), is what the client-side powerbi-client library needs to render the report. Fetch both in the same API route and return them together.

Bolt.new Prompt

Build the Power BI embed token API route at /api/powerbi/embed-token. It should authenticate with Azure AD using MSAL, call the Power BI REST API to get the report's embed URL, then call the GenerateToken endpoint to get an embed token. Return the embedUrl, embedToken, tokenExpiry, and reportId. Cache the access token in memory.

Paste this in Bolt.new chat

lib/powerbi.ts
1// lib/powerbi.ts
2import { ConfidentialClientApplication } from '@azure/msal-node';
3
4let msalApp: ConfidentialClientApplication | null = null;
5
6function getMsalApp() {
7 if (!msalApp) {
8 msalApp = new ConfidentialClientApplication({
9 auth: {
10 clientId: process.env.POWERBI_CLIENT_ID!,
11 clientSecret: process.env.POWERBI_CLIENT_SECRET!,
12 authority: `https://login.microsoftonline.com/${process.env.POWERBI_TENANT_ID}`,
13 },
14 });
15 }
16 return msalApp;
17}
18
19export async function getPowerBIAccessToken(): Promise<string> {
20 const app = getMsalApp();
21 const result = await app.acquireTokenByClientCredential({
22 scopes: ['https://analysis.windows.net/powerbi/api/.default'],
23 });
24 if (!result?.accessToken) throw new Error('Failed to acquire Power BI access token');
25 return result.accessToken;
26}
27
28// app/api/powerbi/embed-token/route.ts
29import { NextRequest, NextResponse } from 'next/server';
30import { getPowerBIAccessToken } from '@/lib/powerbi';
31
32const PBI_API = 'https://api.powerbi.com/v1.0/myorg';
33
34export async function GET(request: NextRequest) {
35 const { searchParams } = new URL(request.url);
36 const workspaceId = searchParams.get('workspaceId') ?? process.env.POWERBI_WORKSPACE_ID!;
37 const reportId = searchParams.get('reportId') ?? process.env.POWERBI_REPORT_ID!;
38
39 const accessToken = await getPowerBIAccessToken();
40 const headers = { Authorization: `Bearer ${accessToken}` };
41
42 // Step 1: Get the report's embed URL
43 const reportResponse = await fetch(
44 `${PBI_API}/groups/${workspaceId}/reports/${reportId}`,
45 { headers }
46 );
47 if (!reportResponse.ok) {
48 return NextResponse.json({ error: 'Failed to fetch report metadata' }, { status: reportResponse.status });
49 }
50 const report = await reportResponse.json();
51
52 // Step 2: Generate the embed token
53 const tokenResponse = await fetch(
54 `${PBI_API}/groups/${workspaceId}/reports/${reportId}/GenerateToken`,
55 {
56 method: 'POST',
57 headers: { ...headers, 'Content-Type': 'application/json' },
58 body: JSON.stringify({ accessLevel: 'view' }),
59 }
60 );
61 if (!tokenResponse.ok) {
62 return NextResponse.json({ error: 'Failed to generate embed token' }, { status: tokenResponse.status });
63 }
64 const tokenData = await tokenResponse.json();
65
66 return NextResponse.json({
67 reportId,
68 embedUrl: report.embedUrl,
69 embedToken: tokenData.token,
70 tokenExpiry: tokenData.expiration,
71 });
72}

Pro tip: MSAL's ConfidentialClientApplication internally caches tokens and handles refresh automatically. You do not need to implement your own token cache for the Azure AD access token — MSAL manages this correctly across function calls.

Expected result: Calling /api/powerbi/embed-token returns a JSON object with embedUrl, embedToken, and tokenExpiry that the client-side component needs to render the Power BI report.

3

Embed the Power BI report in a React component

With an embed token and embed URL from the API route, you can render the Power BI report in your React component using the powerbi-client-react library. Install it: npm install powerbi-client-react powerbi-client. The library provides a PowerBIEmbed React component that wraps the Power BI JavaScript SDK. The PowerBIEmbed component takes an embedConfig object with the report type, embed URL, access token, and display settings. It also accepts event handlers for events like rendered (when the report finishes loading), error, and dataSelected (when a user clicks a data point). These events let you respond to user interactions within the embedded report from your React app. Token expiry handling is important for production. Embed tokens expire after one hour. The Power BI client library fires a tokenExpired event when the current token is about to expire. Handle this event by calling your API route for a new embed token and passing it to the component's updateSettings method. If you do not handle token expiry, the embedded report becomes non-interactive after an hour without refreshing the page. For Row Level Security (RLS), add an identities array to the GenerateToken request body: identities: [{ username: user.email, roles: ['SalesRegion_East'], datasets: [dataset_id] }]. The RLS role and dataset ID must match the RLS configuration in your Power BI report.

Bolt.new Prompt

Create a PowerBIReport React component that fetches an embed token from /api/powerbi/embed-token and renders the report using powerbi-client-react. Show a loading skeleton while the token loads. Handle token expiry by re-fetching the token from the API and passing it to the embedded report. Add error state with a retry button. Make the component accept reportId and workspaceId as optional props.

Paste this in Bolt.new chat

components/PowerBIReport.tsx
1// components/PowerBIReport.tsx
2'use client';
3import { useEffect, useState, useCallback } from 'react';
4import { PowerBIEmbed } from 'powerbi-client-react';
5import { models, Report } from 'powerbi-client';
6
7interface EmbedConfig {
8 embedUrl: string;
9 embedToken: string;
10 reportId: string;
11 tokenExpiry: string;
12}
13
14interface PowerBIReportProps {
15 reportId?: string;
16 workspaceId?: string;
17 height?: number;
18}
19
20export function PowerBIReport({ reportId, workspaceId, height = 600 }: PowerBIReportProps) {
21 const [config, setConfig] = useState<EmbedConfig | null>(null);
22 const [loading, setLoading] = useState(true);
23 const [error, setError] = useState<string | null>(null);
24
25 const fetchEmbedToken = useCallback(async () => {
26 try {
27 const params = new URLSearchParams();
28 if (reportId) params.set('reportId', reportId);
29 if (workspaceId) params.set('workspaceId', workspaceId);
30
31 const response = await fetch(`/api/powerbi/embed-token?${params.toString()}`);
32 if (!response.ok) throw new Error('Failed to fetch embed token');
33
34 const data = await response.json();
35 setConfig(data);
36 setError(null);
37 } catch (err) {
38 setError(err instanceof Error ? err.message : 'Failed to load report');
39 } finally {
40 setLoading(false);
41 }
42 }, [reportId, workspaceId]);
43
44 useEffect(() => { fetchEmbedToken(); }, [fetchEmbedToken]);
45
46 if (loading) return <div style={{ height }} className="animate-pulse bg-gray-100 rounded" />;
47 if (error) return (
48 <div className="flex flex-col items-center justify-center" style={{ height }}>
49 <p className="text-red-500">{error}</p>
50 <button onClick={fetchEmbedToken} className="mt-2 px-4 py-2 bg-blue-500 text-white rounded">
51 Retry
52 </button>
53 </div>
54 );
55 if (!config) return null;
56
57 return (
58 <PowerBIEmbed
59 embedConfig={{
60 type: 'report',
61 id: config.reportId,
62 embedUrl: config.embedUrl,
63 accessToken: config.embedToken,
64 tokenType: models.TokenType.Embed,
65 settings: {
66 navContentPaneEnabled: false,
67 filterPaneEnabled: false,
68 },
69 }}
70 cssClassName="powerbi-report-container"
71 getEmbeddedComponent={(embeddedReport) => {
72 (embeddedReport as Report).on('tokenExpired', () => {
73 fetchEmbedToken();
74 });
75 }}
76 style={{ height: `${height}px`, width: '100%' }}
77 />
78 );
79}

Pro tip: Add the CSS class powerbi-report-container to your global CSS with height: 100% to ensure the embedded iframe fills the container properly. The powerbi-client library requires its host element to have a defined height.

Expected result: The PowerBIReport component renders a fully interactive Power BI report in the browser. Users can use report filters, drill through data, and export visuals using Power BI's embedded toolbar.

Common use cases

Embedded operations dashboard

An operations team has built a comprehensive Power BI report showing supply chain metrics, inventory levels, and order fulfillment rates. Embed that report in your internal ops portal so the team can access it without logging into Power BI separately, with single sign-on from your app's authentication.

Bolt.new Prompt

Add a Power BI embedded analytics section to my internal operations dashboard. Create a component that calls /api/powerbi/embed-token with a workspace ID and report ID, then renders the Power BI report using the powerbi-client-react library. The report should fill the full width of the content area at 650px height with the toolbar hidden.

Copy this prompt to try it in Bolt.new

Per-customer analytics in a SaaS product

Your SaaS product generates usage data stored in a data warehouse connected to Power BI. Each customer has a Power BI report scoped to their data using Row Level Security (RLS). Embed the report in your customer portal with the customer's identity passed through RLS so each customer only sees their own data.

Bolt.new Prompt

Create a customer analytics page that embeds a Power BI report with Row Level Security. When generating the embed token, include the user's company ID as the RLS username so Power BI filters the data to show only that company's records. Use the 'Embed for customers' pattern with a service principal.

Copy this prompt to try it in Bolt.new

Executive KPI summary

Executives want a single-page view of the company's key performance indicators pulled from multiple Power BI reports. Embed specific visualizations from different reports as tiles in a custom layout, creating a curated view that does not exist as a single report in Power BI.

Bolt.new Prompt

Build an executive dashboard that embeds multiple Power BI report pages. Create a tab navigation component where each tab shows a different page of the main executive report, embedded using the Power BI client library with the page parameter set. Disable the navigation pane inside the embedded report.

Copy this prompt to try it in Bolt.new

Troubleshooting

API route returns 403 when calling GenerateToken — 'The caller does not have permission to perform this operation'

Cause: The service principal is not added to the Power BI workspace with at least Contributor role, or the Power BI tenant admin has not enabled 'Allow service principals to use Power BI APIs' in the admin portal.

Solution: In the Power BI Admin portal (app.powerbi.com → Admin portal → Tenant settings), verify 'Allow service principals to use Power BI APIs' is enabled for all users or your specific security group. Then in your Power BI workspace settings → Access, confirm the Azure AD app is listed with Member or Contributor role. Changes to tenant settings can take up to 15 minutes to propagate.

MSAL throws 'AADSTS70011: The provided request must include a resource input parameter'

Cause: The scopes parameter in the token request is incorrect. Power BI requires the scope to be exactly 'https://analysis.windows.net/powerbi/api/.default' including the /.default suffix.

Solution: Verify the scopes array in the acquireTokenByClientCredential call is exactly ['https://analysis.windows.net/powerbi/api/.default']. The /.default suffix is required for client credentials flow — it tells Azure AD to use all statically configured application permissions.

typescript
1// Correct scope format for Power BI client credentials:
2scopes: ['https://analysis.windows.net/powerbi/api/.default']
3// NOT: 'https://analysis.windows.net/powerbi/api'

The Power BI embed component shows 'Sorry, we ran into an issue' error in the embedded iframe

Cause: The embed token is valid but the report embed URL is incorrect, the report has been moved or deleted, or the report requires a capacity that is not available. This can also happen if the embed token was generated for a different report ID than the one in the embedConfig.

Solution: Verify that reportId in the API response matches what is set in the PowerBIEmbed embedConfig. Check that the report still exists in the Power BI workspace by visiting it directly at app.powerbi.com. Ensure the workspace has an active Premium capacity or Power BI Embedded capacity if using the 'embed for customers' scenario.

Best practices

  • Use service principal authentication for production deployments — it does not depend on a user account password that can expire or be changed, making it more reliable than user-based credentials.
  • Store all Azure AD credentials (POWERBI_CLIENT_ID, POWERBI_CLIENT_SECRET, POWERBI_TENANT_ID) in server-side environment variables and never in NEXT_PUBLIC_ prefixed variables or client-side code.
  • Handle the tokenExpired event from the powerbi-client library and refresh the embed token automatically — users should not need to reload the page when the one-hour token expires during a work session.
  • For simpler analytics needs without Azure AD complexity, evaluate Google Looker Studio (free) or Tableau Public (free for public data) as alternatives before committing to the Power BI Embedded licensing and setup requirements.
  • Use Row Level Security in your Power BI reports and pass user identity in the GenerateToken request to automatically scope data visibility — this is more secure than maintaining separate reports per user.
  • Disable the filter pane and navigation pane in the embedConfig settings for most embedded scenarios — they add visual complexity that is usually not appropriate when the report is embedded in a larger application UI.
  • Embed tokens expire after one hour but can be refreshed without user interaction. Implement a background refresh that fetches a new token 5 minutes before expiry and passes it to the embedded report using the report.setAccessToken() method.

Alternatives

Frequently asked questions

Can I test the Power BI embedding in Bolt's development preview?

Yes. The Power BI embed token API calls are outbound HTTPS requests from your server-side Next.js routes, which work fine in Bolt's WebContainer. The powerbi-client library is a browser-side JavaScript library that also works in the preview. The main constraint is that both your Azure AD app permissions and Power BI workspace access must be correctly configured before any of the embedding works — these are setup steps that happen outside of Bolt.

Does Bolt.new have a native Power BI integration?

No. Power BI is not one of Bolt's native connectors. You build the integration yourself using Next.js API routes and the Power BI REST API. Bolt's AI can generate the integration code when you describe what analytics embedding features you need, but Azure AD app registration and Power BI workspace configuration must be done manually in the Azure and Power BI portals.

What Power BI license do I need to embed reports?

For internal apps where all viewers are in your organization (Embed for your organization), each viewer needs a Power BI Pro license ($10/user/month) or a Power BI Premium Per User license ($20/user/month). For customer-facing apps where viewers are outside your organization (Embed for your customers), your organization needs a Power BI Embedded capacity SKU (starting at A1 SKU, approximately $735/month). Free Power BI accounts cannot generate embed tokens.

Can I embed Power BI dashboards as well as reports?

Yes. The Power BI Embedded API supports embedding reports, dashboards, tiles (individual visuals from a dashboard), Q&A experiences, and paginated reports. The PowerBIEmbed component's type field accepts 'report', 'dashboard', 'tile', 'qna', or 'paginated-report'. Each type has slightly different API endpoints for generating the embed token and embed URL.

How do I pass user-specific filters to an embedded Power BI report?

There are two approaches. For Row Level Security (recommended for data security), configure RLS roles in Power BI Desktop and pass the user's identity in the GenerateToken API call's identities array. Power BI automatically applies the RLS filter server-side. For display-level filters (not enforced at data level), use the powerbi-client API's setFilters() method after the report renders to apply visual filters based on the current user's context.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.