---
title: "Loop Step"
description: "Repeat a set of steps for every item in a list, automating repetitive tasks inside a single agent run."
icon: "repeat"
---

The **Loop step** lets an agent process a list of items one by one — or all at once in parallel — without requiring you to run the agent multiple times. You define which steps to repeat, wire in a list as input, and the agent handles the rest automatically.

If you've ever needed to analyze five documents, send a message to ten people, or run a check on every row of a dataset, the Loop step is what makes that possible inside a single agent run.

---

## Why it matters

Without a loop, an agent handles one thing at a time. To process multiple items you would need to run the agent separately for each one, stitch results together manually, or build external orchestration logic.

The Loop step removes all of that. It keeps everything inside the agent, runs each item through the same set of steps, and hands the combined results to whatever comes next. This means:

- **Less manual work.** Repetitive tasks happen automatically, not one-by-one.
- **More dynamic behavior.** Agents can adapt to varying input sizes — two items or two hundred.
- **Cleaner design.** Logic stays inside the agent instead of being spread across external scripts or multiple agent runs.

---

## How it works

1. An earlier step produces a list — a JSON array of objects, strings, file references, or any structured data.
2. The Loop step receives that list and splits it into individual items.
3. For each item, the Loop runs every step placed inside its boundary on the canvas, passing the current item as input.
4. When all items are processed, the results are collected and made available to the steps that follow the Loop.

The steps inside the Loop can access the current item via `{{Steps.LoopStepName.CurrentItem}}` and the current index via `{{Steps.LoopStepName.CurrentIndex}}`.

---

## Set up a Loop step

### 1. Add the Loop step to the canvas

Open your agent in Agent Studio. In the step library, find **Loop** and drag it onto the canvas. An empty loop boundary — a resizable blue rectangle — appears.

Drag any steps you want to repeat inside that boundary. The Loop step will execute those steps for each item in your input list.

### 2. Connect it to an earlier step

Draw a connection from the step that produces your list into the Loop step. The Loop step expects its input to be a JSON array. If the list is nested inside a larger object, use the **Input expression** field to point to it.

**Input expression examples:**

| Scenario | Expression |
|---|---|
| The whole output is a list | Leave blank |
| List is at `results.items` | `{{Steps.PreviousStep.results.items}}` |
| List comes from a specific property | `{{Steps.FetchData.Output.records}}` |

If the input expression is left blank, the step treats the direct output of the connected step as the array.

### 3. Configure the Loop settings

Open the Loop step's settings panel on the right side of the canvas.

| Setting | Description | Default |
|---|---|---|
| **Input expression** | Expression to extract a nested array from a previous step. Leave blank to use the direct input. | — |
| **Max cycles** | Maximum number of items to process. The Loop stops after this count even if the list is longer. | 10 |
| **Stop on error** | If enabled, the Loop halts immediately when any iteration fails. If disabled, it skips failed items and continues. | Off |
| **Execution mode** | **Sequential** processes items one at a time in order. **Parallel** runs all iterations concurrently. | Sequential |

### 4. Reference the current item inside the loop

Steps inside the Loop boundary can access the current iteration's data using these variables:

| Variable | Type | Description |
|---|---|---|
| `{{Steps.LoopStepName.CurrentItem}}` | `any` | The full value of the current item in the list. |
| `{{Steps.LoopStepName.CurrentIndex}}` | `number` | The zero-based index of the current iteration (0, 1, 2…). |

If each item is an object, you can drill into its properties directly:

```
{{Steps.LoopStepName.CurrentItem.name}}
{{Steps.LoopStepName.CurrentItem.documentUrl}}
```

---

## Practical examples

### Process multiple documents one by one

**Scenario:** A OneDrive action returns a list of file paths. For each file, download its content and extract a summary.

**Setup:**

1. **OneDrive — List Files** → produces an array of file objects.
2. **Loop step** — Input expression: `{{Steps.ListFiles.Files}}`
   - Inside the loop:
     - **OneDrive — Download File** → `Path`: `{{Steps.Loop.CurrentItem.path}}`, File Return Mode: `Content`
     - **MarkItDown** → `Base64 Data`: `{{Steps.Download.FileContentBase64}}`, `MIME Type`: `{{Steps.Download.ContentType}}`
     - **AI Model** → Prompt: `Summarize this document: {{Steps.MarkItDown.MarkdownContent}}`
3. **Output step** → receives an array of summaries, one per file.

**Outcome:** Every file is downloaded, parsed, and summarized in a single agent run. The final step receives all summaries together.

---

### Run analysis on a list of inputs

**Scenario:** A form submission sends five customer feedback entries as a JSON array. The agent classifies each one as positive, neutral, or negative.

**Setup:**

1. **Input step** → receives `{"feedback": ["Great service!", "Average experience.", "Terrible wait time.", ...]}`
2. **Loop step** — Input expression: `{{Steps.Input.feedback}}`
   - Inside the loop:
     - **AI Model** → Prompt: `Classify this feedback as Positive, Neutral, or Negative. Respond with one word only.\n\n{{Steps.Loop.CurrentItem}}`
3. **Output step** → receives `["Positive", "Neutral", "Negative", ...]`

**Outcome:** Each feedback entry is classified individually, and the results arrive as an array in the same order as the input.

---

### Trigger an action for each item in a dataset

**Scenario:** An agent receives a list of user IDs and needs to call an external API for each one to fetch their account status.

**Setup:**

1. **Input step** → receives `{"userIds": ["u_001", "u_002", "u_003"]}`
2. **Loop step** — Input expression: `{{Steps.Input.userIds}}`
   - Inside the loop:
     - **HTTP Request** → URL: `https://api.internal.com/users/{{Steps.Loop.CurrentItem}}/status`, Method: `GET`
3. **Output step** → receives an array of API responses, one per user.

**Outcome:** The agent makes one API call per user ID and aggregates all responses without any external orchestration.

---

## How results are handled

After all iterations complete, the Loop step produces an **array of outputs** — one entry per iteration, in the order they were processed (Sequential mode preserves order; Parallel mode does not guarantee order).

Downstream steps receive this array as the Loop step's output and can reference it like any other step output:

```
{{Steps.LoopStepName.Output}}
```

If you need to work with the aggregated results — joining them into a single string, filtering, or restructuring — add an AI Model step or a Code step after the Loop to transform the array before passing it forward.

---

## Best practices

**Keep your input list structured.** The Loop step works best when every item in the list has the same shape. If items have inconsistent properties, add a data normalization step before the Loop to standardize them.

**Set a realistic Max cycles limit.** The default is 10. If your list can grow large, raise the limit explicitly — but be mindful that each iteration consumes time and resources. Very large loops can make an agent run slow or hit timeout limits.

**Prefer Sequential for dependent tasks.** If each iteration's result depends on the previous one, always use Sequential mode. Parallel mode runs iterations simultaneously and will not wait for earlier results.

**Use Parallel mode for independent, fast tasks.** Parallel is ideal for HTTP lookups, simple classifications, or any task where each iteration is self-contained and speed matters.

**Avoid passing very large documents through the loop.** If each iteration processes a long document and passes it to an AI model, context window limits can become a problem. Consider summarizing or chunking documents before they enter the Loop.

---

## Common pitfalls

**Passing a non-array as input.** The Loop step expects a JSON array. If the connected step returns a single object or a string, the Loop will fail at runtime. Use the Input expression field to extract the array, or add a step before the Loop to wrap the value in an array.

**Expecting a single combined output.** Each iteration produces its own output. The Loop does not merge or concatenate results automatically — it produces an array. If you need a single string or object, use a step after the Loop to combine the array.

**Setting Max cycles too low.** If the list has more items than the Max cycles limit, the Loop stops early and silently drops the remaining items. Always check that the limit matches the expected size of your input list.

**Not accounting for failed iterations.** With **Stop on error** disabled (the default), the Loop continues past failed iterations and includes `null` or error entries in the output array. Add error handling downstream if your agent needs to distinguish successful from failed iterations.

**Using Parallel mode when order matters.** Parallel runs do not guarantee output order. If downstream logic depends on results being in the same order as the input list, use Sequential mode.

---

## Summary

The Loop step is the right tool whenever an agent needs to apply the same logic to multiple items — documents, records, IDs, feedback entries, or anything else that arrives as a list. It replaces the need to run an agent multiple times, keeps processing logic in one place, and produces a clean array of results that downstream steps can act on immediately.

Add a Loop step when your input can vary in size, when the same steps need to run more than once, or when you want to avoid building external orchestration around your agent.
