Pagination
Cursor pagination with limit and next_token.
Collection endpoints page with an opaque forward cursor. There are no page numbers and no total count.
Requesting a page
| Parameter | Type | Default | Notes |
|---|---|---|---|
limit | integer | 20 | Items per page, 1–100 |
next_token | string | — | Cursor from the previous response |
GET /merchants?limit=50
GET /merchants?limit=50&next_token=eyJwayI6IjNjMWU1YTkwI…
Reading the response
Pagination state lives in meta.pagination:
{
"data": [ "…50 merchants…" ],
"meta": {
"correlation_id": "…",
"item_count": 50,
"pagination": {
"limit": 50,
"next_token": "eyJwayI6IjNjMWU1YTkwI…"
}
}
}next_token absent means you have reached the end. That is the only end-of-collection signal — do not infer it from a short page, and do not keep paging until you get an empty array.
async function* allMerchants(campaignId) {
let token;
do {
const url = new URL('https://api.acc.funtrips.io/v2/merchants');
url.searchParams.set('limit', '100');
if (token) url.searchParams.set('next_token', token);
const res = await fetch(url, { headers: { 'x-campaign-id': campaignId } });
const body = await res.json();
yield* body.data;
token = body.meta?.pagination?.next_token;
} while (token);
}Rules for cursors
- Opaque. A
next_tokenis a base64 blob encoding our internal key position. Do not decode, construct, or modify one. - Do not persist them. They are meaningful for the duration of a traversal, not as bookmarks. Store the underlying ids instead.
- Do not log them. They can contain partition-key values.
- Send the same filters. Pass the identical
limit, headers and query filters on each page. Changing filters mid-traversal produces undefined ordering.
Endpoints that page
| Endpoint | Ordering |
|---|---|
GET /merchants | Key order — stable, not chronological |
GET /merchants/broadsearch | Relevance. Paginated only when limit is sent |
GET /merchants/search | Relevance, or distance when geo-filtering. Paginated only when limit is sent |
GET /me/fulfillment/orders | Newest first by last_mutation_date |
GET /me/loyalty/ledger/entries | Newest first |
The two search endpoints are the exception worth remembering: omit limit and they return every match in one response, with no meta.pagination block at all. Always send limit in production — an unbounded search against a large catalog is a slow response for your customer and a 504 waiting to happen.
Updated about 3 hours ago
Did this page help you?
