Let’s Query Datasets via APIs!

Sayantani Mitra
CRM Analytics
Published in
7 min readJul 5, 2021

At times, users/clients want to query the datasets instead of downloading the data from tables/charts. It is very useful when someone wants to take the data that comes from these queries and use it as a plugin for other systems or automate the process for further analysis.

We are going to use part of the documentation for Salesforce APIs using Postman that was written by Amit Chaudhary. And then use this in conjunction with Tableau CRM APIs! Sounds simple? Let’s check it out.

Create a Salesforce Connected App

To do this, we need to be a Salesforce Admin. We follow these steps to create this Connected App for OAuth.

From www.varonis.com

What is OAuth?

Salesforce documentation says: “For a client application to access REST API resources, it must be authorized as a safe visitor. To implement this authorization, use a connected app and an OAuth 2.0 authorization flow.

Now that we know what OAuth means, let’s create the connected app!We will use Salesforce Lightning to create this.

We start this from Setup. Under Quick Find, search for App Manager.

App Manager

Then create a New Connected App on the top right.

New Connected App

Fill in the following:

  • Give a name to the Connected App (Chicago Taxi Data API)
  • Contact email (xyz@gmail.com)
  • Logo Image URL (Optional)
  • Icon URL (optional)
  • Add a description (optional)
  • Enable OAuth Settings == true (It is a checkbox)
  • Callback URL: https://login.salesforce.com/services/oauth2/callback (Production) and use https://test.salesforce.com/services/oauth2/callback for Sandbox
  • Selected OAuth Scopes. In our case it will be Access and Manage Wave Data (wave_api). PSA: Tableau CRM used to be called Einstein Analytics which used to be called Wave.
This is how the final Connection will look before Saving
  • Now we save this Connected App!
Connected Apps
Final Connected App

Salesforce provides us with these two very important things

  • Consumer Key: Shows under API (Enable OAuth Settings)
  • Consumer Secret: (Click to reveal)

Postman!

Now that we have successfully created a Connected App, we take a look at Postman. Install Postman (Download)!

These are two OAuth Endpoints in Salesforce other than the callback URL that we will need to input into Postman:

OAuth Endpoints in Salesforce
Authorization
: https://login.salesforce.com/services/oauth2/authorize
Token Request: https://login.salesforce.com/services/oauth2/token

Note: Use test instead of login if using sandbox.

We start with a new Workspace!

Postman Workspace
How the Workspace Looks

Create Create a Request! Then click on Settings.

Turn on Follow Authorization Header

Very Important! — DO NOT FORGET THIS

Turn on Follow Authorization Header. By default it is turned off. Without this, the queries will fail “Invalid_Session”!

Next click on Authorization and then OAuth 2.0

Authorization

Now we configure a New Token

Get New Access token

The first time we do this, Postman will ask to login to the Salesforce Org.

Login to Salesforce via Postman

Click on Proceed!

Authentication Complete

Click Use Token

Use Token

Fun Tableau CRM Query!

Click on Body. Then Raw. The default for Raw is Text which we will change to JSON!

Query Part

Tableau CRM Query is a POST call instead of GET. Thus we change the GET to POST here.

Documents for Tableau CRM APIs:

  1. This is the complete Tableau CRM API Documentation
  2. And the guide for Query is here.

For Tableau CRM API query, we use /wave/query and the query has to be in SAQL!

The best way to use SAQL without converting every dashboard widget query to SAQL is using Dashboard Inspector! It is a very nifty tool in the dashboard that shows you the compact JSON query in SAQL!

For the final Query, we will use one of the existing Tableau CRM query in Chicago Taxi data (Let’s take the query we created for Conditional Formatting)

CompareTable that we had created
Value Table that we had created

Query for Compare Table:

