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

Enhance your career with this limited time 50% discount on Fabric and Power BI exams. Ends August 31st. Request your voucher.

Reply
Nathaniel1307
Regular Visitor

Handling Paginated JSON from API

Hi All,

I'm trying to get some data from an API that returns paginated data in JSON format from a POST request.
Query I have so far is below which retrives the first 500 records but I'm struggling to come up with a way to retrieve the other records, the JSON reponse returns has_more = TRUE when there are other pages to retrieve and other pages can be retrieved by incrementing the page number in the content of the request.

 

Any help much appreciated.

URL, Site ID and API Key removed for security

 

let
    url = "https://URL/api/reports/ID",
    headers = [#"Content-Type" = "application/json", #"X-Site-ID" = "SITEID", #"X-Api-Key" = "APIKEY"],
    response = Web.Contents(
        url,
        [
            Headers = headers,
            Content = Json.FromValue([page = 1])
        ]
    ),
    jsonResponse = Json.Document(response),
    data = jsonResponse[data],
    #"Converted to Table" = Table.FromList(data, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    #"Expanded Column1" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", {"id", "Student ID", "First Name", "Last Name", "Year of Study", "Date", "Product Name", "Total Price", "VAT", "Net", "Entered", "Status", "Refund Date", "Event Date", "Event Title"}, {"id", "Student ID", "First Name", "Last Name", "Year of Study", "Date", "Product Name", "Total Price", "VAT", "Net", "Entered", "Status", "Refund Date", "Event Date", "Event Title"}),
    #"Added Custom" = Table.AddColumn(#"Expanded Column1", "Date2", each #datetime(1970,1,1,0,0,0)+#duration(0,0,0,[Date])),
    #"Changed Type" = Table.TransformColumnTypes(#"Added Custom",{{"Date2", type datetime}}),
    #"Removed Columns" = Table.RemoveColumns(#"Changed Type",{"Date"}),
    #"Renamed Columns" = Table.RenameColumns(#"Removed Columns",{{"Date2", "Date"}})
in
    #"Renamed Columns"

 

Nathaniel1307_0-1748950032276.png

 

2 ACCEPTED SOLUTIONS
burakkaragoz
Community Champion
Community Champion

Hi @Nathaniel1307 ,

 

You're on the right track. When working with paginated APIs in Power Query, especially ones that use a has_more flag and page numbers, you’ll need to implement a recursive or loop-based function to fetch all pages.

Here’s a simplified approach using a custom function:

1. Create a function to fetch a single page:

let
    GetPage = (page as number) =>
    let
        url = "https://URL/api/report/87",
        headers = [
            #"Content-Type" = "application/json",
            #"Site-ID" = "SITEID",
            #"API-Key" = "APIKEY"
        ],
        body = Json.FromValue([page = page]),
        response = Web.Contents(url, [Headers = headers, Content = body]),
        json = Json.Document(response),
        data = json[data],
        hasMore = json[has_more]
    in
        [Items = data[items], HasMore = hasMore]
in
    GetPage

2. Use a loop to fetch all pages:

let
    GetAllPages = List.Generate(
        () => [Page = 1, Result = GetPage(1)],
        each [Result][HasMore] = true,
        each [Page = [Page] + 1, Result = GetPage([Page] + 1)],
        each [Result][Items]
    ),
    Combined = List.Combine(GetAllPages),
    TableOut = Table.FromList(Combined, Splitter.SplitByNothing(), null, null, ExtraValues.Error)
in
    TableOut

This will keep calling the API until has_more is false and combine all the results into one table.

Let me know if you need help adapting this to your exact schema.

If my response resolved your query, kindly mark it as the Accepted Solution to assist others. Additionally, I would be grateful for a 'Kudos' if you found my response helpful.
translation and formatting supported by AI

View solution in original post

Hi @Nathaniel1307 ,

Thanks @burakkaragoz ,
Thank you for the update, @burakkaragoz  is explaining how to avoid errors when expanding a field that might not exist in the JSON response.
The expansion process in Power Query refers to when we extract fields from nested JSON structures like records or lists into separate columns.
In this case, we are expanding:
The data items field from JSON into a Power Query table.
The "supply" field if it exists inside the extracted records.
Supply field is an example scenario. The example checks if the "supply" field is present using Table.HasColumns(). If "supply" exists, it expands the "amount" column inside it. If it doesn’t exist, the step is skipped to prevent errors or empty columns. This approach ensures Power Query handles missing fields safely without breaking the transformation process. In your case you can use any other field from your table.

Best regards,
Chaithra.

View solution in original post

8 REPLIES 8
v-echaithra
Community Support
Community Support

Hi @Nathaniel1307 ,

We wanted to kindly follow up to check if the solution provided for the issue worked? or Let us know if you need any further assistance?
If our response addressed, please mark it as Accept as solution and click Yes if you found it helpful.

 

Regards,
Chaithra.

v-echaithra
Community Support
Community Support

Hi @Nathaniel1307 ,

May I ask if you have gotten this issue resolved?

 

If it is solved, please mark the helpful reply or share your solution and accept it as solution, it will be helpful for other members of the community who have similar problems as yours to solve it faster.

 

Regards,
Chaithra.

v-echaithra
Community Support
Community Support

Hi @Nathaniel1307 ,

As we haven’t heard back from you, we wanted to kindly follow up to check if the solution provided for the issue worked? or Let us know if you need any further assistance?
If our response addressed, please mark it as Accept as solution and click Yes if you found it helpful.

 

Regards,

Chaithra.

burakkaragoz
Community Champion
Community Champion

Hi @Nathaniel1307 ,

 

You're on the right track. When working with paginated APIs in Power Query, especially ones that use a has_more flag and page numbers, you’ll need to implement a recursive or loop-based function to fetch all pages.

Here’s a simplified approach using a custom function:

1. Create a function to fetch a single page:

let
    GetPage = (page as number) =>
    let
        url = "https://URL/api/report/87",
        headers = [
            #"Content-Type" = "application/json",
            #"Site-ID" = "SITEID",
            #"API-Key" = "APIKEY"
        ],
        body = Json.FromValue([page = page]),
        response = Web.Contents(url, [Headers = headers, Content = body]),
        json = Json.Document(response),
        data = json[data],
        hasMore = json[has_more]
    in
        [Items = data[items], HasMore = hasMore]
in
    GetPage

2. Use a loop to fetch all pages:

let
    GetAllPages = List.Generate(
        () => [Page = 1, Result = GetPage(1)],
        each [Result][HasMore] = true,
        each [Page = [Page] + 1, Result = GetPage([Page] + 1)],
        each [Result][Items]
    ),
    Combined = List.Combine(GetAllPages),
    TableOut = Table.FromList(Combined, Splitter.SplitByNothing(), null, null, ExtraValues.Error)
in
    TableOut

This will keep calling the API until has_more is false and combine all the results into one table.

Let me know if you need help adapting this to your exact schema.

If my response resolved your query, kindly mark it as the Accepted Solution to assist others. Additionally, I would be grateful for a 'Kudos' if you found my response helpful.
translation and formatting supported by AI

Hi @burakkaragoz 

I've tried out your code but am getting the below error:

An error occurred in the ‘GetPage’ query. Expression.Error: We cannot apply field access to the type List.
Details:
Value=[List]
Key=items

@Nathaniel1307 ,

 

No problem at all, glad you’re getting the data now. For the supply field, you’re right—Power Query does always supply blank if the column isn’t found in the input JSON.

If you want to handle this case, you can add some logic to check if the column exists before you try to expand it. One way is to use Table.HasColumns before expanding. Here’s quick example:

let Source ..., JsonData ..., // Check if "supply" exists HasSupply Table.HasColumns(JsonData, "supply"), Expanded if HasSupply then Table.ExpandRecordColumn(JsonData, "supply", {"amount"}, {"supply.amount"}) else JsonData in Expanded

With this, you’ll only try to expand “supply” if it’s actually there. If not, the step will just skip expansion and you won’t get blanks or errors.

Hi @burakkaragoz 

I don't quite understand where we are expanding or where supply comes from?

Hi @Nathaniel1307 ,

Thanks @burakkaragoz ,
Thank you for the update, @burakkaragoz  is explaining how to avoid errors when expanding a field that might not exist in the JSON response.
The expansion process in Power Query refers to when we extract fields from nested JSON structures like records or lists into separate columns.
In this case, we are expanding:
The data items field from JSON into a Power Query table.
The "supply" field if it exists inside the extracted records.
Supply field is an example scenario. The example checks if the "supply" field is present using Table.HasColumns(). If "supply" exists, it expands the "amount" column inside it. If it doesn’t exist, the step is skipped to prevent errors or empty columns. This approach ensures Power Query handles missing fields safely without breaking the transformation process. In your case you can use any other field from your table.

Best regards,
Chaithra.

Helpful resources

Announcements
July 2025 community update carousel

Fabric Community Update - July 2025

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

July PBI25 Carousel

Power BI Monthly Update - July 2025

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