Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Score big with last-minute savings on the final tickets to FabCon Vienna. Secure your discount

Reply
komyji
Frequent Visitor

Power BI Online - Cannot Set up Automatic Refresh for REST API Source Without Gateway

Hello,

I have a Power BI report where I connected to data from ArcGIS Online using a public REST API endpoint. Because the REST API only returns 1,000 records per request, I wrote an M query (Power Query) that paginates through the API and combines all the data into a table. My query uses the Web.Contents function with the RelativePath and Query options (see code and API details below).

Everything works perfectly in Power BI Desktop, including the pagination and loading of all data. However, after publishing the report to Power BI Service (app.powerbi.com), I am unable to set up automatic data refresh. The Service tells me that a gateway is required, even though the API is public and requires no authentication.

My main questions:

  1. Why does Power BI Service require an on-premises data gateway for refreshing data from a public REST API source, when no gateway is required for other online/cloud sources?

  2. Is there any way to configure automatic data refresh for this REST API source in Power BI Service without using a data gateway?

  3. Are there any alternatives or best practices for paginating and refreshing data from public APIs through Power BI Service?

    Extra details:

let
    //  Velikost stránky
    PageSize = 1000,

    //  Pevně dané ofsety: 0, 1000, 2000, ..., 499000
    Offsets = List.Transform({0..499}, each _ * PageSize),

    //  Funkce pro načtení stránky s pevně danou URL přes RelativePath a Query
    GetPage = (offset as number) =>
        let
            Response = Json.Document(
                Web.Contents(
                    "https://gis.brno.cz",
                    [
                        RelativePath = "ags1/rest/services/Hosted/cyklo_meteo_merged/FeatureServer/0/query",
                        Query = [
                            where = "1=1",
                            outFields = "*",
                            returnGeometry = "true",
                            f = "json",
                            resultOffset = Text.From(offset),
                            resultRecordCount = Text.From(PageSize)
                        ]
                    ]
                )
            )
        in
            Response,

    //  Načtení všech stránek
    Pages = List.Transform(Offsets, each GetPage(_)),

    //  Odstranění neplatných (null) stránek a ponechání jen těch s "features"
    CleanPages = List.Select(Pages, each _ <> null and Record.HasFields(_, "features")),

    //  Sloučení všech záznamů "features" do jednoho seznamu
    Features = List.Combine(List.Transform(CleanPages, each [features])),

    //  Převedení do tabulky a rozbalení
    #"Converted to Table" = Table.FromList(Features, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    #"Expanded Column1" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", {"attributes"}, {"attributes"}),
    #"Expanded attributes" = Table.ExpandRecordColumn(#"Expanded Column1", "attributes", {
        "globalid", "datetime_", "firstdirection_pedestrians", "seconddirection_name", 
        "seconddirection_cyclists", "precipitation", "pedestrianstotal", "cycliststotal", 
        "temperature", "unitid", "firstdirection_name", "objectid", 
        "seconddirection_pedestrians", "firstdirection_cyclists"
    }, {
        "globalid", "datetime_", "firstdirection_pedestrians", "seconddirection_name", 
        "seconddirection_cyclists", "precipitation", "pedestrianstotal", "cycliststotal", 
        "temperature", "unitid", "firstdirection_name", "objectid", 
        "seconddirection_pedestrians", "firstdirection_cyclists"
    }),

    //  Změna datových typů
    #"Changed Type" = Table.TransformColumnTypes(#"Expanded attributes", {
        {"firstdirection_pedestrians", Int64.Type}, {"seconddirection_cyclists", Int64.Type},
        {"precipitation", type number}, {"pedestrianstotal", Int64.Type},
        {"cycliststotal", Int64.Type}, {"temperature", type number},
        {"objectid", Int64.Type}, {"seconddirection_pedestrians", Int64.Type},
        {"firstdirection_cyclists", Int64.Type}
    }),

    //  Zpracování času
    #"Added Custom" = Table.AddColumn(#"Changed Type", "datetime_parsed", each DateTime.FromText([datetime_], "en-US"), type datetime),
    #"Added Custom1" = Table.AddColumn(#"Added Custom", "datum", each DateTime.Date([datetime_parsed])),
    #"Added Custom2" = Table.AddColumn(#"Added Custom1", "hodina", each Time.Hour([datetime_parsed])),
    #"Changed Type1" = Table.TransformColumnTypes(#"Added Custom2", {{"datum", type date}, {"hodina", Int64.Type}})
in
    #"Changed Type1"

 

1 ACCEPTED SOLUTION
shashiPaul1570_
Resolver I
Resolver I

Hi @komyji 

Thanks for sharing this it's a common issue when using REST APIs in Power BI Service, even when the API is public and works perfectly in Power BI Desktop.

Now, why this happens and how you can resolve it without needing an on-premises data gateway.

Power BI Service performs a security check to detect dynamic data sources — and this includes any queries that build URLs dynamically, such as

  • Pagination via List.Generate

  • Using Web.Contents() with RelativePath inside a function

  • Dynamically constructed query strings or endpoints

