Skip to content

This guide shows you two ways to connect flows. A flow trigger starts a flow when another flow ends. A subflow task runs a flow as one step of another flow and can wait for its result.

Flow trigger Subflow task
Declared in The downstream flow. The parent flow.
The upstream flow knows about the other flow No. Yes.
Starts when The upstream execution ends in a listed state. The task starts.
Data passes through trigger.outputs of the upstream execution. inputs of the task, and the outputs of the child.
The parent waits Not applicable. With wait: true, the default.
Cancel Separate executions. A cancel of the parent cancels a running child.

Use a flow trigger when the downstream flow belongs to another team, or when several flows react to one flow. Use a subflow task when the child is a step of a larger process and the parent needs its result.

Add a trigger of type flow to the downstream flow. flow names the upstream flow as <namespace>/<flow_id>. states lists the end states that fire the trigger.

id: weekly-report
inputs:
- { id: orders, type: int, default: 0 }
triggers:
- id: after-load
type: flow
flow: sales/nightly-load
states: [SUCCESS]
inputs: { orders: "${{ trigger.outputs.orders }}" }
tasks:
- id: render
type: command
command: ["echo", "report for ${{ inputs.orders }} orders"]

When an execution of sales/nightly-load ends SUCCESS, Sluice starts weekly-report. The trigger type of the new execution is flow.

Field Rule
flow The upstream flow. Validation checks only the format, so the upstream flow can be in another namespace or not exist yet.
states Any of SUCCESS, FAILED, TIMED_OUT and CANCELLED. Without states, the trigger fires on every end state.
inputs Templates over trigger.execution_id, trigger.state, trigger.outputs and trigger.flow.

trigger.outputs holds the flow outputs of the upstream execution. Sluice renders flow outputs only when an execution succeeds. After another end state, trigger.outputs is empty, and a template that reads a key from it fails. Pass data between tasks shows how to declare flow outputs.

A flow trigger on FAILED and TIMED_OUT turns one flow into the alert of another:

id: load-alert
inputs:
- { id: failed_execution, type: string, required: true }
- { id: state, type: string, required: true }
triggers:
- id: on-failure
type: flow
flow: sales/nightly-load
states: [FAILED, TIMED_OUT]
inputs:
failed_execution: "${{ trigger.execution_id }}"
state: "${{ trigger.state }}"
tasks:
- id: post
type: http
method: POST
url: ${{ vars.ALERT_URL }}
headers: { Authorization: "Bearer ${{ secret('ALERT_TOKEN') }}" }
body: '{"text": "nightly-load ${{ inputs.state }}: ${{ inputs.failed_execution }}"}'

Sluice fires flow triggers in the transaction that ends the upstream execution. The downstream flow must be valid and enabled. When the downstream execution cannot start, for example because an input fails its check, Sluice writes the audit event trigger.failed. The upstream execution ends as normal. Admins read audit events on Settings → Audit log.

A subflow task starts another flow as a child execution.

id: month-end
tasks:
- id: load
type: subflow
flow: sales/nightly-load
inputs: { run_date: "2026-09-30" }
- id: close
type: command
depends_on: [load]
command: ["echo", "closed with ${{ tasks.load.outputs.orders }} orders"]
Field Rule
flow The child flow as <namespace>/<flow_id>. No templates. Required.
inputs Templates for the inputs of the child. Sluice checks them against the input types of the child when the task starts.
wait Default true.

The child flow must be valid. The Enabled switch of the child does not apply to subflow tasks.

The task stays RUNNING until the child ends. When the child ends SUCCESS, the task succeeds, and its outputs are the flow outputs of the child. When the child ends in another state, the task fails with reason child_failed. A cancel of the parent cancels the child.

The child execution shows Parent execution on its page, and the parent shows Child executions. The selected subflow task links to its child. The trigger payload of the child holds parent_execution_id and parent_task.

A child that fails to start fails the task. A bad input gives reason template_error, and an invalid or missing child flow gives executor_error.

Each execution has a chain_depth. A manual, schedule or webhook execution has depth 0. An execution from a flow trigger or a subflow task has the depth of its source plus 1.

Case Limit Result above the limit
Flow trigger Depth 10 The trigger does not fire. Sluice writes the audit event trigger.chain_depth_exceeded.
Subflow task Depth 10 The task fails with reason depth_exceeded.

Flow triggers and subflows share the count. Thus a loop, for example flow A triggers flow B and B triggers A, stops after 11 executions.