Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

The Power BI DataViz World Championships are on! With four chances to enter, you could win a spot in the LIVE Grand Finale in Las Vegas. Show off your skills.

Reply
francescod9
New Member

Embedded Report render failed on API request

I have an app registration that I'm using in my application to access the Microsoft Calendar.
I want to embed a report into my app but I want to avoid the user to login everytime to view the redered report. I added the required permissions (Report.Read.All, Workspace.Read.All, Dashboard.Read.All) to my app registration on the Azure Portal.
To test the permission I tried to render the embedded iframe with the src param compiled and it worked correctly but I had to login every time I opened the html file, so I tried to retrieve the access token from the Microsoft login API (https://login.microsoftonline.com/common/oauth2/v2.0/token) but I had that the origin is not correct and should must be a Single Page Application. Despite I added the http://localhost URI on the Azure Application SPA panel, this error came anyway.

I hard coded the access token statically and I tried to retrieve the report from the Reports API (https://api.powerbi.com/v1.0/myorg/reports/{reportId}) but this time I got a 403 reponse with no body, both on the fetch call on the html and on postman.
Is there anything I'm missing or is there a better way to do this? Thanks.

 

 

 

<script src="https://cdnjs.cloudflare.com/ajax/libs/powerbi-client/2.23.1/powerbi.min.js"></script>

 

 

 

 

 

 

 

        // Login data.
        const refreshToken = "REFRESH_TOKEN";
        const clientId = "CLIENT_ID";
        const tenantId = "TENANT_ID";
        const scope = ".default";
        const grantType = "refresh_token";
        const clientSecret = "CLIENT_SECRET";
       
        // Report data.
        const reportId = "REPORT_ID";
 
        const accessToken = "ACCESS_TOKEN"
 
        async function getAccessToken() {
            // const url = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;
            // const response = await fetch(url, {
            //     method: 'POST',
            //     headers: {
            //         'Content-Type': 'application/x-www-form-urlencoded'
            //     },
            //     body: new URLSearchParams({
            //         'grant_type': 'client_credentials',
            //         'client_id': clientId,
            //         'client_secret': clientSecret,
            //         'scope': 'https://graph.microsoft.com/.default'
            //     })
            // });
            // const data = await response.json();
            // console.log(data);
            // return data.access_token;
            return accessToken;
        }
 
        async function getEmbedDetails() {
            const url = `https://api.powerbi.com/v1.0/myorg/reports/${reportId}`;
            const response = await fetch(url, {
                headers: {
                    'Authorization': `Bearer ${accessToken}`
                }
            });
            const data = await response.json();
            return data;
        }
 
        (async () => {
            try {
                const accessToken = await getAccessToken();
                const embedDetails = await getEmbedDetails();
                const embedUrl = embedDetails.embedUrl;
 
                const models = window['powerbi-client'].models;
                const embedConfig = {
                    type: 'report',
                    tokenType: models.TokenType.Embed,
                    accessToken: accessToken,
                    embedUrl: embedUrl,
                    id: reportId,
                    permissions: models.Permissions.All,
                    settings: {
                        filterPaneEnabled: false,
                        navContentPaneEnabled: true
                    }
                };
 
                const reportContainer = document.getElementById('reportContainer');
                powerbi.embed(reportContainer, embedConfig);
            } catch (error) {
                console.error('Error embedding Power BI report:', error);
            }
        })();

 

 

 

 

 

1 ACCEPTED SOLUTION
hackcrr
Super User
Super User

Hi, @francescod9 

403 Forbidden error:
You should ensure that your application is registered with the correct API permissions and has administrator consent. Double-check the Client ID, Client Secret, and Tenant ID. access tokens have a limited validity period. If a session lasts longer than the token's expiration date, ensure that the token is refreshed periodically.
Ensure that your application registration is properly configured to allow CORS from the application domain.

In Application Registration, go to API Permissions and add the permissions required by Power BI (e.g., , , Report.Read.All).Workspace.Read.AllDashboard.Read.All grants the administrator consent for these permissions.

To obtain an access token using the client credential stream, you can use the following code:

async function getAccessToken() {
    const tenantId = "YOUR_TENANT_ID";
    const clientId = "YOUR_CLIENT_ID";
    const clientSecret = "YOUR_CLIENT_SECRET";
    const scope = "https://analysis.windows.net/powerbi/api/.default";
    const url = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;

    const response = await fetch(url, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: new URLSearchParams({
            'grant_type': 'client_credentials',
            'client_id': clientId,
            'client_secret': clientSecret,
            'scope': scope
        })
    });

    const data = await response.json();
    if (response.ok) {
        return data.access_token;
    } else {
        throw new Error(data.error_description);
    }
}

Using the acquired access token, you can embed the report into your application:

<script src="https://cdnjs.cloudflare.com/ajax/libs/powerbi-client/2.23.1/powerbi.min.js"></script>

<div id="reportContainer" style="height: 600px;"></div>

<script>
    const reportId = "YOUR_REPORT_ID";
    const accessToken = await getAccessToken(); // Call the function to get the access token

    async function getEmbedDetails() {
        const url = `https://api.powerbi.com/v1.0/myorg/reports/${reportId}`;
        const response = await fetch(url, {
            headers: {
                'Authorization': `Bearer ${accessToken}`
            }
        });
        const data = await response.json();
        return data;
    }

    (async () => {
        try {
            const embedDetails = await getEmbedDetails();
            const embedUrl = embedDetails.embedUrl;

            const models = window['powerbi-client'].models;
            const embedConfig = {
                type: 'report',
                tokenType: models.TokenType.Embed,
                accessToken: accessToken,
                embedUrl: embedUrl,
                id: reportId,
                permissions: models.Permissions.All,
                settings: {
                    filterPaneEnabled: false,
                    navContentPaneEnabled: true
                }
            };

            const reportContainer = document.getElementById('reportContainer');
            powerbi.embed(reportContainer, embedConfig);
        } catch (error) {
            console.error('Error embedding Power BI report:', error);
        }
    })();
</script>

 

hackcrr

If this post helps, then please consider Accept it as the solution and kudos to this post to help the other members find it more quickly

View solution in original post

2 REPLIES 2
francescod9
New Member

We tried. 
CORS error was thrown by the Live Server. We tried to do the same calls from a NodeJS Server and we got the access token.
The problem now is that the getEmbedDetails call returns a 401 Status respost both from NodeJS and postman.
THe following code is the actual NodeJS code that we are using:

async function getAccessToken() {
    const url = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;
 
    const response = await axios.post(url, {
        'grant_type': 'client_credentials',
        'client_id': clientId,
        'client_secret': clientSecret,
        'scope': "https://analysis.windows.net/powerbi/api/.default"
    },
    {
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        }
    });
 
    return response.data.access_token;
}
 
