Repeat Node
Overview
The Repeat node executes a branch of nodes multiple times, either a fixed number of times or once for each item in an array. This is useful for batch processing, iterating over collections, or performing repetitive tasks.
When to Use
Use a Repeat node when you need to:
- Process each item in an array (e.g., send email to each user)
- Perform an action a specific number of times
- Batch process data
- Iterate over search results or API responses
- Apply transformations to multiple items
- Repeat an action until a threshold is met
Configuration
Items or Count
Number or List: Specifies how many times to repeat
- Fixed Number: Enter a number (e.g.,
5) to repeat exactly that many times - JSONPath to Array: Enter a JSONPath expression (e.g.,
$.results.fetchUsers.users) to iterate over each item in an array
Loop Body
The nodes inside the repeat branch define what happens on each iteration. You configure these by adding nodes to the repeat node’s branch in the workflow editor.
How It Works
Fixed Number Iterations
When you provide a number:
- The loop executes that many times
- Each iteration has access to the current index via
$.results.<nodeId>.iterator.current - The index starts at 0
Array Iterations
When you provide a JSONPath to an array:
- The loop executes once for each item in the array
- Each iteration has access to:
- Current index:
$.results.<nodeId>.iterator.current - Current item:
$.results.<nodeId>.iterator.item
- Current index:
- The index starts at 0
Loop Results
The repeat node collects results from all iterations:
- Results are stored as an array at
$.results.<nodeId> - Each element in the array is the result from that iteration
- You can access specific iteration results by index
Examples
Example: Fixed Number Loop
Node ID: retry
Number or List: 3
Loop Body:
makeAPICall- Attempts to call an APIcheckSuccess- Checks if the call succeeded
This will retry the API call up to 3 times.
Access iteration number:
$.results.retry.iterator.currentExample: Process Array Items
Node ID: processUsers
Number or List: $.results.fetchUsers.users
Loop Body:
enrichUserData- Adds additional data to usersendWelcomeEmail- Sends email to user
This processes each user in the users array.
Access current user:
$.results.processUsers.iterator.itemAccess current user’s email:
$.results.processUsers.iterator.item.emailAccess iteration index:
$.results.processUsers.iterator.currentExample: Batch Processing with Transformation
Node ID: transformProducts
Number or List: $.results.getProducts.items
Loop Body:
validateProduct- Validates product datacalculatePrice- Calculates final price with taxformatForExport- Formats product for export
Results:
$.results.transformProducts
// Returns array of results from each iteration:
[
{ /* results from iteration 0 */ },
{ /* results from iteration 1 */ },
{ /* results from iteration 2 */ }
]Example: Send Bulk Notifications
Node ID: notifyUsers
Number or List: $.results.getUsersToNotify.users
Loop Body:
formatMessage- Creates personalized messagesendEmail- Sends email to current user
Using current item in the loop:
- In
formatMessage, access user data:$.results.notifyUsers.iterator.item.name - In
sendEmail, access user email:$.results.notifyUsers.iterator.item.email
Example: Paginated API Calls
Node ID: fetchAllPages
Number or List: 10 (max 10 pages)
Loop Body:
calculateOffset- Function node that calculates:$.results.fetchAllPages.iterator.current * 100fetchPage- Calls API with offsetcheckHasMore- Conditional that checks if there are more pages
This fetches up to 10 pages of results, 100 items per page.
Accessing Loop Data
Iterator Object
The iterator object is available at $.results.<nodeId>.iterator:
{
"current": 2, // Current index (0-based)
"item": { }, // Current item (only when iterating over array)
"continue": true // Internal flag
}Current Item Fields
When iterating over an array of objects:
$.results.<nodeId>.iterator.item.fieldNameExample:
$.results.processOrders.iterator.item.orderId
$.results.processOrders.iterator.item.customer.emailLoop Results
Results from all iterations:
$.results.<nodeId>This is an array where each element corresponds to one iteration’s results.
Best Practices
- Limit Iterations: Set reasonable limits to avoid long-running workflows
- Error Handling: Use onFailure paths to handle errors in iterations
- Batch Size: For large arrays, consider processing in smaller batches
- Access Current Item: Use
$.results.<nodeId>.iterator.itemto access the current element - Index-Based Logic: Use
$.results.<nodeId>.iterator.currentfor index-based decisions - Collect Results: Design nodes to return useful data that can be collected across iterations
- Performance: Be aware that each iteration adds to execution time
Common Patterns
Process Array with Conditional Logic
Repeat: processItems ($.results.fetchItems.items)
├─ Conditional: checkItemType
│ ├─ Choice 1: Type A → processTypeA
│ └─ Choice 2: Type B → processTypeBRetry with Backoff
Repeat: retryOperation (3)
├─ Function: calculateDelay (current * 1000ms)
├─ makeAPICall
└─ Conditional: checkSuccess
├─ Success → End
└─ Failure → Continue to next iterationBatch Update with Progress Tracking
Repeat: updateRecords ($.results.getRecords.items)
├─ Function: logProgress
│ └─ Log "Processing {{results.updateRecords.iterator.current}} of {{results.getRecords.total}}"
├─ updateRecord
└─ Conditional: checkSuccess
├─ Success → markComplete
└─ Failure → logErrorFilter and Transform
Repeat: processOrders ($.results.fetchOrders.orders)
├─ Conditional: filterOrders
│ └─ Choice: Status = "pending"
│ ├─ validateOrder
│ ├─ calculateTotal
│ └─ submitForProcessingLimitations
- No Break: Cannot break out of a loop early (use Conditional nodes to skip processing)
- No Nested Repeat: Cannot nest repeat nodes directly within each other
- Memory: Very large arrays may hit memory limits
- Timeout: Long-running loops may hit workflow execution timeouts
- Sequential Only: Iterations execute sequentially, not in parallel (use Parallel node for concurrent execution)
Error Handling
If a node within the repeat body fails:
- The onFailure path of that node is followed (if defined)
- If no onFailure path is defined, the entire repeat node fails
- Use Conditional nodes to handle errors gracefully and continue to the next iteration