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

Get Fabric Certified for FREE during Fabric Data Days. Don't miss your chance! Learn more

Reply
J94
Helper I
Helper I

API call

Hi everyone,

 

I try to get data in the Query Editor from an API. This API has several pages of data. I have been reading on this topic in the community and asked ChatGPT for help, without success. All I get now is the same page several times. Can someone help to improve the query? I am stuck unfortunately. 

let
token = "my_token", 
baseUrl = "https://apiv2.my_site.com/v2/users/search",
perPage = 100,

GetPage = (page as number) =>
let
body = Text.ToBinary("{""page"":" & Number.ToText(page) & ",""perPage"":" & Number.ToText(perPage) & "}"),
response = Json.Document(
Web.Contents(baseUrl,
[
Headers = [
#"Content-Type" = "application/json",
Authorization = "Bearer " & token
],
Content = body
]
)
)
in
response,
FirstPage = GetPage(1),
TotalPages = FirstPage[totalPages],
PageNumbers = List.Numbers(1, TotalPages),
AllPagesRaw = List.Transform(PageNumbers, each GetPage(_)),
AllContent = List.Transform(AllPagesRaw, each _[content]),
CombinedContent = List.Combine(AllContent),
ResultTable = Table.FromRecords(CombinedContent)
in
ResultTable

1 ACCEPTED SOLUTION
DataNinja777
Super User
Super User

Hi @J94 ,

 

It appears you've encountered a very common issue when paginating through an API in Power Query. The problem stems from a feature called "lazy evaluation," where the engine tries to optimize performance by caching the result of functions like Web.Contents. When used inside a loop or a function like List.Transform, it can mistakenly reuse the result from the first API call for all subsequent calls, which is why you see the same page of data repeated. The solution is to force Power Query to recognize each call as a unique request.

The most direct way to fix your query is to add a Query option to your Web.Contents function. This adds a unique query string (like ?page=1, ?page=2) to the end of the base URL for each iteration. Even though your API reads the page number from the request body, this change signals to the Power Query engine that each call is distinct and should be executed fresh instead of using a cached result. The rest of your logic for determining the page count and combining the results is perfectly fine and can remain as is.

Here is your original code with the small but critical modification applied.

let
    token = "my_token",
    baseUrl = "https://apiv2.my_site.com/v2/users/search",
    perPage = 100,

    GetPage = (page as number) =>
        let
            body = Text.ToBinary("{""page"":" & Number.ToText(page) & ",""perPage"":" & Number.ToText(perPage) & "}"),
            response = Json.Document(
                Web.Contents(baseUrl,
                    [
                        Headers = [
                            #"Content-Type" = "application/json",
                            Authorization = "Bearer " & token
                        ],
                        Content = body,
                        // This Query option is the key change that forces each call to be unique
                        Query = [page = Number.ToText(page)]
                    ]
                )
            )
        in
            response,

    FirstPage = GetPage(1),
    TotalPages = FirstPage[totalPages],
    PageNumbers = List.Numbers(1, TotalPages),
    AllPagesRaw = List.Transform(PageNumbers, each GetPage(_)),
    AllContent = List.Transform(AllPagesRaw, each _[content]),
    CombinedContent = List.Combine(AllContent),
    ResultTable = Table.FromRecords(CombinedContent)
in
    ResultTable

As an alternative, many developers consider the List.Generate function to be a more robust and memory-efficient pattern for pagination. It constructs the list of results iteratively, fetching one page at a time based on the result of the previous step. This approach is especially powerful when an API doesn't tell you the total number of pages upfront. While your API does provide totalPages, List.Generate is still an excellent technique to be aware of for future projects.

The following query accomplishes the same goal using the List.Generate pattern.

