Most entities in the Paddle API have a list endpoint for fetching entities in bulk. For example, you can get a list of transactions, customers, and subscriptions.
Each response is a page of results, and the Paddle ID of the last entity in the page acts as the cursor for the next page.
Pagination object
Responses for paginated list endpoints always return:
- A
dataarray that includes the entities returned. - A
metaobject that includes apaginationobject.
The meta.pagination object includes the following keys for working with paginated responses:
Keys used for working with paginated results.
Number of entities per page for this response. May differ from the number requested if the requested number is greater than the maximum.
URL containing the query parameters of the original request, along with the after parameter that marks the starting point of the next page. Always returned, even if has_more is false.
Whether this response has another page.
Estimated number of entities for this response.
Returns the exact count for datasets of 100,000 or fewer matching entities. Returns 100001 for datasets with more than 100,000 matching entities. Returns -1 when counting is skipped or unavailable.
Page size
Most list endpoints return 50 results by default and a maximum of 200. Listing transactions returns 30 (the default and maximum). Listing adjustments returns 10 by default and a maximum of 50.
Pass per_page to change the number of results in a page. For example, to get 15 customers per page:
/customers?per_page=15 If you request more than the maximum, Paddle returns the maximum. Check meta.pagination.per_page in the response to see how many were returned.
Navigate pages
Use the next URL in meta.pagination to fetch the next page. It contains the query parameters from your original request along with an after parameter set to the Paddle ID of the last entity in the current page.
Paddle returns results after the cursor, not including it. For example, if a response returns the first ten results, the next URL returns the eleventh entity as the first result.
Check has_more to see if there's another page. When has_more is false, you've reached the last page.
estimated_total gives you an approximate total count, so you can gauge how many requests you'll need:
- For datasets of 100,000 or fewer entities, it returns the exact count.
- For larger datasets, it returns
100001to indicate more than 100,000 matches. - It returns
-1if counting is skipped or unavailable.
For reliable iteration over all results, use has_more and next rather than relying on estimated_total for exact counts.
Get previous page
There's no parameter that explicitly returns results before the cursor. Instead, use order_by to reverse the direction.
By default, Paddle returns newest entities first (id[DESC]). Set order_by=id[ASC] to reverse the direction so the next URL takes you backwards from your cursor:
/customers?order_by=id[ASC]&after={customer_id} No results
When there are no results for a request, Paddle returns an empty data array and a meta.pagination object as normal. It doesn't return an error unless the request is invalid.
If you pass a cursor that doesn't exist, Paddle returns a request_error.
Skip the count
If you don't need a total count, send the Skip-Count: true request header on a list endpoint. Paddle skips the count query and returns -1 for estimated_total. This makes responses faster, especially for large datasets.
Use this when you're paging through results with has_more and next and don't need to display or calculate the total.
Best practices
- Check
has_morerather than inferring from result count.
A response may return fewer entities thanper_pageeven when more pages exist. - Use the
nextURL directly.
Don't construct it yourself. It already includes your original filters, sort order, and cursor. - Store the
nextURL to resume polling.nextis always returned, even whenhas_moreisfalse. Persist it and use it later to pick up new results without re-scanning from the start. - Mind the
per_pagetrade-off.
Larger pages mean fewer requests but slower responses, especially for larger entities. - Send
Skip-Count: truewhen you don't need a count.
Skipping the count query speeds up list responses, especially for large datasets whereestimated_totalwould otherwise return100001. - Cache results in client-side apps.
Short-lived caches reduce load on both your app and the Paddle API.