SharePoint  

Integrate Power BI with SPFx: Retrieve Reports, Workspaces & Groups

Power BI is a strong data visualization platform, and embedding Power BI content within SharePoint Framework (SPFx) allows users to get actionable insights directly in their workflow. In this blog, we are going to learn how to:

  1. Configure Power BI with SPFx
  2. Retrieve Power BI Workspaces
  3. List Reports within a Workspace
  4. Retrieve Groups (Power BI workspaces) with member details

Now let’s get going with integrating Power BI + SPFx using Microsoft Graph and Power BI REST APIs.

Step 1. Set up SPFx for Power BI Integration

Start by creating a new SPFx solution

yo @microsoft/sharepoint

Select

  • What is your solution name? PowerBIIntegration
  • Which type of client-side component to create?  WebPart
  • What is your Web part name? PowerBiReportEmbed
  • Which template would you like to use? React

Step 2. Register Azure AD App for Power BI Access

  1. Go to Azure Portal → App registrations.
  2. Register a new app (or use the SPFx app).
  3. Expose API Permissions:
    • Microsoft Graph:
      • Group.Read.All
      • User.Read
    • Power BI Service:
      • Dataset.Read.All
      • Report.Read.All
      • Workspace.Read.All
  4. Generate a Client Secret.
  5. In API permissions, click Grant admin consent.

Step 3. Install Required Packages

npm install powerbi-client powerbi-models --save

​Step 4. Add this graph Power BI API to package-solution.json

"webApiPermissionRequests": [
  {
    "resource": "Power BI Service",
    "scope": "Group.Read.All"
  },
  {
    "resource": "Power BI Service",
    "scope": "Dataset.Read.All"
  },
  {
    "resource": "Power BI Service",
    "scope": "Report.Read.All"
  },
  {
    "resource": "Power BI Service",
    "scope": "Dashboard.Read.All"
  }
]

✅ Don't forget to approve the permissions from the SharePoint Admin Center. The above permissions are required. After deploying the web, these permission must be approved by global tenant admin. Please refer here for more information.

Step 5. Add models to the web part component folder

export interface PowerBiWorkspace {
  id: string;
  name: string;
  isReadOnly: boolean;
}

export interface PowerBiReport {
  id: string;
  name: string;
  embedUrl: string;
  webUrl: string;
  datasetId: string;
  accessToken: string;
}

Step 6. Add services to the web part

The PowerBiService.ts file acts as a helper service that securely connects your SPFx solution to the Power BI REST API. It provides three key methods— GetWorkspaces, GetReports, and GetReportByReportId to retrieve workspaces reports within a workspace, and a specific report by ID. Each method uses the WebPartContext to create an AadHttpClient for authenticated API calls. This approach keeps your API logic modular, reusable, and easier to manage when embedding or interacting with Power BI content.

import { WebPartContext } from "@microsoft/sp-webpart-base";
import { AadHttpClient } from "@microsoft/sp-http";
import { PowerBiWorkspace, PowerBiReport } from "../models/PowerBiModels";

export class PowerBiService {
  private static readonly powerbiApiResourceId = "https://analysis.windows.net/powerbi/api";
  private static readonly baseApiUrl = "https://api.powerbi.com/v1.0/myorg/groups/";
  private static readonly tokenKey = "adal.access.token.key" + PowerBiService.powerbiApiResourceId;

  private static async getClient(context: WebPartContext): Promise<AadHttpClient> {
    return await context.aadHttpClientFactory.getClient(this.powerbiApiResourceId);
  }

  public static async getWorkspaces(context: WebPartContext): Promise<PowerBiWorkspace[]> {
    try {
      const client = await this.getClient(context);
      const response = await client.get(this.baseApiUrl, AadHttpClient.configurations.v1, {
        headers: { Accept: "application/json" },
      });

      if (!response.ok) throw new Error(`Failed to fetch workspaces: ${response.statusText}`);

      const data = (await response.json()) as { value: PowerBiWorkspace[] };
      return data.value;
    } catch (error) {
      console.error("PowerBiService.getWorkspaces Error:", error);
      return [];
    }
  }

  public static async getReports(
    context: WebPartContext,
    workspaceId: string
  ): Promise<PowerBiReport[]> {
    try {
      const client = await this.getClient(context);
      const reportsUrl = `${this.baseApiUrl}${workspaceId}/reports/`;
      const response = await client.get(reportsUrl, AadHttpClient.configurations.v1, {
        headers: { Accept: "application/json" },
      });

      if (!response.ok) throw new Error(`Failed to fetch reports: ${response.statusText}`);

      const data = (await response.json()) as { value: PowerBiReport[] };

      return data.value.map((report) => ({
        ...report,
        accessToken: window.sessionStorage[this.tokenKey] || "",
      }));
    } catch (error) {
      console.error("PowerBiService.getReports Error:", error);
      return [];
    }
  }

  public static async getReport(
    context: WebPartContext,
    workspaceId: string,
    reportId: string
  ): Promise<PowerBiReport | null> {
    try {
      const client = await this.getClient(context);
      const reportUrl = `${this.baseApiUrl}${workspaceId}/reports/${reportId}/`;
      const response = await client.get(reportUrl, AadHttpClient.configurations.v1, {
        headers: { Accept: "application/json" },
      });

      if (!response.ok) throw new Error(`Failed to fetch report: ${response.statusText}`);

      const report = (await response.json()) as PowerBiReport;

      return {
        ...report,
        accessToken: window.sessionStorage[this.tokenKey] || "",
      };
    } catch (error) {
      console.error("PowerBiService.getReport Error:", error);
      return null;
    }
  }
}

Step 7. Time to implement it in webpart

Get Power BI Workspaces

const workspaces = await PowerBiService.getWorkspaces(context);
console.log('Workspaces:', workspaces );

Output Fields – Workspaces

Each workspace object includes:

  • id: Unique identifier of the workspace
  • name: Display the name of the workspace
  • isOnDedicatedCapacity: Indicates if it's backed by Premium capacity (boolean)

Get Reports in a Workspace

const reports = await PowerBiService.getReports(context, workspaceId);

Output Fields – Reports

Each report object includes:

  • id: Unique ID of the report
  • name: Display name of the report
  • embedUrl: URL used for embedding the report
  • webUrl: Direct link to view the report in Power BI
  • datasetId: ID of the dataset powering the report

Optional: Render in React

{reports.map(report => (
  <Card key={report.id} shadow="sm" p="md">
    <Title order={4}>{report.name}</Title>
    <Text>Report ID: {report.id}</Text>
    <a href={report.webUrl} target="_blank" rel="noopener noreferrer">View Report</a>
  </Card>
))}

Deploy and Test

  1. Run gulp bundle --ship && gulp package-solution --ship
  2. Upload .sppkg to SharePoint App Catalog
  3. Approve the API permissions
  4. Add your web part to a modern SharePoint page

Troubleshooting Tips

  • Make sure the Azure app is granted the correct Power BI permissions
  • Consent to Graph & Power BI permissions in Admin Center
  • Ensure the user has access to workspaces/reports in the Power BI Service
  • Use browser dev tools to inspect failed 403 or 401 errors

Helpful Resources

Summary

By integrating Power BI into SPFx with Microsoft Graph and REST APIs, you can:

  • ✅ Retrieve Workspaces
  • ✅ List Reports dynamically
  • ✅ Get Group Members behind Workspaces
  • ✅ Create powerful dashboards in SharePoint

Want More?

Feel free to connect or ask questions on LinkedIn. Next time, we’ll embed the actual Power BI report iframe with SSO using the powerbi-client-react package.

Happy coding!