# Subprocesses

> A subprocess is a collection of other tasks and subprocesses that helps to split a complex process into more manageable and navigable parts.
:::note
* Opt for a Call activity when you need to use an additional process either within the same project or from a separate project. Such an agentic process, with an independent value, can be invoked either as a self-contained process or by other processes, triggering the creation of a new instance automatically. 
* Use a subprocess when there's a requirement to encapsulate specific logic, thereby augmenting the parent process's simplicity. As an inherent part of the same instance, the subprocess contributes to streamlining the overall orchestration.
:::

## Overview

A subprocess is a collection of other tasks and subprocesses that helps to split a complex process into more manageable and navigable parts.
:::note
* Opt for a Call activity when you need to use an additional process either within the same project or from a separate project. Such an agentic process, with an independent value, can be invoked either as a self-contained process or by other processes, triggering the creation of a new instance automatically. 
* Use a subprocess when there's a requirement to encapsulate specific logic, thereby augmenting the parent process's simplicity. As an inherent part of the same instance, the subprocess contributes to streamlining the overall orchestration.
:::

Refer to [Process Modeling](https://docs.uipath.com/maestro/automation-suite/2.2510/user-guide/understanding-process-modeling) for additional details on BPMN support.

![multi instance subprocess](https://dev-assets.cms.uipath.com/assets/images/maestro/maestro-multi-instance-subprocess-554950-8bcd931c.webp)

## Passing and accessing variables between subprocesses

Subprocesses encapsulate reusable logic, but they often need to exchange data with the parent process or other subprocesses. Maestro provides clear rules for how variables are scoped and passed so that your data remains consistent across levels.

![BPMN Workflow - InputOutput variables](https://dev-assets.cms.uipath.com/assets/images/maestro/maestro-bpmn-workflow-inputoutput-variables-587317-44386bfb.webp)

## Accessing inputs within a subprocess

To access the output of a previous activity within the same subprocess, no additional configuration is required.

**Example**: If activity `foo` sets an output variable called `foo_op`, and a subsequent activity `bar` exists in the same subprocess, `bar` can reference `foo_op` directly.

**Key rule**: Variables defined in an activity are accessible to any downstream activity within the same subprocess, including nested elements. You do **not** need to pass them explicitly as subprocess inputs.

## Exposing outputs from a subprocess

When a parent process needs access to output data from an activity inside a nested subprocess, you can expose that data using one of two approaches.

**Approach 1: Using Output Variables**

1. In the inner subprocess, define an output variable—for example, `inner_sp_op`—and assign it the value of the internal activity's output (`bar_op`).
2. In the outer subprocess (or parent process), define another output variable—for example, `outer_sp_op`—and assign it the value of the inner subprocess output (`inner_sp_op`).
3. Downstream activities (e.g., `qux`) in the parent process can now reference `outer_sp_op`.

**Approach 2: Using End Event Variables**

1. In the inner subprocess, configure the **end event** to declare an output variable such as `ee_inner_op`, and assign it the value of `bar_op`.
2. In the outer subprocess, configure the corresponding end event to declare an output variable such as `ee_outer_op`, and assign it the value of `ee_inner_op`.
3. Activity `qux` in the parent process can now reference `ee_outer_op`.

   :::tip
   End event variables automatically propagate to the parent scope without needing separate output variable configuration.
   :::

   ## Inspecting subprocess variables

You can inspect variable values at design time (via the **debug API**) or runtime (via the **instance API**) to verify scoping and data propagation.

Debug API - View variables

```
GET /v1/debug-instances/{instanceId}/variables?parentElementId=outer_subprocess
```

**Available variables:**

* `foo_op`
* `inner_subprocess_op`
* `ee_outer_op`

```
GET /v1/debug-instances/{instanceId}/variables?parentElementId=inner_subprocess
```

**Available variables**:

* `bar_op`
* `ee_inner_op`

**Runtime API – View variables**

```
GET /v1/instances/{instanceId}/variables?parentElementId=outer_subprocess
```

**Available variables**:

* `foo_op`
* `inner_subprocess_op`
* `ee_outer_op`

```
GET /v1/instances/{instanceId}/variables?parentElementId=inner_subprocess
```

**Available variables**:

* `bar_op`
* `ee_inner_op`

## Multi-instance markers

Subprocesses support multi-instance markers, where each element is executed multiple times. The elements that can be marked as multi-instance are all task types except for subprocesses.

## Nested markers

The following string variables string are supported as nested iterators:

| Category | Attributes | How to use/access |
| --- | --- | --- |
| **OuterSP** - Get Contact Information for each user | InputCollection | var.GetUsers |
| **OuterSP** - Get Contact Information for each user | Iterator Item | iterator.item.gid |
| **InnerSP** - Get all emails for each contact | InputCollection | iterator[0].item.contactArray |
| **InnerSP** - Get all emails for each contact | Iterator Item | iterator[1].item.ContactId |
| **Send Email** | InputCollection | iterator[1].item.EmailArray |
| **Send Email** | Iterator Item | iterator[2]item.emailAddress |