Once a query is flagged as dynamic, Power BI disables direct cloud refresh and requires a gateway, even for public endpoints. This behavior is confirmed by Microsoft and discussed in multiple community threads.

How to Fix It (No Gateway Required)
Use Web.Contents with a static base URL, and pass pagination and filters through RelativePath and Query parameters. This makes your query predictable and certifiable, reducing the chance of being flagged as dynamic.

Example

 

Web.Contents(
"https://gis.brno.cz",
[
RelativePath = "ags1/rest/services/Hosted/cyklo_meteo_merged/FeatureServer/0/query",
Query = [
where = "1=1",
resultOffset = "0",
resultRecordCount = "1000",
f = "json"
]
]
)

 

This approach is recommended in various threads mentioned below. Follow this and let me know if it works for you — and feel free to support this post as a solution

https://stackoverflow.com/questions/77061776/this-dataset-includes-a-dynamic-data-source-since-dynam...
https://community.fabric.microsoft.com/t5/Desktop/Help-applying-Query-and-Relative-path-to-avoid-dyn...

 

View solution in original post

5 REPLIES 5
v-dineshya
Community Support
Community Support

Hi @komyji ,

Thank you for reaching out to the Microsoft Community Forum.

 

Hi @shashiPaul1570_ , Thank you for your prompt response.

 

Hi @komyji  , In addition to @shashiPaul1570_  response, I am adding some more points.

 

Power BI Service requires a gateway when it cannot classify the data source as cloud-based. Even though your REST API is public and hosted online, Power BI sees the use of Web.Contents with dynamic parameters like pagination as a custom connector, which it treats as an on-premises source. This is due to how Power BI evaluates data privacy levels and query folding. When dynamic URL construction is involved, Power BI can't consider the source is safe to refresh without a gateway.

 

Can you refresh this REST API in Power BI Service without a gateway?
Solution: Yes, but with limitations and workarounds.

 

Please try below workarounds

 

1. Please try to move your M query into a Power BI Dataflow. Dataflows run in the cloud and often don't require a gateway for public web sources.

 

Go to Power BI Service --> Workspace --> Dataflows --> Create new. Use the same M code in the Power Query editor. Save and refresh the dataflow. Connect your report to the dataflow instead of the API directly.

 

3. Create an Azure Function or Logic App that handles the pagination and returns a single JSON response. Then connect Power BI to that endpoint. Power BI sees it as a single cloud source.

 

4. Minimize dynamic URL logic inside Power BI.

 

5. Preprocess data externally with Azure, AWS Lambda or a small web service.

 

6. Limit the number of pages if possible to reduce refresh time.

 

7. Cache data in a cloud database like Azure SQL and SharePoint list, connect Power BI to that.

 

I hope this information helps. Please do let us know if you have any further queries.

 

Regards,

Dinesh

Hi @komyji ,

We haven’t heard from you on the last response and was just checking back to see if you have a resolution yet. And, if you have any further query do let us know.

 

Regards,

Dinesh

Hi @komyji ,

We haven’t heard from you on the last response and was just checking back to see if you have a resolution yet. And, if you have any further query do let us know.

 

Regards,

Dinesh

Hi @komyji ,

We haven’t heard from you on the last response and was just checking back to see if you have a resolution yet. And, if you have any further query do let us know.

 

Regards,

Dinesh

shashiPaul1570_
Resolver I
Resolver I

Hi @komyji 

Thanks for sharing this it's a common issue when using REST APIs in Power BI Service, even when the API is public and works perfectly in Power BI Desktop.

Now, why this happens and how you can resolve it without needing an on-premises data gateway.

Power BI Service performs a security check to detect dynamic data sources — and this includes any queries that build URLs dynamically, such as

  • Pagination via List.Generate

  • Using Web.Contents() with RelativePath inside a function

  • Dynamically constructed query strings or endpoints

Once a query is flagged as dynamic, Power BI disables direct cloud refresh and requires a gateway, even for public endpoints. This behavior is confirmed by Microsoft and discussed in multiple community threads.

How to Fix It (No Gateway Required)
Use Web.Contents with a static base URL, and pass pagination and filters through RelativePath and Query parameters. This makes your query predictable and certifiable, reducing the chance of being flagged as dynamic.

Example

 

Web.Contents(
"https://gis.brno.cz",
[
RelativePath = "ags1/rest/services/Hosted/cyklo_meteo_merged/FeatureServer/0/query",
Query = [
where = "1=1",
resultOffset = "0",
resultRecordCount = "1000",
f = "json"
]
]
)

 

This approach is recommended in various threads mentioned below. Follow this and let me know if it works for you — and feel free to support this post as a solution

https://stackoverflow.com/questions/77061776/this-dataset-includes-a-dynamic-data-source-since-dynam...
https://community.fabric.microsoft.com/t5/Desktop/Help-applying-Query-and-Relative-path-to-avoid-dyn...

 

Helpful resources

Announcements
August Power BI Update Carousel

Power BI Monthly Update - August 2025

Check out the August 2025 Power BI update to learn about new features.

August 2025 community update carousel

Fabric Community Update - August 2025

Find out what's new and trending in the Fabric community.