Connect Retool to Microsoft Power BI by creating a REST API Resource pointing to the Power BI REST API, authenticated via Azure AD OAuth 2.0. Embed existing Power BI reports in Retool using a Custom Component iframe, or pull Power BI dataset data into native Retool charts and tables. All API calls are proxied server-side through Retool, keeping Azure AD tokens secure.
| Fact | Value |
|---|---|
| Tool | Microsoft Power BI |
| Category | Analytics |
| Method | REST API Resource |
| Difficulty | Intermediate |
| Time required | 30 minutes |
| Last updated | April 2026 |
Why Connect Retool to Power BI?
Many enterprise organizations run Power BI as their primary reporting layer, with analysts maintaining reports and dashboards that business stakeholders consume. However, operations teams and internal tool users often need those same insights surfaced alongside operational data and actions — not in a separate browser tab. Connecting Retool to Power BI allows you to either pull Power BI dataset data directly into Retool's native visualization components, or embed existing Power BI reports as interactive iframes within a Retool app so users never leave the internal tool context.
The Power BI REST API provides programmatic access to workspaces, datasets, reports, and data refresh operations. From Retool, you can build an admin panel that lists all Power BI workspaces, shows which datasets need a data refresh, triggers refreshes on demand, and monitors refresh history — all operations that would otherwise require navigating the Power BI web portal manually. For data science and BI operations teams, this kind of management interface reduces time spent on administrative tasks significantly.
The embedding approach is particularly useful for organizations where Power BI already contains the authoritative visualizations that stakeholders trust. Rather than rebuilding those charts from scratch in Retool, embedding the actual Power BI report preserves the existing work while integrating it into a broader operational context. The key engineering consideration is generating embed tokens securely — a process Retool handles well because the Power BI API call that generates the token runs server-side through the REST API Resource proxy.
Integration method
Retool connects to Power BI's REST API (api.powerbi.com) through a REST API Resource configured with Azure Active Directory OAuth 2.0 authentication. Retool proxies all Power BI API requests server-side, keeping Azure AD credentials off the browser. For embedding full Power BI report visuals, you can use Retool's Custom Component feature to render a Power BI Embedded iframe — this requires generating an embed token via the Power BI API and passing it securely from a Retool query.
Prerequisites
- A Retool account (Cloud or self-hosted) with permission to add Resources
- An Azure Active Directory tenant with admin access to register an app registration
- A Power BI Pro or Power BI Premium workspace (Power BI Free doesn't support API access or embedding for non-owners)
- The Power BI workspace ID and report ID you want to work with (found in the Power BI service URL when viewing a report)
- Basic familiarity with Azure AD app registrations and OAuth 2.0 flows
Step-by-step guide
Register an Azure AD app for Power BI API access
Power BI's REST API requires Azure Active Directory authentication. You must register an app in your Azure AD tenant to get the OAuth credentials Retool will use. Navigate to portal.azure.com and sign in with an account that has permission to register Azure AD applications (Azure AD → App Registrations requires at minimum Application Developer or Global Administrator role). Go to Azure Active Directory → App Registrations → New Registration. Fill in the registration form: - Name: 'Retool Power BI Integration' or similar - Supported account types: 'Accounts in this organizational directory only' (for single-tenant/internal use) - Redirect URI: Select 'Web' and enter your Retool OAuth callback URL. For Retool Cloud, this is https://oauth.retool.com/oauth/user/oauthcallback. For self-hosted Retool, it is https://your-retool-instance.com/oauth/user/oauthcallback. Click Register. On the app's overview page, note the Application (client) ID and Directory (tenant) ID — you'll need both for the Retool resource configuration. Navigate to Certificates & Secrets → Client Secrets → New Client Secret. Add a description and expiry (24 months is common for internal tooling). Copy the Value immediately — it is only shown once. Navigate to API Permissions → Add a Permission → Power BI Service. Select Delegated Permissions and add: Report.Read.All, Dataset.Read.All, Dataset.ReadWrite.All (if you need refresh triggers), Workspace.Read.All. Click Grant Admin Consent to pre-approve these permissions for all users in your tenant — this prevents individual consent prompts for each Retool user.
Pro tip: After granting admin consent, verify the permission status shows 'Granted for [Tenant Name]' with a green checkmark next to each permission in the API Permissions list. If permissions show as 'Not granted', the API calls will return 403 errors even with valid credentials.
Expected result: An Azure AD app registration exists with client ID, client secret, and Power BI API permissions granted. You have the client ID, client secret, and tenant ID values ready to configure in Retool.
Create the Power BI REST API Resource in Retool
With your Azure AD app credentials ready, configure the Retool REST API Resource to authenticate with Power BI's API. Open Retool and navigate to the Resources tab. Click Add Resource and select REST API. Fill in the configuration: - Name: 'Microsoft Power BI' - Base URL: https://api.powerbi.com/v1.0/myorg For authentication, select OAuth 2.0 from the Auth dropdown. Configure the OAuth 2.0 settings: - Grant type: Authorization Code - Authorization URL: https://login.microsoftonline.com/{{ YOUR_TENANT_ID }}/oauth2/v2.0/authorize (replace with your actual tenant ID) - Access Token URL: https://login.microsoftonline.com/{{ YOUR_TENANT_ID }}/oauth2/v2.0/token - Client ID: paste your Azure AD app's Application (client) ID - Client Secret: paste the client secret value you saved - Scope: https://analysis.windows.net/powerbi/api/.default offline_access - Share OAuth 2.0 credentials between users: enable this if all Retool users should access Power BI under a single service account identity (common for internal tools) Click Connect Account. A Microsoft login popup opens — sign in with the Power BI account that has access to the workspaces you need. After authentication, the resource shows a green Connected status. Add a default header to all requests: Content-Type: application/json. Click Save Changes.
Pro tip: For production deployments where you want all Retool users to access Power BI under a single service identity (rather than their individual Power BI accounts), enable 'Share OAuth 2.0 credentials between users' and authenticate with a dedicated service account that has access to all required workspaces.
Expected result: The Power BI REST API Resource appears in the Resources list with a connected OAuth status. Creating a query with this resource and making a GET request to /groups returns a list of Power BI workspaces.
Query workspaces, datasets, and reports
With the resource configured, you can now build queries that interact with the Power BI REST API. Create a new query in your Retool app and select the Power BI resource. To list all workspaces (groups) you have access to: - Method: GET - Path: /groups Run this query to verify the connection. The response contains an array of workspace objects, each with an id, name, and isOnDedicatedCapacity flag. To list reports in a specific workspace: - Method: GET - Path: /groups/{{ workspaceSelect.value }}/reports Bind the path parameter to a Select component populated with workspace data from the first query. Use a transformer on the first query to map workspaces to { label: ws.name, value: ws.id } format for the Select component. To list datasets: - Method: GET - Path: /groups/{{ workspaceSelect.value }}/datasets To get refresh history for a specific dataset: - Method: GET - Path: /groups/{{ workspaceSelect.value }}/datasets/{{ datasetTable.selectedRow.id }}/refreshes Set up all queries to run automatically when their inputs change (workspace selection, dataset selection) using the 'Run this query automatically when inputs change' toggle. Add 'Only run when' conditions to prevent errors when no workspace or dataset is selected.
1// JavaScript transformer to format workspace list for Select component2// Apply on the List Workspaces query3const workspaces = data.value || [];4return workspaces.map(ws => ({5 label: ws.name,6 value: ws.id,7 is_premium: ws.isOnDedicatedCapacity,8 type: ws.type9}));1011// JavaScript transformer for datasets table12// Shows refresh status and timing at a glance13const datasets = data.value || [];14return datasets.map(ds => ({15 id: ds.id,16 name: ds.name,17 configured_by: ds.configuredBy || '',18 is_refreshable: ds.isRefreshable,19 is_on_prem_gateway: ds.isOnPremGatewayRequired,20 last_refresh: ds.Refresh?.endTime21 ? new Date(ds.Refresh.endTime).toLocaleString()22 : 'Never refreshed'23}));Pro tip: Power BI's API uses camelCase inconsistently across endpoints — some responses wrap results in a 'value' array (data.value), while others return arrays directly. Always inspect the raw query response in Retool's Run panel before writing transformers to understand the actual response shape.
Expected result: A workspace dropdown populates from the Power BI API. Selecting a workspace loads its datasets and reports in separate tables. Selecting a dataset shows its refresh history in a detail panel.
Trigger on-demand dataset refreshes from Retool
Power BI scheduled refreshes run at configured intervals, but operations teams often need to trigger an immediate refresh when they know source data has updated. Build a dataset refresh trigger directly in Retool. Create a new query with: - Method: POST - Path: /groups/{{ workspaceSelect.value }}/datasets/{{ datasetTable.selectedRow.id }}/refreshes - Body type: JSON - Body: {} (Power BI accepts an empty JSON body for a basic on-demand refresh; you can add notifyOption parameters for email notifications) Set this query to Manual trigger. Wire it to a 'Trigger Refresh' button in the dataset table's row actions, with a confirmation dialog: 'Trigger an on-demand refresh for dataset {{ datasetTable.selectedRow.name }}?' On Success, add event handlers to: show a success notification ('Refresh triggered. May take a few minutes to complete.'), then re-run the refresh history query to see the new pending entry appear. Note: Power BI's refresh API returns 202 Accepted immediately — the actual refresh runs asynchronously. The refresh history query shows status as 'Unknown' or 'InProgress' initially, then updates to 'Completed' or 'Failed'. Consider adding a manual 'Check refresh status' button rather than auto-polling, to avoid excessive API calls. For tracking refreshes across your entire workspace, create a transformer that joins the dataset list with their latest refresh history and shows last refresh time and status in the main datasets table — giving BI administrators a full health view at a glance.
1// POST body for triggering a Power BI dataset refresh2// Power BI also supports notifyOption for email notifications on completion3{4 "notifyOption": "NoNotification"5}67// JavaScript transformer to show refresh status with color coding8// Apply on the refresh history query for the selected dataset9const refreshes = data.value || [];10return refreshes.slice(0, 20).map(r => ({ // show last 20 refreshes11 id: r.requestId,12 status: r.status,13 refresh_type: r.refreshType,14 start_time: r.startTime ? new Date(r.startTime).toLocaleString() : '',15 end_time: r.endTime ? new Date(r.endTime).toLocaleString() : 'In progress',16 duration_seconds: (r.startTime && r.endTime)17 ? Math.round((new Date(r.endTime) - new Date(r.startTime)) / 1000)18 : null,19 service_exception: r.serviceExceptionJson20 ? JSON.parse(r.serviceExceptionJson)?.errorCode || 'Error'21 : ''22}));Pro tip: Power BI limits on-demand refreshes to 8 per day for Pro datasets (48 per day for Premium). Track refresh counts in a Retool variable and disable the Trigger Refresh button when the limit is close, rather than letting users hit Power BI's API rate limit error.
Expected result: Clicking Trigger Refresh sends a POST to the Power BI API and receives a 202 response. The refresh history table shows a new entry with 'Unknown' or 'InProgress' status. Refreshing the status a few minutes later shows 'Completed' when the refresh finishes.
Embed a Power BI report in a Retool Custom Component
For teams that want to display actual Power BI report visuals (not just data) within Retool, use Power BI Embedded via Retool's Custom Component feature. This approach generates a short-lived embed token server-side and renders the interactive report in an iframe. First, create a query to generate an embed token: - Method: POST - Path: /groups/{{ workspaceSelect.value }}/reports/{{ reportTable.selectedRow.id }}/GenerateToken - Body type: JSON - Body: { "accessLevel": "View" } This returns an embed token (data.token) and an embed URL (data.embedUrl) valid for approximately 60 minutes. Next, create a Custom Component in Retool (Component panel → Custom Component). In the Custom Component code editor, write HTML that loads the Power BI JavaScript SDK and renders the report using the embed token from your query: Wire the Custom Component's model data to pass the embed token and URL from your Retool query: set the model to { token: {{ generateEmbedTokenQuery.data.token }}, embedUrl: {{ reportTable.selectedRow.embedUrl }} }. The component's JavaScript reads these values from the model and calls the Power BI SDK's embed function. For complex integrations combining Power BI embedding with multiple data sources, custom page-level filters, and report interaction events feeding back into Retool, RapidDev's team can help design the full architecture including token refresh logic and bidirectional data flow between the embedded report and Retool components.
1<!-- Power BI Custom Component HTML/JS -->2<!-- Paste this into Retool's Custom Component code editor -->3<div id="reportContainer" style="height: 600px; width: 100%;"></div>4<script src="https://cdn.jsdelivr.net/npm/powerbi-client@2.22.3/dist/powerbi.min.js"></script>5<script>6 const powerbi = window['powerbi-client'].default;7 8 // Watch for model changes (token/URL passed from Retool queries)9 Retool.subscribe(function(model) {10 if (!model.token || !model.embedUrl) return;11 12 const config = {13 type: 'report',14 id: model.reportId || undefined,15 embedUrl: model.embedUrl,16 accessToken: model.token,17 tokenType: powerbi.models.TokenType.Embed,18 settings: {19 panes: {20 filters: { visible: true },21 pageNavigation: { visible: true }22 },23 background: powerbi.models.BackgroundType.Transparent24 }25 };26 27 const container = document.getElementById('reportContainer');28 const report = powerbi.embed(container, config);29 30 // Notify Retool when report loads31 report.on('loaded', function() {32 Retool.modelUpdate({ reportLoaded: true });33 });34 });35</script>Pro tip: Power BI embed tokens expire after 60 minutes by default. Add a 'Refresh Embed Token' button in Retool that re-runs the GenerateToken query and updates the Custom Component's model with the new token — this prevents the embedded report from going blank mid-session.
Expected result: The Custom Component renders the selected Power BI report as a fully interactive iframe within the Retool app. Users can interact with report filters, drill down into visuals, and switch pages — all within the Retool interface. The report reflects live Power BI data.
Common use cases
Build a Power BI report embed portal in Retool
Create a Retool app that lets internal users browse available Power BI reports in their workspace, select one from a dropdown, and view the full interactive report embedded in the Retool page — without needing a Power BI Pro license for each viewer. The Retool app handles the embed token generation via the Power BI API and renders the report in a Custom Component. Users interact with the report's filters and drill-downs directly within Retool.
Build a Power BI report viewer panel in Retool. Show a dropdown that lists all reports in the specified Power BI workspace. When a report is selected, generate an embed token via the Power BI API and render the report using Power BI Embedded in a Custom Component iframe. Include a refresh button that regenerates the embed token when it expires.
Copy this prompt to try it in Retool
Build a dataset refresh monitoring dashboard
Create a Retool operations panel for BI admins that shows all Power BI datasets across workspaces with their last refresh time, refresh status (success, failed, in progress), and scheduled refresh configuration. Admins can trigger a manual refresh on any dataset from the Retool interface and monitor the refresh history log. This is particularly useful when business stakeholders report stale data — admins can immediately see and fix the issue without navigating Power BI's management portal.
Create a dataset management panel that lists all Power BI datasets with their workspace name, last refresh time, and refresh status. Add a 'Trigger Refresh' button for each row that calls the Power BI API to start an on-demand refresh. Show the last 10 refresh history entries for the selected dataset in a detail panel. Highlight datasets whose last refresh was more than 24 hours ago in orange.
Copy this prompt to try it in Retool
Combine Power BI dataset data with internal database in a custom dashboard
Build a Retool dashboard that pulls raw data from a Power BI dataset using the Execute Queries API, then combines it with your internal operational database in a JavaScript transformer to create enriched charts and tables. For example, pull Power BI's customer segmentation model output and join it with your CRM database's deal pipeline data — creating an enriched sales forecast panel that neither Power BI nor your internal database could produce alone.
Create a sales operations dashboard that queries Power BI's customer segmentation dataset using the Execute Queries API, then joins the results with the internal deals table from the PostgreSQL database in a JavaScript transformer. Display a combined table showing each deal with the customer's BI-predicted segment and churn risk score alongside the pipeline stage and deal value.
Copy this prompt to try it in Retool
Troubleshooting
Power BI API returns 401 Unauthorized even though OAuth flow completed successfully in Retool
Cause: The OAuth token obtained may not have the correct scopes, the admin consent was not granted for the required permissions, or the token has expired and Retool's automatic refresh is failing.
Solution: Go to the Azure AD portal → App Registrations → your app → API Permissions and verify that all Power BI permissions show 'Granted for [Tenant Name]' with a green checkmark. If any show 'Not granted', click 'Grant admin consent for [Tenant]'. Then return to Retool's Resources tab, click your Power BI resource, and click 'Connect Account' again to re-authenticate with a fresh token.
List Workspaces (GET /groups) returns an empty 'value' array even though the user has Power BI workspaces
Cause: The authenticated account only has access to the default 'My Workspace' (personal workspace), which does not appear in the /groups endpoint. The account may not have been added as a member of any shared workspaces, or the OAuth permissions may not include Workspace.Read.All.
Solution: Verify the authenticated account has been added as at least a Viewer to the relevant Power BI workspaces (Power BI Service → Workspace → Settings → Access). Also confirm that Workspace.Read.All delegated permission is included in the Azure AD app's API permissions and that admin consent has been granted. The account's personal 'My Workspace' will not appear in the /groups response — shared workspaces only.
GenerateToken API returns 403 with 'Forbidden' when trying to embed a report
Cause: The Power BI workspace or capacity is not configured for embedding, the authenticated account lacks adequate permissions on the report, or the workspace is not on Power BI Premium/Embedded capacity (required for embedding without per-user Power BI Pro licenses).
Solution: For embedding without requiring each viewer to have a Power BI Pro license, the workspace must be on Power BI Premium or a dedicated Embedded capacity. Check the workspace settings in Power BI Service → Workspace → Settings → Premium tab. If embedding with per-user Pro licenses is acceptable, ensure the authenticated service account has at least Contributor access to the workspace and that the report allows embedding.
Dataset refresh trigger returns 200 but the refresh history shows the same 'Failed' entry as before
Cause: The Power BI dataset may have a gateway connection issue, the data source credentials stored in Power BI may have expired, or the dataset has a dependency on an on-premises data gateway that is offline.
Solution: Check the dataset's refresh history details in Power BI Service → Workspace → Datasets → (dataset) → Refresh History. The serviceExceptionJson field in the refresh history API response also contains the error code. Common fixes: update data source credentials in Power BI Dataset Settings, verify the on-premises gateway is running and connected, or check that the data source server is accessible from Power BI's cloud.
1// JavaScript to parse the serviceExceptionJson error from refresh history2// Add this to your refresh history transformer to surface errors clearly3service_exception: r.serviceExceptionJson4 ? (() => {5 try {6 const ex = JSON.parse(r.serviceExceptionJson);7 return ex.errorCode + ': ' + (ex.parameters?.[0] || '');8 } catch { return r.serviceExceptionJson; }9 })()10 : ''Best practices
- Use a dedicated service account for the Power BI OAuth connection with 'Share credentials between users' enabled — this prevents broken connections when individual employee accounts change passwords or are deactivated.
- Request only the Power BI API scopes you actually need — read-only dashboards only need Report.Read.All and Dataset.Read.All, not write permissions.
- Store the Azure AD client secret in Retool Configuration Variables marked as secret, not hardcoded in resource settings, so it can be rotated without editing the resource.
- Power BI embed tokens expire after 60 minutes — implement a token refresh button or a JavaScript timer that regenerates the embed token before it expires to prevent the report from going blank mid-session.
- For large organizations with many workspaces, pre-filter the workspace list in your transformer to show only the workspaces relevant to each team, reducing cognitive load and navigation time.
- Always add 'Only run when' conditions to workspace-scoped queries (reports, datasets, refresh history) to prevent API calls when no workspace is selected in the dropdown.
- Test the OAuth flow and API permissions thoroughly in a development Power BI workspace before pointing the integration at production workspaces — permission issues are easier to diagnose in isolation.
- Consider whether native Retool charts (built from raw data) or embedded Power BI reports (preserving existing visualizations) better serve your use case — embedding adds complexity but preserves existing analytical work.
Alternatives
Choose Tableau if your organization uses Tableau Server or Tableau Cloud as the primary BI platform, which uses Tableau REST API and Trusted Authentication rather than Azure AD OAuth.
Choose Looker if your team uses Google's Looker platform, which offers a REST API and SDK for embedding visualizations and querying LookML-defined data models from Retool.
Choose Google Analytics if your analytics needs center on web traffic and user behavior data rather than business intelligence reporting across enterprise data sources.
Frequently asked questions
Does connecting Retool to Power BI require each user to have a Power BI Pro license?
It depends on how you use the integration. For the REST API data extraction approach (pulling data from Power BI datasets into Retool charts), only the service account used for OAuth needs a Power BI Pro license. For embedding interactive Power BI reports via the GenerateToken API, either each viewer needs a Pro license, or the workspace must be on Power BI Premium or dedicated Embedded capacity (which allows viewer access without per-user licenses). Using 'Share credentials between users' in the Retool resource configuration lets all Retool users share a single Pro service account.
How do I secure API access when embedding Power BI dashboards in Retool?
The key security principle is that embed tokens must be generated server-side, never in the browser. In Retool, this is handled correctly because the GenerateToken API call goes through Retool's server-side resource proxy — the Azure AD OAuth token and Power BI API key never reach the browser. The short-lived embed token (60 minutes) is what gets passed to the frontend Custom Component for rendering. Restrict the Azure AD app's Power BI permissions to read-only if viewers should not be able to export or edit reports.
Can I filter an embedded Power BI report to show only data relevant to a selected row in a Retool table?
Yes, using the Power BI JavaScript SDK's setFilters method or by passing report-level filters in the embed configuration. In your Custom Component, when the Retool model updates with a new filter value (e.g., a customer ID from a selected table row), call report.setFilters([{ target: { table: 'Customers', column: 'CustomerID' }, operator: 'In', values: [customerId] }]) to apply a filter to the embedded report. This creates bidirectional interaction between Retool table selections and the embedded Power BI visualization.
What is the difference between Power BI REST API data and embedded Power BI reports in Retool?
The REST API data approach uses Power BI's Execute Queries API to pull raw data from Power BI datasets into Retool, where you then build visualizations using Retool's native Chart, Table, and Stat components. This gives you full control over the visualization but requires rebuilding the display logic. The embed approach renders the actual Power BI report visual inside a Retool iframe using Power BI Embedded — preserving existing visualizations but adding token management complexity and requiring Premium capacity for license-free viewing.
How do I handle Power BI API rate limits in Retool?
Power BI's REST API has rate limits that vary by endpoint and subscription tier. For operations that poll frequently (like refresh status checks), avoid auto-triggering queries on timers — use manual refresh buttons instead. The dataset refresh endpoint is limited to 8 refreshes per day for Pro (48 for Premium). The GenerateToken endpoint allows up to 200 requests per hour per user. For Retool apps used by many concurrent users, the 'Share credentials' option means all users share the same rate limit bucket, so plan accordingly for high-traffic dashboards.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation