Power BI is turning 10, and we’re marking the occasion with a special community challenge. Use your creativity to tell a story, uncover trends, or highlight something unexpected.
Get startedJoin us for an expert-led overview of the tools and concepts you'll need to become a Certified Power BI Data Analyst and pass exam PL-300. Register now.
I am trying to embed a Power BI report into my Laravel project using the Power BI REST API. The report is loading successfully. Although to load that report currently I am using an Access Token which I got in the 'Learn Microsoft- REST API Try It' console.
Using the code below, my report loads successfully if I use the access token which I got in the 'Learn Microsoft- REST API Try It'.
I am also generating an Access Token using Postman using these headers, parameters and URL with the help of this documentation. (First Case: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow)
URL: https://login.microsoftonline.com/{$tenantID}/oauth2/v2.0/token
Request headers:- Content-Type : application/x-www-form-urlencoded
Request Body:
In x-www-form-urlencoded,
client_id : 'clientID',
scope : 'https://analysis.windows.net/powerbi/api/.default',
client_secret : 'client_secret',
grant_type : 'client_credentials'
But, if I use the Access Token generated using the above Postman request to load Powerbi report in my project then I get this error.
Here's the code I am using to load powerbi report (using Powerbi Rest Api) using the Access Token generated by 'Learn Microsoft- REST API Try It' console.
<html>
<head>
<script src="https://microsoft.github.io/PowerBI-JavaScript/demo/node_modules/jquery/dist/jquery.js"></script>
<script src="https://microsoft.github.io/PowerBI-JavaScript/demo/node_modules/powerbi-client/dist/powerbi.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/powerbi-client/2.22.4/powerbi.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js" integrity="sha512-3gJwYpMe3QewGELv8k/BX9vcqhryRdzRMxVfq6ngyWXwo03GFEzjsUm8Q7RZcHPHksttq7/GFoxjCVUjkjvPdw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/powerbi-client/2.22.4/powerbi.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js" integrity="sha512-3gJwYpMe3QewGELv8k/BX9vcqhryRdzRMxVfq6ngyWXwo03GFEzjsUm8Q7RZcHPHksttq7/GFoxjCVUjkjvPdw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.jsdelivr.net/npm/powerbi-models@1.12.6/dist/models.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/powerbi-models@1.12.6/dist/models.min.js"></script>
</head>
<body>
<div id="embedContainer"></div>
<script>
let loadedResolve, reportLoaded = new Promise((res, rej) => { loadedResolve = res; });
let renderedResolve, reportRendered = new Promise((res, rej) => { renderedResolve = res; });
let report;
const models = window['powerbi-client'].models;
function embedPowerBIReport() {
const accessToken = 'access token';
const embedUrl = 'https://app.powerbi.com/reportEmbed?reportId=7rfxxxxxxxxxxxxxxxxxxxxx';
const embedReportId = '7rfxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
const tokenType = '0';
const permissions = models.Permissions.All;
const config = {
type: 'report',
tokenType: tokenType == '0' ? models.TokenType.Aad : models.TokenType.Embed,
accessToken: accessToken,
embedUrl: embedUrl,
id: embedReportId,
permissions: permissions,
settings: {
panes: {
filters: {
visible: true
},
pageNavigation: {
visible: true
}
}
}
};
const embedContainer = $('#embedContainer')[0];
report = powerbi.embed(embedContainer, config);
report.off("loaded");
report.on("loaded", function () {
loadedResolve();
report.off("loaded");
});
report.off("error");
report.on("error", function (event) {
console.log(event.detail);
});
report.off("rendered");
report.on("rendered", function () {
renderedResolve();
report.off("rendered");
});
}
embedPowerBIReport();
async function applyFilter() {
const filter = {
$schema: "http://powerbi.com/product/schema#basic",
target: {
table: "WBL-AllReviews-Export Less Records",
column: "Partner Name"
},
operator: "In",
values: ["WBL Central", "WBL Western"]
};
await reportLoaded;
await reportRendered;
await report.updateFilters(models.FiltersOperations.Add, [filter]);
}
try {
setTimeout(applyFilter);
console.log("Report filter was added.");
}
catch (errors) {
console.log(errors);
}
</script>
</body>
</html>
Solved! Go to Solution.
As I mentioned you need to use an App registration to surpass the Outh2
Please watch this video
https://m.youtube.com/watch?v=2RZkc_qrV1g&t=610s
You need to be aware using this method will only get you the last 30 days of data.
Regards
Amine Jerbi
If I answered your question, please mark this thread as accepted
and you can follow me on
My Website, LinkedIn and Facebook
use jwt.io to validate that your token has the required scope.
Hi @lbendlin , As you said I decoded both tokens, and I found different payload data for both tokens. The one which I got from 'Microsoft-Learn Try It Rest Api' have scopes and the other one which I got from the postman request have 'roles' instead of 'scopes'. I am posting a difference here.
Please advice me what should I do to obtain the access token that I received from 'Microsoft REST API Try It Console'
Payload data in token I got from 'Microsoft Try It' it
{
"rh": "0asdfaxxxxxxxxxxxxxxxxxxxxx",
"scp": "App.Read.All Capacity.Read.All Capacity.ReadWrite.All Content.Create Dashboard.Read.All Dashboard.ReadWrite.All Dataflow.Read.All Dataflow.ReadWrite.All Dataset.Read.All Dataset.ReadWrite.All Gateway.Read.All Gateway.ReadWrite.All Pipeline.Deploy Pipeline.Read.All Pipeline.ReadWrite.All Report.Read.All Report.ReadWrite.All StorageAccount.Read.All StorageAccount.ReadWrite.All Tenant.Read.All Tenant.ReadWrite.All UserState.ReadWrite.All Workspace.Read.All Workspace.ReadWrite.All",
"signin_state": [
"kmsi"
],
"sub": "xxxxxxxxxxxxx",
"tid": "TenantID",
"unique_name": "MyEmailId",
"upn": "MyEmailId",
"uti": "",
"ver": "1.0",
"wids": [
"xxxxxxxxxxxxxxxx"
]
}
Payload Data I got from Access Token which I got by Postman request
{
"rh": "0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"roles": [
"Tenant.ReadWrite.All",
"Tenant.Read.All"
],
"sub": "xxxxxxxxxxxxxxxxxxxxxxxx",
"tid": "Tenant Id",
"uti": "xxxxxxxxxxxxxxxxxxx",
"ver": "1.0"
}
To embed reports you need to use App Registration. Tokens only last for 60 mins.
https://learn.microsoft.com/en-us/power-bi/developer/embedded/register-app?tabs=customers
Regards
Amine Jerbi
If I answered your question, please mark this thread as accepted
and you can follow me on
My Website, LinkedIn and Facebook
Hi @aj1973 @lbendlin , Thank you for your response. I have added the necessary scopes and now the solution is working. However, I want to embed this report for customers. And every time I have to log in with my Microsoft member account to generate the access token. If embedded for customers is there any way I can get embed token / access token without any login.
Current functionality: I am visiting this URL
programmatically
public function getCode(Request $request){
$code = $request->code;
$client = new Client();
$response = $client->request('POST', 'https://login.microsoftonline.com/TENANT_ID/oauth2/v2.0/token', [
'headers' => [
'Content-Type' => 'application/x-www-form-urlencoded',
],
'form_params' => [
'client_id' => 'CLIENT_ID,
'redirect_uri' => 'https://MY-APP-URL/reports/powerbi',
'grant_type' => 'authorization_code',
'code' => $code,
'client_secret' => 'CLIENT-SECRET',
],
]);
$responseBody = $response->getBody()->getContents();
$responseData = json_decode($responseBody, true);
$accessToken = $responseData['access_token'];
return view('reports.powerbi')->with('data', $accessToken);
}
As I mentioned you need to use an App registration to surpass the Outh2
Please watch this video
https://m.youtube.com/watch?v=2RZkc_qrV1g&t=610s
You need to be aware using this method will only get you the last 30 days of data.
Regards
Amine Jerbi
If I answered your question, please mark this thread as accepted
and you can follow me on
My Website, LinkedIn and Facebook
You need scopes, not roles. You probably need to register an app and then use the app credentials in Postman.
This is your chance to engage directly with the engineering team behind Fabric and Power BI. Share your experiences and shape the future.
Check out the June 2025 Power BI update to learn about new features.
User | Count |
---|---|
56 | |
27 | |
26 | |
22 | |
20 |
User | Count |
---|---|
58 | |
43 | |
24 | |
23 | |
19 |