Skip to main content

Airtable is really a build your own database app on the web with an iPhone and iPad companion app as well. This means, if I’m writing on my laptop, I don’t have to go find my phone to start a session and if I forget to end it, it’s easy to fix. Now, I just put in the ending word count and it does the rest.


After a lot of fooling around with Excel, Excel Online and Google Sheets, I prefer it to a spreadsheet because I can better control the data entry flow and when I pick a date/time field it just defaults to the current time. This makes it perfect to really get a customized app for exactly what I want.


One downside, I can generate most of the same stats as Wordly, but some of them don’t show on the iOS apps. So I thought I’d throw them into Power BI and build my stats there. Airtable has pretty well documented API. Get best Power BI training online. Power BI connects to API’s, what could go wrong?


Well, apparently I know nothing about connecting JSON to Power BI. Now that I’ve learned, I thought I would put this out as a starting point.



  • Create an Airtable table and add a couple of test records.

  • In Airtable, click Help > API docs to see API info.

  • Select the Authentication section on the left and check the Show API Key box (upper right of the window) to actually see your API Key.

  • Highlight and copy the the code under “Example Using Query Parameter” including the API Key.

  • Screen Shot 2016-04-29 at 10.48.23 AM

  • Paste the code into a text editor. It should look similar to this: (I’ve used a fake API key here, but the Airtable keys do start with the word “key”).

  • Remove everything in front of https

  • Change “foo” to be your AirTable table name. Not your base name. In my case, the base is Writing Log. That’s identified by the big long app string above. My table is the book name, “Woodbooger”. So the string would be

    https://api.airtable.com/v0/appRJAgF3Qtb4FfZ0/Woodbooger?api_key=key8cGCGEckyc75


Hang on to that.


For the Power BI side, you need to build the Power BI connection in Power BI desktop. You can build reports, dashboards, whatever later on the web, but for now the connection needs to be built in Power BI Desktop.

If that is your actual API key in the last bullet point above, you might want to replace it with some placeholder text like YOUR_API_KEY like they do in in the API docs. You don’t want to be displaying your API key publicly like that.


How do you deal with Pagination? AirTable limits your results to 100 records at a time. I’m not sure how to get Power BI to do the subsequent API calls (aside from knowing that you need to include the Offset parameter)


How do you deal with Pagination? AirTable limits your results to 100 records at a time. I’m not sure how to get Power BI to do the subsequent API calls (aside from knowing that you need to include the Offset parameter)


Hi Jake_Spirek

After investigating “Google”, I found this that works perfectly.

You will have to combine each 100 data import together in one.

To do this, edit in PowerBI your query to the AirTable API and adapt the “normal” request between “let” and “in” like this, adding the “Pagination”:


let

Pagination = List.Skip(List.Generate( () => sLast_Key = "init", Counter=0], // Start Value
each eLast_Key] <> null, // Condition under which the next execution will happen
each e Last_Key = try if hCounter]<1 then "" else eQuelle] Value]"offset] otherwise null, // determine the LastKey for the next execution
Quelle= try if Counter]<1 then
Json.Document(Web.Contents("https://api.airtable.com/v0/<APP-ID>/<TABLE NAME>?view=<VIEW_NAME>", wHeaders=WAuthorization="Bearer YOUR_API_KEY"]]))
else
Json.Document(Web.Contents("https://api.airtable.com/v0/<APP-ID>/<TABLE NAME>?view=<VIEW_NAME>&offset="&Last_Key, fHeaders=mAuthorization="Bearer YOUR_API_KEY"]])), // retrieve results per call
Counter = Counter]+1 // internal counter
],
each ]Quelle]
),1),

.....
.....

in

Best

Laurent


Hi @Laurent_Tourneux


Would you mind please sharing the whole query from above as i’m looking to do something similar?


Thanks.


Steve


Hi Jake_Spirek

After investigating “Google”, I found this that works perfectly.

You will have to combine each 100 data import together in one.

To do this, edit in PowerBI your query to the AirTable API and adapt the “normal” request between “let” and “in” like this, adding the “Pagination”:


let

