Skip to main content

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
You cannot use both starting_after and ending_before in the same request.

Response Format

Paginated responses include a metadata object:
{
  "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

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:
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:
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

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

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
⌘I