Tips > Building Workflows

Paginate Through APIs Without Native n8n Nodes

Many APIs that lack dedicated n8n nodes use cursor-based or offset-based pagination.

When an API has no dedicated n8n node, a single Code node can run the whole pagination loop. It calls the endpoint repeatedly -- following a cursor or incrementing an offset -- collects every page into one array, and returns all records as items. A page cap prevents infinite loops, and a short delay between requests respects rate limits.

When do you need a Code node for 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.

How do you loop through cursor-based pagination in a Code node?

// 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 }));

Why use this.helpers.httpRequest inside Code nodes?

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 · Configure Payload Size and Binary Data Mode for Large Files

Showcase builds

19 complete workflows from my own projects, each with its n8n workflow JSON to import. Showcase entries link the file at the end of the article.

See the showcase builds

Keep reading

190 entries grouped by topic, from first workflow to queue mode. Free, no signup.

Browse the encyclopedia

Need it built?

I design, build and run n8n systems for clients. Every engagement starts with a $1,500 diagnostic audit, credited toward the build.

Book an introductory call