Microsoft Power BI Integration (self-serve)

Clients can now integrate their Yext analytics with Power BI :tada:

Microsoft Power BI is a business intelligence and analytics tool that brands use to create dashboards, reports, and visualizations. With our new step-by-step guide, we help our clients to easily pull in data from Yext to Power BI. This option is self-serve and must be set up by the client within their own Power BI Desktop experience but with sample code snippets, we have made this as low lift as possible!

This guide details how to use Yext as a Web API source in Power BI to allow clients to pull in any analytics and reviews data they want. Clients can customize their metrics, dimensions, and filters to pull in data specific to their solutions.

In this approach, clients are limited in how they can refresh their data which must be done manually in Power BI, read how to here. Also, clients are limited to static date ranges in this approach, it cannot be configured to “last 30 days” rather a date range must be set to April 1, 2022 through April 20, 2022.

We’d love to hear your questions and feedback! Comment below!
Additionally, we will be developing an out-of-the-box connector for Power BI in the coming months.

3 Likes

Hello @Adrienne_Williams

Thank you for such a detailed guide on connecting the two tools.

While creating an open power BI query, i’m running into an issue. Specifically when it comes to using filters. I’m trying to use FOLDER_IDS as a filter, but every time i’m getting an error from the Yext API. PFB my code that i’m using.

let
url = "https://api.yext.com/v2/accounts/me/analytics/reports?&v=20220310&api_key=“API Key”,
header = [#“Content-Type”=“application/json”,#“Accept”=“application/json”],
body = Text.FromBinary(Json.FromValue([metrics = {“GOOGLE_CUSTOMER_ACTIONS”}, dimensions = {“FOLDER_NAMES”, “MONTHS”, “CUSTOMER_ACTION_TYPE”}, filters = [FOLDER_IDS = [343868]]])),
Source = Json.Document(Web.Contents(url,[Headers = header,Content=Text.ToBinary(body)]))
in
Source

Also the code runs just fine, without the filter condition.

Hi Naveen!
Welcome to the Hitchhikers Community and great question!

I think the issue you are running into is the filter property is actually folderIds instead of FOLDER_IDS. FOLDER_IDS is used as a dimension but varies slightly when you are looking to filter an API call. You can see a full list of available filters in our Analytics Reports API documentation for reference!

Your filter should be …
filters = {folderIds = [343868]} since filters is an object (just like metrics and dimensions) and the folderId property is an array for your list of filters.

Hope this helps :slightly_smiling_face:

Hello @Adrienne_Williams,

Thank you for kind reply. Indeed I got confused between folderIds & FOLDER_IDS. However now i’m getting this error on Power BI

“Expression.Error: The import folderIds matches no exports. Did you miss a module reference?”

Code used:

let
url = “https://api.yext.com/v2/accounts/me/analytics/reports?&v=20220310&api_key=*****************”,
header = [#“Content-Type”=“application/json”,#“Accept”=“application/json”],
body = Text.FromBinary(Json.FromValue([metrics = {“GOOGLE_CUSTOMER_ACTIONS”}, dimensions = {“FOLDER_NAMES”, “MONTHS”, “CUSTOMER_ACTION_TYPE”}, filters = {folderIds = [343868]}])),
Source = Json.Document(Web.Contents(url,[Headers = header,Content=Text.ToBinary(body)]))
in
Source

Hi Naveen,
This error seems to point to an expression error which just means some small punctuation is missing! This is syntax specific to Microsoft and Power BI which can be slightly confusing.

Your current query contains this

Since the folderIds property is an array and contains multiple values, you’ll have to add square brackets around the filter properties and curly brackets around the IDs. You will actually want to change it to this:

filters = [folderIds = {343868, ID2, ID3}]]))

If you run into other syntax issues specific to Microsoft feel free to post another question here or check out the Power BI Community.

Best,
Adrienne

1 Like

Hello @Adrienne_Williams,

Thank you so much for your help, I was finally able to run the query successfully. The last suggestion worked. Much appreciated. :smile:

1 Like

@Adrienne_Williams,

Below is my API query for a working API query I created.

