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.
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;
}
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
- Use consistent limits: Keep the same limit value when paginating through results
- Handle empty results: Check if the data array is empty before accessing items
- Store cursors: Save pagination state to resume later if needed
- Respect rate limits: Add delays between requests for large datasets
- Use appropriate page sizes: Balance between number of requests and response size