Pagination
Endpoints listing things, like licenses or customers, return them one page at a time. You choose the page and its size, and the response tells where it stands among all the items: how many there are, and how many pages.
Request
| Query parameter | Default | What it does |
|---|---|---|
page | 1 | The page to return. Pages are numbered from 1. |
pageSize | 20 | How many items per page, from 1 to 100. |
sort | Depends on the endpoint | The field to sort by, prefixed with - for descending order, like -createdAt. |
curl "https://api.licensemanager.dev/v1/products/x7Kp2QaZ/licenses?page=2&pageSize=50&sort=-createdAt" \
-H "x-api-key: $API_KEY"Response
{
"data": [
{ "id": "l3Nv8KwB", "key": "7KQ2M-X9ZPA-H4TRC-WN6EY-B3JDF", "…": "…" }
],
"pagination": {
"page": 2,
"pageSize": 50,
"total": 142,
"totalPages": 3
}
}| Field | What it is |
|---|---|
data | The items of the page, in the requested order. Every page holds pageSize items, except the last one, which can hold fewer. |
pagination.page | The page returned, as requested. |
pagination.pageSize | The page size, as requested. |
pagination.total | How many items match the filters, across all pages. |
pagination.totalPages | How many pages there are, which is also the number of the last one. 0 when nothing matches. |
There’s a next page while page is lower than totalPages.
Going through every item
With the TypeScript SDK:
import { Configuration, LicensesApi, type License } from "@licenseman/sdk";
const licensesApi = new LicensesApi(
new Configuration({ apiKey: process.env.LICENSEMANAGER_API_KEY }),
);
async function listAllLicenses(productId: string) {
const licenses: License[] = [];
for (let page = 1; ; page++) {
const { data, pagination } = await licensesApi.listLicenses({
productId,
page,
pageSize: 100,
sort: "createdAt",
});
licenses.push(...data);
if (page >= pagination.totalPages) return licenses;
}
}Use the largest page size, 100, to make fewer requests: each one counts toward your API requests.
Sorting
Each endpoint lists the fields it can sort by in the API reference, like createdAt, expiresAt or lastActivatedAt for licenses.
- Items with the same value are ordered by id, so the order is always the same between two requests.
- Items without a value, like a license that never expires when sorting by
expiresAt, come last in ascending order, and first in descending order. - Some fields keep items without a value last in both orders, because that’s what you usually want: a license never activated when sorting by
lastActivatedAt, a license without a price when sorting byprice, a customer without a name when sorting byname.
Filtering
Most lists accept filters, which apply before paginating: total counts the items matching them. For example, licenses can be filtered by status, policyId, customerId, or by dates with createdFrom and expiresTo, and customers by email. Lists with a search parameter match text regardless of case.
Edge cases
A page past the last one returns an empty data, not an error.
Items created or deleted while you go through pages shift them: a license created between two requests can make an item appear on two pages, or none. Sort by createdAt ascending to go through items safely: new ones only add to the end. To find a specific item, filter rather than going through pages.
pageSize above 100, or a page of 0, is refused with 422 and validation_error.
To find one item, filter instead of listing: ?email=jane@example.com on customers, ?key=… on licenses, ?slug=yearly on policies.