Skip to main content
forEach lets a service step execute once per row in a source table. The workflow engine handles iteration, parallelization, rate limiting, and per-item error handling — you define the source and map row values into parameters.

Basic usage

Given a source table repos with a list of repositories, this step fetches commits for each repo:
The engine iterates over every row in repos, substituting {{item.owner}} and {{item.name}} with column values from each row.

Configuration

Template variables

Use {{item.X}} to reference columns from the source table row:
{{var.X}} references workflow-level variables. Both can be used together in the same step.

Parallelism and rate limiting

To process multiple accounts concurrently while staying within API rate limits:

Error handling

By default, a single item failure stops the entire step. To continue processing remaining items when individual items fail:
With "skip", failed items are logged but don’t block the rest. The output table contains results from all successful items.

Multi-user workflows

Use runAsUser to execute each iteration with a different user’s credentials. This is the pattern for system-level workflows that aggregate data across multiple users that have different credentials configured for a service. Given a users table where each user has configured their Slack credentials, this step fetches all channels for each user using their individual credentials:
Each iteration uses the credentials of the user specified by credential_user_id. If one user’s credentials are invalid, onItemError: "skip" ensures other users are still processed. Note forEach can be combined with pagination — each forEach iteration paginates independently through all of the service call’s results.

Output

All iterations append results to a single output table just like any other workflow step result.

Validation