# Pagination

> Lists come a page at a time, newest first, with a cursor to the next page.

Source: https://useroutegate.com/docs/concepts/pagination

[`GET /api/v1/transactions`](/docs/api/public/listPublicTransactions) returns the key's transactions a page at a time, newest first. The catalogue and pricing lists are short and come back whole, with no `page`.

## Parameters

| Parameter | Value                                                                      |
| --------- | -------------------------------------------------------------------------- |
| `limit`   | Items per page, 1 to 100. Default 25. A larger number is treated as 100.   |
| `cursor`  | The `next_cursor` from the previous page. Leave it out for the first page. |

Keep every filter the same from page to page (`status`, `network`, `service`, `destination`, `from`, `to`, `search`); only `cursor` changes.

## Response

```json
{
  "success": true,
  "code": "OK",
  "message": "OK",
  "data": {
    "items": [{ "reference": "txn_01a0d8dfa6b87d10a3e54c2b9f86d1e4", "status": "successful" }],
    "page": {
      "next_cursor": "MTc5MDM0NDkzMTAwMDAwMDAwMC4wMWEwZDhkZi1hNmI4LTdjM2UtOWYyMS00YjZkOGUwYTJjNTc",
      "has_more": true
    }
  }
}
```

`has_more` is `true` while another page exists, and `next_cursor` is `null` on the last page. Each item is a full transaction, cut down to two fields here. A cursor is opaque: pass it back exactly as you received it. A malformed one is refused with `400 VALIDATION_FAILED` on the `cursor` field.

## Reading every page

```javascript
async function allTransactions(query = {}) {
  const items = [];
  let cursor;
  do {
    const params = new URLSearchParams({ ...query, limit: "100", ...(cursor && { cursor }) });
    const response = await fetch(`https://api.useroutegate.com/api/v1/transactions?${params}`, {
      headers: { Authorization: `Bearer ${process.env.ROUTEGATE_API_KEY}` },
    });
    const { data } = await response.json();
    items.push(...data.items);
    cursor = data.page.has_more ? data.page.next_cursor : undefined;
  } while (cursor);
  return items;
}
```
