Pagination
Some endpoints return large result sets that are paginated using cursor-based pagination. This is more reliable than offset-based pagination for real-time blockchain data where new entries appear constantly.
How it Works
Paginated responses include these fields:
| Field | Type | Description |
|---|---|---|
count | integer | Number of items in the current page |
limit | integer | Maximum items per page |
hasMore | boolean | true if more results exist beyond this page |
cursor | string | null | Opaque token to fetch the next page. null if no more pages. |
Paginated Endpoints
| Endpoint | Description |
|---|---|
| getLogs | Event logs filtered by address, topic, block range |
| getTransfers | ERC-20 transfer events for an address |
Basic Usage
JSON-RPC
{
"jsonrpc": "2.0",
"method": "getLogs",
"params": {
"chain": "ethereum",
"address": "0xA0b8...",
"cursor": "19000500"
},
"id": 1
}SDK
import { Spectrum } from '@spectrum-nodes/sdk';
const spectrum = new Spectrum({ api: 'https://your-endpoint.simplystaking.xyz/YOUR_API_KEY/' });
// Paginate through all logs
let cursor: string | undefined;
const allLogs = [];
do {
const page = await spectrum.data.getLogs('ethereum', {
address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
fromBlock: 19000000,
cursor,
});
allLogs.push(...page.logs);
cursor = page.cursor ?? undefined;
console.log(`Fetched ${page.count} logs (total: ${allLogs.length}, hasMore: ${page.hasMore})`);
} while (cursor);
console.log(`Done. ${allLogs.length} total logs.`);Behavior
- Cursor value is a block number string. It represents the starting point for the next page.
- Page size is fixed at 1,000 items per page (the
limitfield). - Block range: if you don’t specify
fromBlock, the API defaults to the last 10,000 blocks. Always specifyfromBlockfor deterministic pagination. - Ordering: logs are returned in ascending block order within each page.
- No cursor = first page: omit the
cursorparameter for the initial request. - cursor = null in response means you’ve reached the end.
Tips
- Always check
hasMorebefore making the next request. - Store the
cursorvalue if you need to resume pagination later. - For large historical scans, use a narrow block range (
fromBlocktotoBlock) to control the window size. - The cursor is opaque - don’t parse or modify it. Pass it back exactly as received.