---
title: "PowerBI Desktop Integration"
slug: "powerbi-desktop-integration"
updated: 2026-02-16T11:40:25Z
published: 2026-02-16T11:40:25Z
canonical: "support.tulip.co/powerbi-desktop-integration"
---

> ## Documentation Index
> Fetch the complete documentation index at: https://support.tulip.co/llms.txt
> Use this file to discover all available pages before exploring further.

# PowerBI Desktop Integration

*Integrate tulip tables with PowerBI Desktop for streamlined analytics*

[Link to library page](https://library.tulip.co/videos/powerbi-desktop-integration)

## Overview

This attached .pbix template showcases how to easily query tulip tables to PowerBI [Download PowerBI Template](https://tulip.widen.net/content/efdxolfssc/original/tulip_library_powerquery_template.zip?u=a1yhpj&amp;download=true)

Tulip Analytics will work much better analyses of only tulip data as well as streaming data. For analyses that require a complex data model, longer refresh frequencies, and broader reach, this approach can be used to put tulip data in the heads of leaders

## PowerQuery Script

Alternatively, see below for PowerQuery Script included in the PowerBI Template

```
(TulipTableId as text, instance as text) as table=>

let
Query = #table( type table [#"table" = text], { {TulipTableId}}),

Function = Table.AddColumn(Query, "Offset", Number.Round(Json.Document(Web.Contents("https://"&instance&"/api/v3/tables/"& TulipTableId &"/count"))/100)),

ExpandedOffset =Table.ExpandListColumn(Function, "Offset"),

NbLoop=Number.Round(Json.Document(Web.Contents("https://"&instance&"/api/v3/tables/"& TulipTableId &"/count"))/100),

TableOffset=Table.FromList(List.Transform({0..NbLoop},each Number.ToText(_*100))),

TableOffset1=Table.RenameColumns(TableOffset,{{"Column1", "Offset"}}),

TulipTable= Table.AddColumn(TableOffset1, "Records", each Table.FromRecords(Json.Document(Web.Contents("https://"&instance&"/api/v3/tables/" & TulipTableId & "/records?limit=100&offset="& [Offset] &"&sortBy=_sequenceNumber&sortDir=asc"))))

in
TulipTable
```

## Power BI Service Integration

Note

Although the script above works in Power BI Desktop, automatic refresh in the cloud (Power BI Service) requires special attention. To avoid the Dynamic Data Source error, the script must use the RelativePath and Query functions within Web.Contents.

This allows Power BI to identify the root URL of the Tulip instance as a static data source, enabling scheduled refreshes and secure management of API credentials once the report is published.

Use the following Power Query (M) script for Power BI Service compatibility:

```
(TulipTableId as text, instance as text) as table =>
let
    BaseUrl = "https://" & instance,
    CountPath = "api/v3/tables/" & TulipTableId & "/count",
    NbRecords = Json.Document(Web.Contents(BaseUrl, [RelativePath = CountPath])),
    NbLoop = Number.RoundUp(NbRecords / 100),
    Offsets = List.Transform({0..NbLoop-1}, each _ * 100),
    TableOffset = Table.FromList(Offsets, Splitter.SplitByNothing(), {"Offset"}),
    TableOffset1 = Table.TransformColumnTypes(TableOffset, {{"Offset", type text}}),
    TulipTable = Table.AddColumn(TableOffset1, "Records", each 
        let
            RecordsPath = "api/v3/tables/" & TulipTableId & "/records",
            Response = Json.Document(
                Web.Contents(BaseUrl, [
                    RelativePath = RecordsPath,
                    Query = [
                        limit = "100",
                        offset = [Offset],
                        sortBy = "_sequenceNumber",
                        sortDir = "asc"
                    ]
                ])
            )
        in
            Table.FromRecords(Response)
    )
in
    TulipTable
```

*This Power BI Service integration guidance was contributed by ATS.*

## Instructions

Download the .pbix template and follow the in-app instructions (Shown below)

1. Review templated PowerQuery under section: "Home >>> Transform Data" to open PowerQuery
2. Review the query "Tulip Query" and replace Tulip TableID with desired table ID and instance with instance url (e.g., company.tulip.co)
3. Click "Invoke" and enter API credentials (Use "Basic" Authentication)
4. Clarify privacy level when prompted (Default is organization for most use cases)
5. Click on the Split Arrows to the right of the records column
6. Modify table as needed; click "Close and Apply"

## Further References

- [PowerBI Desktop Support](https://learn.microsoft.com/en-us/power-bi/transform-model/desktop-query-overview)
- [Microsoft Documentation on Dynamic Data Sources](https://learn.microsoft.com/en-us/power-bi/connect-data/refresh-data#refresh-and-dynamic-data-sources)
