> ## Documentation Index
> Fetch the complete documentation index at: https://nexus.gerowallet.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Pagination

> Working with paginated responses in the Gero Nexus API

Many Gero Nexus endpoints return lists of items in pages. This guide explains the pagination parameters and how to iterate through all results.

## Pagination Parameters

List endpoints accept two query parameters:

| Parameter  | Type    | Default | Description            |
| ---------- | ------- | ------- | ---------------------- |
| `page`     | integer | `1`     | Page number (1-based)  |
| `pageSize` | integer | `100`   | Items per page (1–100) |

<Note>
  A few endpoints use a different default `pageSize` (for example, address transaction history
  defaults to `20`). The maximum is always `100`. Check the endpoint's page in the
  [API Reference](/docs/api-reference) for its exact defaults and any endpoint-specific filters
  (some endpoints add their own parameters, e.g. DReps accept a `sort`).
</Note>

## Request Examples

```bash theme={null}
# Page 1 with 100 items (defaults)
curl "https://nexus.gerowallet.io/api/blocks" \
  -H "X-Api-Key: nxs_your_api_key_here"

# Page 3 with 50 items
curl "https://nexus.gerowallet.io/api/blocks?page=3&pageSize=50" \
  -H "X-Api-Key: nxs_your_api_key_here"
```

## Detecting the Last Page

Paginated endpoints come in **two response shapes** — check the endpoint's
[API Reference](/docs/api-reference) page for which it uses. Neither sends pagination-metadata response
*headers*.

**Bare array** (e.g. `/api/blocks`, `/api/addresses/{address}/utxos`). No metadata in the body —
keep requesting pages until you receive **fewer items than your `pageSize`** (or an empty array).
That page is the last one.

```http theme={null}
HTTP/1.1 200 OK
Content-Type: application/json

[ { ... }, { ... }, ... ]
```

**Wrapper object** (e.g. `/api/addresses/{address}/transactions/history`). Items are nested under
a key, alongside a `pagination` block — stop when `pagination.hasNext` is `false`.

```http theme={null}
HTTP/1.1 200 OK
Content-Type: application/json

{ "transactions": [ ... ], "pagination": { "page": 1, "pageSize": 20, "totalItems": 25, "totalPages": 2, "hasNext": true, "hasPrevious": false } }
```

## Iterating Through All Pages

The helpers below are for **bare-array** endpoints (they stop on a short page). For a **wrapper**
endpoint, loop while `pagination.hasNext` is `true` — see the wrapper example below.

### Bare-array endpoints — JavaScript/TypeScript

```javascript theme={null}
async function fetchAll(endpoint, pageSize = 100) {
  const items = [];
  let page = 1;

  while (true) {
    const url = new URL(`https://nexus.gerowallet.io${endpoint}`);
    url.searchParams.set('page', page);
    url.searchParams.set('pageSize', pageSize);

    const response = await fetch(url, {
      headers: { 'X-Api-Key': process.env.NEXUS_API_KEY }
    });
    if (!response.ok) throw new Error(`HTTP ${response.status}`);

    const batch = await response.json();
    items.push(...batch);

    // Short (or empty) page → we've reached the end.
    if (batch.length < pageSize) break;

    page++;
    await new Promise((r) => setTimeout(r, 100)); // be gentle on rate limits
  }

  return items;
}

const allBlocks = await fetchAll('/api/blocks');
console.log(`Fetched ${allBlocks.length} blocks`);
```

### Bare-array endpoints — Python

```python theme={null}
import os
import time
import requests

BASE = 'https://nexus.gerowallet.io'
HEADERS = {'X-Api-Key': os.environ['NEXUS_API_KEY']}


def fetch_all(endpoint, page_size=100):
    items = []
    page = 1

    while True:
        response = requests.get(
            f'{BASE}{endpoint}',
            params={'page': page, 'pageSize': page_size},
            headers=HEADERS,
        )
        response.raise_for_status()

        batch = response.json()
        items.extend(batch)

        # Short (or empty) page → end of results.
        if len(batch) < page_size:
            break

        page += 1
        time.sleep(0.1)  # be gentle on rate limits

    return items


all_blocks = fetch_all('/api/blocks')
print(f'Fetched {len(all_blocks)} blocks')
```

### Wrapper endpoints

For a `{ items, pagination }` endpoint, loop while `pagination.hasNext`:

```javascript theme={null}
async function fetchAllWrapped(endpoint, itemsKey, pageSize = 100) {
  const items = [];
  let page = 1;

  while (true) {
    const url = new URL(`https://nexus.gerowallet.io${endpoint}`);
    url.searchParams.set('page', page);
    url.searchParams.set('pageSize', pageSize);

    const res = await fetch(url, { headers: { 'X-Api-Key': process.env.NEXUS_API_KEY } });
    if (!res.ok) throw new Error(`HTTP ${res.status}`);

    const body = await res.json();
    items.push(...body[itemsKey]);

    if (!body.pagination || !body.pagination.hasNext) break;
    page++;
  }

  return items;
}

// e.g. transaction history:
// await fetchAllWrapped('/api/addresses/<addr>/transactions/history', 'transactions');
```

## Best Practices

<AccordionGroup>
  <Accordion title="Choose an appropriate page size" icon="ruler">
    * Use smaller pages (20–50) for interactive UIs that need a fast first response
    * Use the maximum (100) for batch processing to minimize round trips
  </Accordion>

  <Accordion title="Respect rate limits" icon="gauge">
    Add a small delay between page requests so a deep backfill doesn't trip the per-second
    limit. See [Rate Limits](/docs/concepts/rate-limits).
  </Accordion>

  <Accordion title="Cache when possible" icon="database">
    Cache slow-changing paginated data (block, tx, and asset metadata) to cut request volume
    against your monthly quota.
  </Accordion>
</AccordionGroup>

## Endpoints Supporting Pagination

A representative (non-exhaustive) set of `page`/`pageSize` endpoints and their response shape:

| Endpoint                                        | Default `pageSize` | Response shape                         |
| ----------------------------------------------- | ------------------ | -------------------------------------- |
| `/api/blocks`                                   | 100                | bare array                             |
| `/api/addresses/{address}/utxos`                | 100                | bare array                             |
| `/api/addresses/{address}/transactions/history` | 20                 | `{ transactions, pagination }` wrapper |

<Note>
  Not every list endpoint paginates this way. Some return the full set in one response (e.g.
  `/api/pools`), and some use a different cursor instead of `page`/`pageSize` (e.g.
  `/api/account/{stakeAddress}/txs` takes a required `from` block-height parameter). Always check
  the endpoint's [API Reference](/docs/api-reference) page for its exact parameters and response shape.
</Note>

## Next Steps

<CardGroup cols={2}>
  <Card title="Rate Limits" icon="gauge" href="/docs/concepts/rate-limits">
    Understand rate limiting and quotas
  </Card>

  <Card title="Error Handling" icon="triangle-exclamation" href="/docs/concepts/error-handling">
    Learn how to handle API errors
  </Card>

  <Card title="Authentication" icon="key" href="/docs/authentication">
    Learn about API authentication
  </Card>

  <Card title="API Reference" icon="book" href="/docs/api-reference">
    Explore all available endpoints
  </Card>
</CardGroup>
