Reference

Pagination

The pagination envelope every list response carries, and how to walk it: auto-iterate, one page at a time, collect everything, or by hand.

Every list endpoint returns one page of items plus the metadata to find the next. The SDKs will walk it for you, hand you one page at a time, or stay out of the way while you drive page and page_size yourself.

ApproachReach for it when
Auto-paginationYou want every result and would rather not think about pages
Collect all itemsYou want every result in one list and the result set is small
Page-level iterationYou process results a batch at a time
Manual paginationYou decide which page is fetched and when

Response format

Paginated endpoints are offset-based. You ask for a page number and a page size, and the response reports where that page sits in the full result set.

Page numbers are 1-indexed. The first page is page=1.
{
    "success": true,
    "data": {
        "items": [],
        "pagination": {
            "total_items": 142,
            "total_pages": 15,
            "current_page": 1,
            "page_size": 10,
            "has_next": true,
            "has_previous": false
        }
    },
    "timestamp": "2025-10-15T10:00:00Z"
}

success, data and timestamp are the standard envelope on every LevelFour response, described in the API reference.

Auto-pagination

The SDK fetches the next page when you reach the end of the current one, so your loop reads as though the whole result set were already in memory.

for rec in client.recommendations.list(page_size=50):
    print(rec.recommendation_id)

Async (Python)

The async client takes the same call. Await it once, then iterate with async for.

async for rec in await async_client.recommendations.list(page_size=50):
    print(rec.recommendation_id)

Collect all items

Fetch every page and return all items as a single collection.

Collecting walks every page before it returns anything, and holds the whole result set in memory at once. On a large result set, iterate instead.
all_recs = list(client.recommendations.list(page_size=100))

Page-level iteration

Each turn of the loop hands you a whole page rather than a single item.

for page in client.recommendations.list(page_size=50).iter_pages():
    print(f"Processing {len(page.items)} items")
    for item in page.items:
        process(item)
The Go client signals a finished walk by returning levelfour.ErrNoPages from GetNextPage. Match it with errors.Is before treating the error as a failure.

Async pages (Python)

iter_pages() works the same way on the async client.

async for page in (await async_client.recommendations.list(page_size=50)).iter_pages():
    print(f"Processing {len(page.items)} items")

Manual pagination

Pass page and page_size directly and handle navigation yourself.

page = client.recommendations.list(page=1, page_size=50)
while page:
    for item in page.items:
        process(item)
    page = page.next_page()

Paginated endpoints

Every method below returns a paginated result. The resource pages carry each one's parameters and response shape.

What it listsPythonTypeScriptGo
Recommendationsrecommendations.list()recommendations.list()Recommendations.List()
Recommendations for one providerrecommendations.list_by_provider()recommendations.listByProvider()Recommendations.ListByProvider()
Potential savings for one providerrecommendations.list_provider_potential_savings()recommendations.listProviderPotentialSavings()Recommendations.ListProviderPotentialSavings()
Realized savingsrecommendations.audit.list()recommendations.audit.list()Recommendations.Audit.List()
Realized savings for one providerrecommendations.audit.list_by_provider()recommendations.audit.listByProvider()Recommendations.Audit.ListByProvider()
Cost breakdowncosts.list()costs.list()Costs.List()
Cost breakdown for one providercosts.list_by_provider()costs.listByProvider()Costs.ListByProvider()
There is no providers namespace behind these. client.providers lists your connected providers and nothing else. Everything scoped to a single provider lives on recommendations or costs and takes a provider_id.

Defaults

These are the values a request falls back to when you leave the parameter out. page is always 1.

The page size is not the same everywhere. The two savings lists and the recommendations list are sized for scanning a backlog; the breakdowns return one row per resource and are capped tighter.

Endpointpage_size defaultMaximum
recommendations.list()20200
recommendations.list_by_provider()20200
recommendations.list_provider_potential_savings()20200
recommendations.audit.list()10100
recommendations.audit.list_by_provider()10100
costs.list()10100
costs.list_by_provider()10100
Asking for more than the maximum is a 422, not a silent clamp. The auto-paginating iterators above sidestep the whole question, because they carry the page size the server gave them.

Next

  • Error handling maps each status code to its typed class and lists what the SDKs retry before you see the failure
  • Resources documents every method, paginated or not, in all three SDKs
  • Python, TypeScript and Go name the pager type each client returns

On this page

Ask the FinOps Agent about your cloud spend