Pagination
Three kinds of list use three pagination styles. Pick the endpoint by what you need, not only by the filter set.
| Page numbers | Scroll cursor | ID cursor | |
|---|---|---|---|
| Endpoints | /search, /car-options | /cars | /countries, /locations |
| Request | page, perPage | Follow next_url | after_id, per_page |
| Page size | 2–50, default 50 | 1–500, default 500 | 1–1,000, default 100 |
| Depth limit | page × perPage ≤ 10,000 | None, cursor lives 1–15 min | None |
| Stop when | links.next is null | scroll_id is null | meta.has_more is false |
| Use for | User-facing search | Full inventory sync | Syncing dictionaries |
Two /search quirks to code around. data can hold one more car than perPage (we saw 3 cars for perPage=2), so slice client-side if you need an exact size. And meta.total stops at 10,000: treat that value as "10,000 or more" and call /search/count with the same filters for the exact number.
Automobile and motorcycle dictionaries
Omit vehicle_type for automobiles; motorcycle / 2 selects motorcycles. Preserve this type throughout the hierarchy.
per_page is 1–100, default 100. Use page or after_id, never both. Offset: page × per_page ≤ 10000. For complete traversal, send next_after_id as after_id with page omitted until has_more=false. total then counts remaining matches.
Without pagination parameters, /brands and /models keep their legacy arrays and limits. Send per_page=100 for {data,meta}. Embedded generations keep {name,from,to}; use /generations/{model_id} for IDs.
{
"links": {
"first": "https://api.carstat.dev/search?perPage=2&page=1",
"last": "https://api.carstat.dev/search?perPage=2&page=5000",
"prev": null,
"next": "https://api.carstat.dev/search?perPage=2&page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 5000,
"path": "https://api.carstat.dev/search",
"per_page": 2,
"to": 3,
"total": 10000
}
}{
"data": [
"…3 countries…"
],
"meta": {
"per_page": 3,
"has_more": true,
"next_after_id": 3
}
}Get API access
Connect your key to run every request on these pages against your own data. No key yet? Ask us for a demo key: the same JSON as the paid plans.