Tutorials

How to Loop Through a Paginated REST API in Retool Workflows

OTC Team··4 min read
How to Loop Through a Paginated REST API in Retool Workflows

If you've ever tried to loop through a paginated REST API in a Retool workflow, you've probably hit the same wall: Retool doesn't have a native "while loop" block, and most forum solutions involve stitching together two separate workflows with different triggers. There's a cleaner way — a single recursive workflow that calls itself until the API runs out of pages. Here's exactly how to build it.

Why Pagination Is Tricky in Retool Workflows

Most REST APIs don't return all their data in one response. They return a page of results plus a token — often called a nextPageToken, skipToken, or nextLink — that you pass back in the next request to get the following page. To fetch everything, you need to keep calling the API until that token disappears.

In traditional code, you'd use a while loop. In Retool Workflows, the cleanest equivalent is recursion: a workflow that triggers itself as a child workflow, passing the next page token as a parameter each time. No webhook trigger required. No second workflow to maintain.

How the Recursive Workflow Pattern Works

The logic is straightforward once you see it laid out. Here's the high-level flow:

  • Step 1 — Initial API call: Make a REST API request. On the first run, no page token is passed (or you pass an empty default).
  • Step 2 — Check the response: Use a Code block or Branch block to inspect the result. Ask two questions: Did the API return any items? Is there a nextPageToken in the response?
  • Step 3 — Process the data: Upsert or write the returned records to your Retool Database, a connected Postgres table, or wherever you're storing results.
  • Step 4 — Recurse or stop: If a nextPageToken exists, trigger the same workflow as a child workflow, passing the token as a parameter. If there's no token (or no items returned), the workflow ends naturally.

The stopping condition is built into the data itself — when the API returns an empty page or no next token, the recursion simply doesn't continue. No extra termination logic needed.

Setting Up the Recursive Step in Retool

The key block is the one that makes the workflow call itself. In the Retool Workflow editor, add a Workflow block (the block type that runs another workflow). Point it at the current workflow, then pass the next page token as a dynamic parameter.

For a Google API response, your parameter setup in the recursive block would look like this:

  • Parameter name: pageToken
  • Parameter value: {{ getUserList.data.nextPageToken }}

For Microsoft Graph API, the pattern is nearly identical but uses @odata.nextLink or a $skipToken extracted from that URL. Your first API request block should accept skipToken as an input parameter, defaulting to an empty string when the workflow is first triggered.

The full block sequence in your workflow should look something like:

  • startTrigger — accepts optional pageToken parameter
  • getUsers — REST API block, passes pageToken into the query parameter
  • upsertRecords — writes results to your database
  • checkNextPage — Branch block: routes to getNextPage if token exists, routes to endWorkflow if not
  • getNextPage — Workflow block that calls this same workflow with {{ getUsers.data.nextPageToken }}

Common Reason the Child Workflow Won't Trigger

A frequent issue reported by Retool users is the child workflow firing only once and then stopping. The most common cause: missing Response blocks on each branch of your workflow. Retool requires every execution path in a workflow to terminate with a Response block. If a branch is missing one, the workflow may silently fail before it reaches the recursive step.

Check every branch — including your "no more pages" exit path — and make sure each one ends with a Response block. This is the fix for most cases where recursion appears to stop after the first child call.

When to Run This Workflow

Once built, this pattern is flexible. You can trigger the workflow in several ways:

  • Scheduled: Run it nightly to keep a local database table in sync with an external API
  • On app load: Trigger it asynchronously so your dashboard data is fresh without blocking the UI
  • On demand: Wire it to a Refresh button in your Retool app so users can pull the latest data manually

The core benefit is that once all pages are fetched and stored locally, your dashboard queries run against a fast local table — not against the external API on every load. For APIs with thousands of records spread across dozens of pages, this is a significant performance win.

Key Takeaways

  • Use a single Retool Workflow with a self-referencing Workflow block to handle paginated REST APIs — no second workflow or webhook needed.
  • Pass the nextPageToken (or equivalent) as a parameter into the recursive call using {{ queryName.data.nextPageToken }}.
  • The recursion stops automatically when the API returns no token — no manual termination logic required.
  • If your child workflow refuses to trigger more than once, check that every branch has a Response block.
  • This pattern works with any token-based pagination API: Google APIs, Microsoft Graph, and most modern REST services.

This is one of those Retool patterns that feels almost too simple once it clicks. If you're building internal tools that sync data from external APIs, the recursive single-workflow approach will save you a lot of maintenance overhead compared to multi-workflow setups.

Ready to build?

We scope, design, and ship your Retool app — fast.

Ready to ship your first tool?