Many APIs that lack dedicated n8n nodes use cursor-based or offset-based pagination.
Many APIs that lack dedicated n8n nodes use cursor-based or offset-based pagination. A Code node can handle the entire pagination loop, returning all pages as a single batch of items.
Real-world example: Fetching all records from a custom REST API that returns 100 items per page with a nextCursor field.
// Mode: Run Once for All Items
const baseUrl = 'https://api.example.com/v1/records';
const apiKey = $input.first().json.apiKey; // Or use credential expressions
const allRecords = [];
let cursor = null;
let page = 0;
const maxPages = 50; // Safety limit to prevent infinite loops
do {
const url = cursor
? `${baseUrl}?limit=100&cursor=${encodeURIComponent(cursor)}`
: `${baseUrl}?limit=100`;
const response = await this.helpers.httpRequest({
method: 'GET',
url,
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
});
if (response.data && Array.isArray(response.data)) {
allRecords.push(...response.data);
}
cursor = response.pagination?.nextCursor ?? null;
page++;
// Respect rate limits
if (cursor) {
await new Promise(resolve => setTimeout(resolve, 200));
}
} while (cursor && page < maxPages);
return allRecords.map(record => ({ json: record }));
```text
> **Tip: Use `this.helpers.httpRequest`**
>
> Inside Code nodes, `this.helpers.httpRequest` is the preferred way to make HTTP calls. It respects n8n's proxy settings and has built-in retry logic. Avoid `fetch()` or `axios` unless you have a specific reason.
**Related:** [Use Edit Fields in "Map Each" Mode for Simple Renames](../data-transformation/01-use-edit-fields-in-map-each-mode-for-simple-renames.md) | [Configure Payload Size and Binary Data Mode for Large Files](../performance-and-large-files/01-configure-payload-size-and-binary-data-mode-for-large-files.md)
I build production n8n and Cloudflare automation for teams — the same engineering behind HarperFlow. Fixed-price, escrow-protected, US-based.