q = load "0Fb6g000000LwXHCA0/0Fc6g000004X0rqCAC";result = group q by ('Pickup_Community_Area__c', 'taxi.Name', 'Trip_Name__c', 'aff.Name');result = foreach result generate q.'Pickup_Community_Area__c' as 'Pickup_Community_Area__c', q.'taxi.Name' as 'taxi.Name', q.'Trip_Name__c' as 'Trip_Name__c', q.'aff.Name' as 'aff.Name', max(q.'Trip_Total__c') as 'Trip_Total';result = order result by ('Pickup_Community_Area__c' asc, 'taxi.Name' asc, 'Trip_Name__c' asc, 'aff.Name' asc);result = limit result 2000;

The first part of load (0Fb6g000000LwXHCA0) is the dataset id. 0Fc6g000004X0rqCAC is the version id of the dataset. This is also very important! Every time we update a dataset via dataflow/recipe, a new version of the dataset is created. The older version id of the dataset will still work. But… anything new like a field, formula updates will not update in the query if the old one is used.

Ways to find the version id for the dataset:

  1. From the Dashboard Inspector in the dashboard itself.
  2. From Workbench!
  • Login to Workbench.
  • Click on Utilities -> REST Explorer
  • It comes up with part of the API URL: /services/data/v51.0/
  • Add wave at the end
Workbench Response
  • Click on the one that says datasets and then on the folder thing that says datasets.
Datasets
  • Now click on the dataset we need the current version id for. In this case, taxi_trips
Version Id

3. Using Postman!

Current Version Id in Postman

Another important thing for JSON query in APIs, there cannot be any line breaks in the query! Thus, we remove all line breaks. Thus:

q = load "0Fb6g000000LwXHCA0/0Fc6g000004X0rqCAC";result = group q by ('Pickup_Community_Area__c', 'taxi.Name', 'Trip_Name__c', 'aff.Name');result = foreach result generate q.'Pickup_Community_Area__c' as 'Pickup_Community_Area__c', q.'taxi.Name' as 'taxi.Name', q.'Trip_Name__c' as 'Trip_Name__c', q.'aff.Name' as 'aff.Name', max(q.'Trip_Total__c') as 'Trip_Total';result = order result by ('Pickup_Community_Area__c' asc, 'taxi.Name' asc, 'Trip_Name__c' asc, 'aff.Name' asc);result = limit result 2000;

IMPORTANT: If there is a line break, we get a JSON_PARSER_ERROR

The type of JSON we use is called query

Since it is JSON, it starts and ends with curly brackets!

We also need to escape the double quotes within the query itself!

Thus, the final version of the query that goes into the body of Postman looks like:

{
"query": "q = load \"0Fb6g000000LwXHCA0/0Fc6g000004X0rqCAC\";result = group q by ('Pickup_Community_Area__c', 'taxi.Name', 'Trip_Name__c', 'aff.Name');result = foreach result generate q.'Pickup_Community_Area__c' as 'Pickup_Community_Area__c', q.'taxi.Name' as 'taxi.Name', q.'Trip_Name__c' as 'Trip_Name__c', q.'aff.Name' as 'aff.Name', max(q.'Trip_Total__c') as 'Trip_Total';result = order result by ('Pickup_Community_Area__c' asc, 'taxi.Name' asc, 'Trip_Name__c' asc, 'aff.Name' asc);result = limit result 2000;"
}
POST Query

The POST needs an URL! The URL we use has the following format:

  1. If you have a custom salesforce url:

https://<customname>.my.salesforce.com/services/data/v51.0/wave/query/

2. Otherwise, we use the instance id (the instance used here is na174)

https://na174.salesforce.com/services/data/v51.0/wave/query/

Now all we do is click Send!

The JSON body final response in Raw looks like

Raw JSON Response

When we use Pretty instead of Raw, this is how it looks

Pretty JSON with field names and type of field
Records

And we are done!

We just created a whole new Connected App followed by Postman Installation and Queried a dataset from Tableau CRM to get the records!!

--

--