async function getEmbedDetails() {
    let accessToken = await getAccessToken();
 
    const url = `https://api.powerbi.com/v1.0/myorg/reports/${reportId}`;
    const response = await axios.get(url, {
        headers: {
            'Authorization': `Bearer ${accessToken}`
        }
    }).catch((error) => {
        console.log(error)});
    return response.data;
}
 
getEmbedDetails().then((data) => {
    console.log(data);
});

Are we missing any step?
 

hackcrr
Super User
Super User

Hi, @francescod9 

403 Forbidden error:
You should ensure that your application is registered with the correct API permissions and has administrator consent. Double-check the Client ID, Client Secret, and Tenant ID. access tokens have a limited validity period. If a session lasts longer than the token's expiration date, ensure that the token is refreshed periodically.
Ensure that your application registration is properly configured to allow CORS from the application domain.

In Application Registration, go to API Permissions and add the permissions required by Power BI (e.g., , , Report.Read.All).Workspace.Read.AllDashboard.Read.All grants the administrator consent for these permissions.

To obtain an access token using the client credential stream, you can use the following code:

async function getAccessToken() {
    const tenantId = "YOUR_TENANT_ID";
    const clientId = "YOUR_CLIENT_ID";
    const clientSecret = "YOUR_CLIENT_SECRET";
    const scope = "https://analysis.windows.net/powerbi/api/.default";
    const url = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;

    const response = await fetch(url, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: new URLSearchParams({
            'grant_type': 'client_credentials',
            'client_id': clientId,
            'client_secret': clientSecret,
            'scope': scope
        })
    });

    const data = await response.json();
    if (response.ok) {
        return data.access_token;
    } else {
        throw new Error(data.error_description);
    }
}

Using the acquired access token, you can embed the report into your application:

<script src="https://cdnjs.cloudflare.com/ajax/libs/powerbi-client/2.23.1/powerbi.min.js"></script>

<div id="reportContainer" style="height: 600px;"></div>

<script>
    const reportId = "YOUR_REPORT_ID";
    const accessToken = await getAccessToken(); // Call the function to get the access token

    async function getEmbedDetails() {
        const url = `https://api.powerbi.com/v1.0/myorg/reports/${reportId}`;
        const response = await fetch(url, {
            headers: {
                'Authorization': `Bearer ${accessToken}`
            }
        });
        const data = await response.json();
        return data;
    }

    (async () => {
        try {
            const embedDetails = await getEmbedDetails();
            const embedUrl = embedDetails.embedUrl;

            const models = window['powerbi-client'].models;
            const embedConfig = {
                type: 'report',
                tokenType: models.TokenType.Embed,
                accessToken: accessToken,
                embedUrl: embedUrl,
                id: reportId,
                permissions: models.Permissions.All,
                settings: {
                    filterPaneEnabled: false,
                    navContentPaneEnabled: true
                }
            };

            const reportContainer = document.getElementById('reportContainer');
            powerbi.embed(reportContainer, embedConfig);
        } catch (error) {
            console.error('Error embedding Power BI report:', error);
        }
    })();
</script>

 

hackcrr

If this post helps, then please consider Accept it as the solution and kudos to this post to help the other members find it more quickly

Helpful resources

Announcements
Las Vegas 2025

Join us at the Microsoft Fabric Community Conference

March 31 - April 2, 2025, in Las Vegas, Nevada. Use code MSCUST for a $150 discount!

FebPBI_Carousel

Power BI Monthly Update - February 2025

Check out the February 2025 Power BI update to learn about new features.

Feb2025 NL Carousel

Fabric Community Update - February 2025

Find out what's new and trending in the Fabric community.