Supplies are limited. Contact info@espc.tech right away to save your spot before the conference sells out.
Get your discountScore big with last-minute savings on the final tickets to FabCon Vienna. Secure your discount
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:
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?
Is there any way to configure automatic data refresh for this REST API source in Power BI Service without using a data gateway?
Are there any alternatives or best practices for paginating and refreshing data from public APIs through Power BI Service?
Extra details:
The REST API is publicly accessible and does not need a login.
The layer URL: https://gis.brno.cz/ags1/rest/services/Hosted/cyklo_meteo_merged/FeatureServer/0/query
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"
Solved! Go to Solution.
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...
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
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...
User | Count |
---|---|
34 | |
16 | |
13 | |
10 | |
8 |
User | Count |
---|---|
52 | |
31 | |
24 | |
17 | |
15 |