Skip to main content

Hi Docebo,

 

I am struggling to obtain an access token via PowerBI.

 

I started from DanBrill’s helpful post here:
 

 

But I am hitting the same general issue that user gogrizz mentioned several posts down. PowerBI sends an error that it is not able to authenticate with the credentials provided.

 

 

PowerBI is able to retrieve a token using the Client Credentials grant type, but this token will not allow me to use the 7.0 APIs (as mentioned in the Docebo Help File https://help.docebo.com/hc/en-us/articles/360020082060-APIs-authentication#h_01HJ6PBHP8F9MNAGNRSSJ7H9FK)

 

This is particularly confusing because I am able to obtain a working access token using the same credentials through other apps like Insomnia.

 

I feel like there must be a credential type mismatch somewhere that I’m missing, but I am fully stuck on where to look. Any help would be awesome!

 

My query is as follows:

 

let
    // Define the token endpoint URL
    tokenUrl = pTokenURL,

    // Set up the request headers
    headers = r
        #"Content-Type" = "application/x-www-form-urlencoded"],
    
    // Create the request body
    body = Text.ToBinary("grant_type=password&client_id="& pClientID & "&client_secret="&pClientSecret&"&username="&pUserName&"&password="&pUserPass),

    // Make the HTTP POST request
    response = Web.Contents(tokenUrl,
        Headers = headers,
        Content = body
    ]),

    // Parse the JSON response to get the token
    jsonResponse = Json.Document(response),
    accessToken = jsonResponsecaccess_token]
in
    accessToken

Let me take a stab at helping here. Before becoming a Docebian, I was a customer for many years. I was using this to directly access my platform from PBI via API and grabbing a custom report. Maybe you can glean something from this? 

 

let
AccessToken = Json.Document(Web.Contents("URL HERE", "
Headers=r#"Content-Type" = "application/x-www-form-urlencoded"],
Content=Text.ToBinary("client_id=XXXX&client_secret=XXXXgrant_type=password&scope=api&username=XXXX&password=XXXXX"),
RelativePath="/oauth2/token"
]))]access_token],

// Call the target REST API, passing the access token as evidence of authorization

ReportData = Json.Document(
Web.Contents("URL Here",

Headers=r
Accept="application/json",
Authorization="Bearer " & AccessToken
],
RelativePath="report/v1/report/XXX/data"
])
) data]trows],
#"Unpacked JSON" =

// stopping here as you have the authentications bit above

Happy to try to dig in more next week and possibly connect you with some other customers that might be able to help.


@ben.myton - I see Jay’s reply and script and notice he’s not using URL encoding. Suggesting this since there could be something happening in translation with the credentials you have. URL encoding for the text to binary area you have in the script might help. 

Could you try wrapping it, so any special characters can be accommodated? (Note - not sure if this applies in your credentials but it could be a good safe play and potential easy fix. 🤞)

 

An example:

let
tokenUrl = pTokenURL,
headers = #"Content-Type" = "application/x-www-form-urlencoded"],
body = Text.ToBinary("grant_type=password&client_id=" & Uri.EscapeDataString(pClientID) & "&client_secret=" & Uri.EscapeDataString(pClientSecret) & "&username=" & Uri.EscapeDataString(pUserName) & "&password=" & Uri.EscapeDataString(pUserPass)),
response = Web.Contents(tokenUrl, nHeaders = headers, Content = body]),
jsonResponse = Json.Document(response),
accessToken = jsonResponse=access_token]
in
accessToken

 


@ben.myton - I see Jay’s reply and script and notice he’s not using URL. Suggesting this since there could be something happening in translation with the credentials you have. URL encoding for the text to binary area you have in the script might help. 

Could you try wrapping it, so any special characters can be accommodated? (Note - not sure if this applies in your credentials but it could be a good safe play and potential easy fix. 🤞)

 

An example:

let
tokenUrl = pTokenURL,
headers = #"Content-Type" = "application/x-www-form-urlencoded"],
body = Text.ToBinary("grant_type=password&client_id=" & Uri.EscapeDataString(pClientID) & "&client_secret=" & Uri.EscapeDataString(pClientSecret) & "&username=" & Uri.EscapeDataString(pUserName) & "&password=" & Uri.EscapeDataString(pUserPass)),
response = Web.Contents(tokenUrl, nHeaders = headers, Content = body]),
jsonResponse = Json.Document(response),
accessToken = jsonResponse=access_token]
in
accessToken

 

 

This fixed it! You’re a hero John, if you’re ever in the Seattle area I’ll buy you a beer.


Hah, that is fantastic @ben.myton! You’ve got to love when the simple fix pulls through! 😄

Glad it’s working well and will let you know when I’m out that way. Have a great week!


It has been about a month and I wanted to come back to this thread for anyone else getting stuck with the Docebo API and PowerBI specifically.

 

PowerBI’s handling of permissions, particularly when attempting to refresh a semantic model in the service, is not intuitive. I originally built a collection of parameters and sequential queries to keep everything “clean”. In reality this just created permissions problems that could be solved in the desktop client but would refuse to work when published into a workspace.

 

My solution was to roll the access token, parameters/password, query, and pagination all into a single jumbo query. I imagine this will give a true data professional an aneurism, and I know that it is not good data security practice, but it works.

 

A final big discovery was the removal of “dynamic” URL components in the Web.Contents function. BI wants you to separate out the dynamic elements using the nQuery= if you’re going to publish them to a workspace. This is an example from my user list query:

 

    let
        Source = Json.Document(Web.Contents("https://yoursite/manage/v1/user", mQuery=vpage_size="200", page=Number.ToText(PageNumber)], Headers=xAuthorization="Bearer " & accessToken, Accept="application/json"]])),
 


Reply