let
    token = "my_token",
    baseUrl = "https://apiv2.my_site.com/v2/users/search",
    perPage = 100,

    GetPage = (page as number) as record =>
        let
            body = Text.ToBinary("{""page"":" & Number.ToText(page) & ",""perPage"":" & Number.ToText(perPage) & "}"),
            response = Json.Document(
                Web.Contents(baseUrl,
                    [
                        Headers = [#"Content-Type"="application/json", Authorization="Bearer " & token],
                        Content = body,
                        Query = [page=Number.ToText(page)]
                    ]
                )
            )
        in
            response,

    FirstPageResponse = GetPage(1),
    TotalPages = FirstPageResponse[totalPages],

    AllPagesContent = List.Generate(
        () => [Page = 1, Content = FirstPageResponse[content]],
        each [Page] <= TotalPages,
        each [Page = [Page] + 1, Content = GetPage([Page] + 1)[content]],
        each [Content]
    ),

    CombinedContent = List.Combine(AllPagesContent),
    ResultTable = Table.FromRecords(CombinedContent)
in
    ResultTable

To apply these changes, you can navigate to the Power Query Editor, select your query, and open the Advanced Editor from the Home tab. There, you can replace your script with one of the versions provided above. After ensuring your real token is in place, your query should successfully retrieve and combine the data from all pages.

 

Best regards,

View solution in original post

2 REPLIES 2
J94
Helper I
Helper I

Hi @DataNinja777 
thank you so much! It works perfectly 🙂

DataNinja777
Super User
Super User

Hi @J94 ,

 

It appears you've encountered a very common issue when paginating through an API in Power Query. The problem stems from a feature called "lazy evaluation," where the engine tries to optimize performance by caching the result of functions like Web.Contents. When used inside a loop or a function like List.Transform, it can mistakenly reuse the result from the first API call for all subsequent calls, which is why you see the same page of data repeated. The solution is to force Power Query to recognize each call as a unique request.

The most direct way to fix your query is to add a Query option to your Web.Contents function. This adds a unique query string (like ?page=1, ?page=2) to the end of the base URL for each iteration. Even though your API reads the page number from the request body, this change signals to the Power Query engine that each call is distinct and should be executed fresh instead of using a cached result. The rest of your logic for determining the page count and combining the results is perfectly fine and can remain as is.

Here is your original code with the small but critical modification applied.

let
    token = "my_token",
    baseUrl = "https://apiv2.my_site.com/v2/users/search",
    perPage = 100,

    GetPage = (page as number) =>
        let
            body = Text.ToBinary("{""page"":" & Number.ToText(page) & ",""perPage"":" & Number.ToText(perPage) & "}"),
            response = Json.Document(
                Web.Contents(baseUrl,
                    [
                        Headers = [
                            #"Content-Type" = "application/json",
                            Authorization = "Bearer " & token
                        ],
                        Content = body,
                        // This Query option is the key change that forces each call to be unique
                        Query = [page = Number.ToText(page)]
                    ]
                )
            )
        in
            response,

    FirstPage = GetPage(1),
    TotalPages = FirstPage[totalPages],
    PageNumbers = List.Numbers(1, TotalPages),
    AllPagesRaw = List.Transform(PageNumbers, each GetPage(_)),
    AllContent = List.Transform(AllPagesRaw, each _[content]),
    CombinedContent = List.Combine(AllContent),
    ResultTable = Table.FromRecords(CombinedContent)
in
    ResultTable

As an alternative, many developers consider the List.Generate function to be a more robust and memory-efficient pattern for pagination. It constructs the list of results iteratively, fetching one page at a time based on the result of the previous step. This approach is especially powerful when an API doesn't tell you the total number of pages upfront. While your API does provide totalPages, List.Generate is still an excellent technique to be aware of for future projects.

The following query accomplishes the same goal using the List.Generate pattern.

let
    token = "my_token",
    baseUrl = "https://apiv2.my_site.com/v2/users/search",
    perPage = 100,

    GetPage = (page as number) as record =>
        let
            body = Text.ToBinary("{""page"":" & Number.ToText(page) & ",""perPage"":" & Number.ToText(perPage) & "}"),
            response = Json.Document(
                Web.Contents(baseUrl,
                    [
                        Headers = [#"Content-Type"="application/json", Authorization="Bearer " & token],
                        Content = body,
                        Query = [page=Number.ToText(page)]
                    ]
                )
            )
        in
            response,

    FirstPageResponse = GetPage(1),
    TotalPages = FirstPageResponse[totalPages],

    AllPagesContent = List.Generate(
        () => [Page = 1, Content = FirstPageResponse[content]],
        each [Page] <= TotalPages,
        each [Page = [Page] + 1, Content = GetPage([Page] + 1)[content]],
        each [Content]
    ),

    CombinedContent = List.Combine(AllPagesContent),
    ResultTable = Table.FromRecords(CombinedContent)
in
    ResultTable

To apply these changes, you can navigate to the Power Query Editor, select your query, and open the Advanced Editor from the Home tab. There, you can replace your script with one of the versions provided above. After ensuring your real token is in place, your query should successfully retrieve and combine the data from all pages.

 

Best regards,

Helpful resources

Announcements
Fabric Data Days Carousel

Fabric Data Days

Advance your Data & AI career with 50 days of live learning, contests, hands-on challenges, study groups & certifications and more!

October Power BI Update Carousel

Power BI Monthly Update - October 2025

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

FabCon Atlanta 2026 carousel

FabCon Atlanta 2026

Join us at FabCon Atlanta, March 16-20, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM.