> ## Documentation Index
> Fetch the complete documentation index at: https://docs.knoxcall.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Sub-workflows

> Call one workflow from another as a step — wait for its output or start it and carry on — with depth and fan-out limits and loops refused before they run.

# Sub-workflows

A large automation does not have to be one large canvas. The **Call Workflow** step runs
another of your workflows as a step, so the pieces you keep re-drawing — notify the
customer, reconcile the order, escalate to a human — become one workflow each, written
once and called from everywhere.

## Adding the step

Drop **Call Workflow** onto the canvas and pick the workflow to run. The picker offers
your workspace's workflows in the mode you are currently in, and nothing else: a Live run
can only call a Live workflow, a Test run only a Test one. The called workflow must be
turned on: a workflow that is off is listed as *Disabled — not callable*, and choosing it
is refused when you publish and again at run time, because turning a workflow off has to
stop it everywhere.

| Field        | What it does                                                                                     |
| ------------ | ------------------------------------------------------------------------------------------------ |
| **Workflow** | The workflow to run. Chosen from the list, not typed.                                            |
| **Input**    | The JSON the called workflow receives as its trigger payload. Supports `{{variables}}`.          |
| **Mode**     | *Wait for it to finish*, or *Start it and continue*.                                             |
| **Timeout**  | Wait mode only: how long before this step gives up. 5 seconds to 24 hours; 5 minutes by default. |

The called workflow reads what you map in **Input** as `{{trigger.<field>}}`. Nothing is
forwarded automatically — what the child sees is always something you wrote, which is
what stops an upstream payload leaking into a workflow that was not expecting it.

## Waiting, without holding anything up

In **wait** mode your run pauses until the called workflow finishes, then continues with
its output:

```
{{steps.call-1.output.invoiceId}}
```

The pause is durable, not a held connection. Your run is checkpointed and set aside; it
comes back when the called run finishes. A workflow that waits two hours for a called
workflow costs nothing while it waits, and it survives a restart.

The step's output carries:

| Field         |                                                                                     |
| ------------- | ----------------------------------------------------------------------------------- |
| `executionId` | The run that was started. The run log links straight to it.                         |
| `status`      | `completed` in wait mode, `queued` when you started it and carried on.              |
| `output`      | The called workflow's own output — only its output, never its steps or its secrets. |
| `durationMs`  | How long the called run took.                                                       |

In **start and continue** mode the step returns the new run's id immediately and your run
moves on. Use it for work whose result you do not need: a notification, an audit write, a
slow batch you will check on later.

## When the called workflow fails

A failed called run fails the step, with the child's error attached — so everything you
already use for a failing step works here too: **Retry**, **Continue**, the **error
branch**, or a wired **Error Handler**. A retry starts a fresh run rather than re-reading
the failed one.

A **timeout** fails the step and leaves the called run going. It is a real run that has
made real calls, and stopping it is your decision — open it from the run log and cancel it
if that is what you want.

## The limits, and why they are there

<Warning>
  Every one of these refuses the step rather than quietly doing something else.
</Warning>

* **Depth 5.** A workflow may be called from a workflow that was called from a workflow,
  five levels deep. Past that the step fails, naming the limit.
* **100 called runs per run.** One run may start at most a hundred called runs. If you
  need to process a thousand records, put the loop *inside* the called workflow rather
  than calling it once per record.
* **No loops.** A workflow may not call itself, directly or through a chain that comes
  back to it. This is refused when you publish — the builder tells you which step — and
  refused again at run time, in case the other workflow changed after you published.
* **Your workspace, your mode.** A call never crosses into another workspace, and never
  between Live and Test.
* **The called workflow is on.** A disabled workflow is not callable — the same switch
  that stops its own triggers stops it being called.

Called runs are ordinary runs: they appear in your run history with a trigger of
*sub-workflow*, they count once against your monthly operations, and each one has its own
step log. The step that called them counts once, as a control step — nothing is billed
twice.

## Seeing what happened

The called run appears in the run history like any other, and the run log's entry for the
**Call Workflow** step links directly to it. Open it to see the child's own steps, its
input and its output.
