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

# Pagination

> Learn how to navigate through large result sets

## Overview

The KDP API uses cursor-based pagination for endpoints that return large collections of data. This approach provides consistent results even when data is being added or removed.

## How It Works

Paginated endpoints accept the following query parameters:

* `limit` - Number of items to return (default: 20, max: 100)
* `starting_after` - Cursor for forward pagination
* `ending_before` - Cursor for backward pagination

<Note>
  You cannot use both `starting_after` and `ending_before` in the same request.
</Note>

## Response Format

Paginated responses include a `metadata` object:

```json theme={null}
{
  "data": [...],
  "metadata": {
    "hasMore": true,
    "count": 20
  }
}
```

* `hasMore` - Indicates if there are more results available
* `count` - Number of items in the current page

## Examples

### First Page

```bash theme={null}
curl https://api.kas.fyi/addresses/kaspa:qpzpfwcsqsxhxwup26r55fd0ghqlhyugz8cp6y3wxuddc02vcxtjg75pspnwz/transactions?limit=20 \
  -H "x-api-key: YOUR_API_KEY"
```

### Next Page

Use the last item's ID from the previous response as `starting_after`:

```bash theme={null}
curl https://api.kas.fyi/addresses/kaspa:qpzpfwcsqsxhxwup26r55fd0ghqlhyugz8cp6y3wxuddc02vcxtjg75pspnwz/transactions?limit=20&starting_after=tx_abc123 \
  -H "x-api-key: YOUR_API_KEY"
```

### Previous Page

Use the first item's ID from the current page as `ending_before`:

```bash theme={null}
curl https://api.kas.fyi/addresses/kaspa:qpzpfwcsqsxhxwup26r55fd0ghqlhyugz8cp6y3wxuddc02vcxtjg75pspnwz/transactions?limit=20&ending_before=tx_xyz789 \
  -H "x-api-key: YOUR_API_KEY"
```

## Implementation Example

### TypeScript

```typescript theme={null}
async function getAllTransactions(address: string, apiKey: string) {
  const transactions = [];
  let hasMore = true;
  let cursor = null;

  while (hasMore) {
    const params = new URLSearchParams({
      limit: '100',
      ...(cursor && { starting_after: cursor })
    });

    const response = await fetch(
      `https://api.kas.fyi/addresses/${address}/transactions?${params}`,
      { headers: { 'x-api-key': apiKey } }
    );

    const data = await response.json();
    transactions.push(...data.transactions);
    
    hasMore = data.metadata.hasMore;
    if (hasMore && data.transactions.length > 0) {
      cursor = data.transactions[data.transactions.length - 1].transactionId;
    }
  }

  return transactions;
}
```

### Python

```python theme={null}
def get_all_transactions(address, api_key):
    transactions = []
    has_more = True
    cursor = None
    
    while has_more:
        params = {'limit': 100}
        if cursor:
            params['starting_after'] = cursor
        
        response = requests.get(
            f'https://api.kas.fyi/addresses/{address}/transactions',
            params=params,
            headers={'x-api-key': api_key}
        )
        
        data = response.json()
        transactions.extend(data['transactions'])
        
        has_more = data['metadata']['hasMore']
        if has_more and data['transactions']:
            cursor = data['transactions'][-1]['transactionId']
    
    return transactions
```

## Best Practices

1. **Use consistent limits**: Keep the same limit value when paginating through results
2. **Handle empty results**: Check if the data array is empty before accessing items
3. **Store cursors**: Save pagination state to resume later if needed
4. **Respect rate limits**: Add delays between requests for large datasets
5. **Use appropriate page sizes**: Balance between number of requests and response size