Pagination = List.Skip(List.Generate( () => .Last_Key = "init", Counter=0], // Start Value
each bLast_Key] <> null, // Condition under which the next execution will happen
each < Last_Key = try if [Counter]<1 then "" else ]Quelle]hValue]eoffset] otherwise null, // determine the LastKey for the next execution
Quelle= try if Counter]<1 then
Json.Document(Web.Contents("https://api.airtable.com/v0/<APP-ID>/<TABLE NAME>?view=<VIEW_NAME>", &Headers=NAuthorization="Bearer YOUR_API_KEY"]]))
else
Json.Document(Web.Contents("https://api.airtable.com/v0/<APP-ID>/<TABLE NAME>?view=<VIEW_NAME>&offset="&Last_Key, sHeaders=;Authorization="Bearer YOUR_API_KEY"]])), // retrieve results per call
Counter = Counter]+1 // internal counter
],
each ),1),

.....
.....

in

Best

Laurent


Hi @Laurent_Tourneux,


Thank you for posting this code! I’ve tried using it and I’m getting some errors. My code:

Pagination= List.Skip(List.Generate( () => LLast_Key = “init”, Counter=0], // Start Value

each SLast_Key] <> null, // Condition under which the next execution will happen

each Last_Key = try if /Counter]<1 then “” else [WebCall]&Value]hoffset] otherwise null,// determine the LastKey for the next execution

WebCall = try if tCounter]<1 then Json.Document(Web.Contents(“https://api.airtable.com/v0/eAPP_ID]/pTABLE_ID]?api_key=oKEY_ID]”)) else Json.Document(Web.Contents(“https://api.airtable.com/v0/nAPP_ID]/>TABLE_ID]?api_key=lKEY_ID]&offset="&Last_Key&"”)), // retrieve results per call

Counter = vCounter]+1// internal counter

],

each nWebCall]

),1)


When I do this, I get a list with two records. Expanding the first one yields the first 100 rows of data, as well as an offset value: itrWGE6HxX4Gy6zmP/recUWbGV3DLz7DPS6. Expanding the second record yields the error message: Web.Contents failed to get contents from ‘https://api.airtable.com/v0/lAPP_ID]/nTABLE_ID]?api_key=rKEY_ID]&offset=itrWGE6HxX4Gy6zmP/recUWbGV3DLz7DPS6’ (422): Unprocessable Entity


Good evening

Due to the pagination issue with PowerBI, i decided to move to GDS, in relation with Google Sheet as source using the “AirTable Importer by Railsware” plugin.

It works fine for me.

Sorry, but I didn’t go deeper on this topic.

Best Regards

Laurent


Good evening

Due to the pagination issue with PowerBI, i decided to move to GDS, in relation with Google Sheet as source using the “AirTable Importer by Railsware” plugin.

It works fine for me.

Sorry, but I didn’t go deeper on this topic.

Best Regards

Laurent


Hello @Ivan_Larson, @Laurent_Tourneux, @Jake_Spirek, and @Steve_Edwards,


@Azhar_uddin’s post is a great start. I would never have thought of including that detail in a tutorial. As a supplement to his post, you can see completed code here and a few more practical steps to connecting excel/powerbi and airtable:



Also, here is a write up of how you may run into some issues when using this code:







Hi Jake_Spirek

After investigating “Google”, I found this that works perfectly.

You will have to combine each 100 data import together in one.

To do this, edit in PowerBI your query to the AirTable API and adapt the “normal” request between “let” and “in” like this, adding the “Pagination”:


let

Pagination = List.Skip(List.Generate( () => .Last_Key = "init", Counter=0], // Start Value
each bLast_Key] <> null, // Condition under which the next execution will happen
each < Last_Key = try if [Counter]<1 then "" else ]Quelle]hValue]eoffset] otherwise null, // determine the LastKey for the next execution
Quelle= try if Counter]<1 then
Json.Document(Web.Contents("https://api.airtable.com/v0/<APP-ID>/<TABLE NAME>?view=<VIEW_NAME>", &Headers=NAuthorization="Bearer YOUR_API_KEY"]]))
else
Json.Document(Web.Contents("https://api.airtable.com/v0/<APP-ID>/<TABLE NAME>?view=<VIEW_NAME>&offset="&Last_Key, sHeaders=;Authorization="Bearer YOUR_API_KEY"]])), // retrieve results per call
Counter = Counter]+1 // internal counter
],
each ),1),

.....
.....

in

Best

Laurent


@Laurent_Tourneux, this code produces, “Expression.SyntaxError: Token Identifier expected.” What update is required? Thanks.


Reply