url = “https://api.yext.com/v2/accounts/me/analytics/reports?v=20220511&api_key=[my API Key]”,
header = [#“Content-Type”=“application/json”,#“Accept”=“application/json”],
body = Text.FromBinary(Json.FromValue([metrics = {“NEW_REVIEWS”}, dimensions = {“DAYS”, “PARTNERS”, “LOCATION_IDS”, “RATINGS”},filters = [startDate = #date(2021,01,03)]])),
Source = Json.Document(Web.Contents(url,[Headers = header,Content=Text.ToBinary(body)]))

What I am looking for help on now is with is a query that gets information related to Review Invitations, but I can’t find the relevant Metrics and Dimensions to request this data. There is no reference to this type of data on in the Query Samples Guide, so maybe it’s not even possible at this time, but I did stumble upon this page which gave me some hope: Review Invitations | Hitchhikers (yext.com).

The information I am be looking to obtain regarding Review Invitations would be Date, Location ID and Number of Review Requests Sent, so that I would ideally end up with a table that shows the number of reviews requests sent out by store by date.
For example a single row would be: [DAYS: 01/01/2022, Location_IDs: 200, Reviews Sent: 235]

Thanks,

Nick

Hi @Nick_Pyle !
Welcome to the Hitchhikers Community! This is a great additional use case for pulling data into Power BI :bar_chart:

This is possible but will take some tweaks.

First, add the Reviews Invitations endpoint permission to your existing Power BI app - Step 1 in the guide.

This query is going to be quite different from the other Yext analytics endpoints. This Yext Reviews endpoint will return all of the metrics available with the generic call, you dont have to sepcify every metric and dimension you want like you do for the other queries.

A few caveats:

  1. The date will be returned as an epoch timestamp, I’m assuming you can transform this in PBI.

  2. In order to get a sum of requests sent by location ID you will have to sum this in PBI as the API returns them all as individual objects. If you wanted, you could filter to 1 location ID at a time but this would just be more work creating queries up front.

If you want to filter you can do so with any of the options on this page. Just include them as query parameters by adding “&[filtername]=[value]” to the end of the URL after your API key. For example, https://api.yext.com/v2/accounts/me/analytics/reports?v=20220511&api_key=*****&folderIds=12345,56789

  1. In order to get the full set of data you will have to paginate through the data. To do this I recommend setting the limit parameter to 100 (in the URL as you will see below).

.
.
.

Here’s a quick summary of what you’ll be doing:
In order to pull in all of your invitation data you will need 2 queries. For a full explanation and step-by-step you can read more, here, but I’ve provided everything you need below!

  • Query 1) This is a function that hits the /reviewinvites endpoint. Be sure to rename this Query to be getPages as it is referenced in Query 2.

    Note: the API key has been removed from the URL here and is authenticated as “Web API” in Step 3 - Edit Credentials.

  • Query 2) Returns the table full of data! Due to a large volume of data, this may take a few minutes to load.

.
.
.
Copy & Paste these queries into your Blank Query editor. Feel free to post any follow-up questions as this post is fairly long!

Best,
Adrienne

Query 1

let
    Source = (offset as text) => let
       url = "https://api.yext.com/v2/accounts/me/reviewinvites?v=20220901&limit=100&offset=" & offset,
    
       Source = Json.Document(Web.Contents(url, [ApiKeyName="api_key"])),
        response = Source[response],
        invitations = response[invitations],
        #"Converted to Table" = Table.FromList(invitations, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
        #"Expanded Column1" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", {"firstName", "lastName", "contact", "templateId", "status", "entity", "type", "requested", "sent", "invitationUid", "feedbackUrl"}, {"Column1.firstName", "Column1.lastName", "Column1.contact", "Column1.templateId", "Column1.status", "Column1.entity", "Column1.type", "Column1.requested", "Column1.sent", "Column1.invitationUid", "Column1.feedbackUrl"})
    
    
    in
    #"Expanded Column1"
in
    Source

Query 2

let
   entitiesPerPage = 100,
   Limit = "&limit=" & Text.From(entitiesPerPage),
   url = "https://api.yext.com/v2/accounts/me/reviewinvites?v=20220901" & Limit,
   Source = Json.Document(Web.Contents(url, [ApiKeyName="api_key"])),
    response = Source[response],
   countPages = Number.RoundUp(Value.Divide(response[countEmail], 100)),
   textPages = Text.From(countPages),
    List = List.Numbers(0, countPages, 100),
    #"Converted to Table" = Table.FromList(List, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    #"Changed Type" = Table.TransformColumnTypes(#"Converted to Table",{{"Column1", type text}}),
    #"Invoked Custom Function" = Table.AddColumn(#"Changed Type", "getPages", each getPages([Column1])),
    #"Expanded getPages" = Table.ExpandTableColumn(#"Invoked Custom Function", "getPages", {"Column1.firstName", "Column1.lastName", "Column1.contact", "Column1.templateId", "Column1.status", "Column1.entity", "Column1.type", "Column1.requested", "Column1.sent", "Column1.invitationUid", "Column1.feedbackUrl"}, {"getPages.Column1.firstName", "getPages.Column1.lastName", "getPages.Column1.contact", "getPages.Column1.templateId", "getPages.Column1.status", "getPages.Column1.entity", "getPages.Column1.type", "getPages.Column1.requested", "getPages.Column1.sent", "getPages.Column1.invitationUid", "getPages.Column1.feedbackUrl"})
in
    #"Expanded getPages"

@Adrienne_Williams, thank you for the help. Although I believe that I have implemented most of what you have suggested properly, I am hung up on an API Credential error for Query 2. Am I to use a Web API Authentication for both Query 1 and Query 2? And if so, is there anywhere in the query where I need to enter my API key or do I just enter the API Key in the Authentication Configuration pop-up widow where it askes me for the “Key” and “Select which level to apply these settings to”? I have tried many configurations and none have yet to work.

Thanks,
Nick

Yes, @Nick_Pyle you should authenticate as a Web API for both queries but you should only need to do this once as it is the same endpoint.

The key you need to input in the pop-up is your Yext API key, you wont need to include this anywhere in the query. Also, you will want to click the level of settings that just should end at /reviewinvites.

Hope this works for you :crossed_fingers:t4:

Adrienne