For Loop

View as Markdown

Overview

The for expression is a foreach loop that iterates over an iterable (array/list from the data bank), binding each item to an each & index variable. It executes steps sequentially per iteration, then aggregate outputs into the output_key as a list of dicts. It is Ideal for bulk actions like user notifications.

Output Aggregation Deep Dive

The for expression outputs a clean list of objects, where one object contains the results of an iteration. An example loop with two actions,incident_manager_profile and updated_manager_profile, expect:

1"for_expression_output_result": [
2 {
3 "incident_manager_profile": { "id": "12345", "status": "INACTIVE" },
4 "updated_manager_profile": { "id": "67890", "status": "ON_CALL" }
5 },
6 {
7 "incident_manager_profile": { "id": "1a2b3c", "status": "INACTIVE" },
8 "updated_manager_profile": { "id": "4d5e6f", "status": "ON_CALL" }
9 }
10]

You can access the variables the same way you access any others in the data bank; e.g., data.for_expression_output_result[0].incident_manager_profile.status will yield INACTIVE

Low-Code Editor

Add a For Loop Step, bind iterable, define loop variables, and add expressions inside.

You can only bind an iterable in in, you cannot create a list on the fly using DSL such as ["a", "b"], only data bank variables work.

You can create a precursor script action to output a list and pass it to in .

  1. Bind the Iterable (in): Only data bank variables work, inline lists like ["a","b"] will fail.
  2. Define each & index: Set each for item (e.g., user) and index (e.g., user_index), these are only scoped to the for loop.
  3. Add expression & Set output_key: Add expressions to each step. Make sure to add readable output keys.

Syntax Reference

Schema

1for:
2 each: ITEM_VAR_NAME* # str: Current item (e.g., 'user')-scoped to steps
3 index: INDEX_VAR_NAME # str: Optional position (e.g., 'user_index')—use for ordering
4 in: DATA_BANK_ITERABLE* # str: Ref to array var (e.g., 'data.users')—no inline literals!
5 output_key: RESULTS_VAR* # str: Aggregates as list[dict] of step outputs
6 steps: # list: Expressions per iteration (optional, but useful)
7 - EXPRESSION_1 # e.g., action with {{each.record_id}}
8 - EXPRESSION_2

Fields

FieldTypeMandatoryDescription
eachstringYesitem binder - accessed as var.prop within steps
indexstringNoIndex binder - provides position (e.g., idx). Useful for ordering or referencing iteration results.
instringYesData bank reference only (upstream outputs)
output_keylist[dict]YesList of per-iteration dicts: [ {step_key: val}, ... ]. Access: data.results[i].step_key.
stepslist[expr]NoLoop body; empty yields empty dicts

Exiting a loop early

A return inside steps breaks out of the loop: the remaining iterations are skipped and the compound action ends with the data mapped in that return. Use it to stop iterating once you have found what you need, for example inside a switch case.

Practical Examples

Example 1: Actions in Batch

Run actions for each user in a list

Compound Action

1steps:
2 - action:
3 action_name: mw.batch_get_users_by_email
4 output_key: user_results
5 input_args:
6 user_emails:
7 - '"jdoe@example.com"'
8 - '"sdom@example.com"'
9 - '"jnde@example.com"'
10 - for:
11 each: user
12 index: user_index
13 in: data.user_results.user_records # From upstream fetch
14 output_key: requested_for_notifications
15 steps:
16 - action:
17 action_name: mw.send_plaintext_chat_notification
18 output_key: notification_output
19 input_args:
20 user_record_id: user.lookup_id
21 message: '''Hi, this is a batch message!'''

Expected Output

1requested_for_notifications: [
2 { "notification_output": { "status": "sent", "user": "user1" } },
3 { "notification_output": { "status": "sent", "user": "user2" } },
4 { "notification_output": { "status": "sent", "user": "user3" } }
5]

The compound actions fetches the records of the users and consequentially uses a for loop to send a message to each user.

Example 2: Outage Ticket Processing

Batch-update manager for open tickets

Sample input argument

outage_tickets: [ {"system_id": "OUT-123"}, {"system_id": "OUT-456"} ]

Compound Action

1for:
2 each: ticket
3 index: index
4 in: data.outage_tickets
5 output_key: outage_ticket_process_results
6 steps:
7 - action:
8 action_name: get_incident_manager_for_outage
9 input_args:
10 outage_id: ticket.system_id
11 output_key: incident_manager_profile
12 - action:
13 action_name: update_incident_manager_profile
14 input_args:
15 manager_id: data.incident_manager_profile.id
16 status: '''ON_CALL'''
17 output_key: updated_manager_profile

Expected Output

1outage_ticket_process_results: [
2 {
3 "incident_manager_profile": { "id": "7bd99d76-...", "status": "INACTIVE" },
4 "updated_manager_profile": { "id": "7bd99d76-...", "status": "ON_CALL" }
5 },
6 {
7 "incident_manager_profile": { "id": "839b82da-...", "status": "INACTIVE" },
8 "updated_manager_profile": { "id": "839b82da-...", "status": "ON_CALL" }
9 }
10]

The for loop iterates through each ticket, it finds the incident manager for the ticket and updates the status of the incident manager to ON_CALL