Skip to main content
Skip table of contents

PowerBI Integration with Custom Query

Summary

This document summarizes the simple steps to follow for getting Timepiece data into PowerBI, using the PowerBI Desktop App.

This document utilizes the Public REST API provided by Timepiece.

Configuration

Create a new Query

Open PowerBI Desktop App

Click "Home >> Get Data >> Blank Query"


Configure the Query using the Advanced Editor

When the "Power Query Editor" window opens, Select "Advanced Editor".

When the "Advanced Editor" window will opens, enter the sample query text below.

Sample query to get Timepiece data...
CODE
let
    // Define the base URL and relative path
    BaseUrl = "https://tis.obss.io",
    RelativePath = "/rest/list2",
     
    // Change this with your Timepiece JWT
    TP_JWT = "<tis_jwt>",
    PageSize = 1000,
 
    // Define a function to retrieve a single page of data
    GetPage = (nextPageToken as nullable text) =>
        let
            // Base query parameters
            query = [
                filterType = "customJQL",
                customJQL = "project not in (HTP, TTP) or key < TTP-101",
                columnsBy = "statusDuration",
                fields = "status, assignee",
                statuses = "",
                calendar = "normalHours",
                viewFormat = "days",
                outputType = "jsonSimplified", 
                emptyValueToken = "nochar",
                pageSize = Text.From(PageSize)
            ],

            // Conditionally add nextPageToken to the query for subsequent requests
            finalQuery = if nextPageToken <> null then Record.Combine({query, [nextPageToken = nextPageToken]}) else query,
            
            // Fetch the JSON data from the API
            Source = Web.Contents(BaseUrl & RelativePath, [
                Query = finalQuery,
                Headers = [Authorization = "TISJWT " & TP_JWT]
            ]),

            // Parse the JSON content
            JsonData = Json.Document(Source)
        in
            JsonData,

    // Generate a list containing the JSON response for each page
    AllPages = List.Generate(
        () => GetPage(null), // Initial call: No token is sent for the first page.
        each _ <> null, // Condition: Continue as long as the previous step returned a valid response.
        each if [nextPageToken]? <> null then GetPage([nextPageToken]) else null // Next step: Use the token from the previous response to get the next page. Stop if no token is found.
    ),
    
    // Extract the 'results' list from each page's JSON response.
    ResultsLists = List.Transform(AllPages, each if Record.HasFields(_, "results") then _[results] else {}),

    // Combine all the individual 'results' lists into one large list of records
    AllRecords = List.Combine(ResultsLists),

    // 1. Get a distinct list of all possible column names from all records
    AllColumnHeaders = List.Distinct(List.Combine(List.Transform(AllRecords, each Record.FieldNames(_)))),
    
    // 2. Create a default record that has all possible columns set to "-"
    DefaultRecord = Record.FromList(List.Repeat({"-"}, List.Count(AllColumnHeaders)), AllColumnHeaders),

    // 3. Ensure every record has all columns by merging it with the default record.
    // This adds any missing fields (like "Open") with "-".
    NormalizedRecords = List.Transform(AllRecords, each Record.Combine({DefaultRecord, _})),

    // Convert the normalized (and now structurally identical) records into a single table
    AllData = Table.FromRecords(NormalizedRecords)
in
    AllData

image-20250821-131018.png

  • Adjust the values of the data query parameters according to your needs.

    • Some common parameters are given in the query text below. Change their values according to your use case.

      • You are recommended to start with a JQL query that returns a small number of issues (preferably no more than a few hundred issues). That will keep the query run times short and speed up your initial configuration. Change the query to a large one (if needed) when all the configuration described in this document is complete.

    • Replace "<tis_jwt>" in the query with your Timepiece JWT token.

    • Don't change the "BaseUrl". It should always point to "https://tis.obss.io".

      • This is the Timepiece service URL.

    • Don't change the "RelativePath".

      • This script uses the "/rest/list2" endpoint to get data in pages of 100 issues.

    • Don't change the "PageSize".

      • It should remain 1000, as this is the largest allowed page size.

    • See the "Parameters" section in this document about the REST API parameters you can use and their possible values.


Run & Save the Query

Click the "Done" button on the Query windows when your modifications are complete.

  • PowerBI will start pulling data automatically.

  • Power BI Desktop app shows some visual cues to indicate that a query is running. Unfortunately, it doesn't provide a way to see progress or remaining time estimation.

  • The query might take a long time to complete, based on the number of issues in your query.

    • The performance of the query depends on the power of your computer, your network connection, and the current load on Timepiece Service and your Jira Cloud.

    • In our tests, our wait times were roughly 5 seconds for every 1000 issues.

When the query is completed, you should be back to the "Power Query Editor" window.

  • You can set a name for your query using the "Properties" panel.

  • Click "Close & Apply >> Close & Apply" when you're done.

  • PowerBI will most likely start running the data query again.


See the Results

When the query is completed, you should be back to the main "Power BI Desktop" app window.

You can use the "Table View" tab to see your query results.


Edit and Refresh the Query

You can use the "Data" panel and right-click on the query name to run the query again or edit the query using the "Power Query Editor".


Save your Project

You have configured your data query and pulled data, you can use the "File >> Save" menu to save your Power BI project.

Now you can do some PowerBI magic to analyze your data.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.