This page was written for advanced builders who want to review and edit workflows in code.
Overview
Workflows in Tracecat are defined as YAML workflow definitions.Workflow schema
The workflow body uses these top-level fields:Top-level fields
Workflow name.
Workflow description.
Input schema. Use
expects to define trigger inputs in the workflow definition.Workflow settings. Supported fields are
environment and timeout.Optional trigger definitions. Trigger types are
webhook and schedule.Workflow alias to run when the workflow fails.
Workflow actions.
Output schema. Use
returns to define the workflow output in the workflow definition.Actions schema
Unique action identifier. It must be unique within the workflow and match Tracecat’s slug format.
Fully qualified action name such as
core.http_request, core.transform.reshape, core.transform.scatter, core.loop.end, or tools.slack.post_message.Action inputs. The valid keys depend on the action type.
Dependencies for this action.Use
upstream_ref for a success edge, upstream_ref.success for an explicit success edge, and upstream_ref.error for an error edge. Any other suffix is invalid.Conditional expression. If it evaluates to a falsy value, the action is skipped.
Run the action once per item in a collection. Inside the action, access the current item through
var.<name>.
Example: for_each: ${{ for var.alert in TRIGGER.alerts }}.Retry configuration with
max_attempts and timeout.Delay in seconds before the action starts.
Join behavior for downstream actions. Use
all to wait for all upstream branches, or any to allow a downstream join to complete once any upstream branch completes.Per-action override for the secrets environment.
Marks an action as interactive.
interaction cannot be combined with for_each.Expressions
Expressions use${{ ... }}.
Use these references inside expressions:
TRIGGER.<field>ACTIONS.<ref>.resultSECRETS.<name>.<KEY>VARS.<name>.<key>ENV.<field>var.<name>FN.<name>(...)
Control-flow primitives
Conditional execution with run_if
Scatter and gather
Usecore.transform.scatter to fan out a collection into parallel streams, then core.transform.gather to collect results back into a list.
ACTIONS.<scatter_ref>.result.
Do-while loops
Usecore.loop.start to open a loop region and core.loop.end to decide whether to continue.
core.loop.startexposesACTIONS.<loop_start_ref>.result.iterationcore.loop.endrequiresconditionmax_iterationsdefaults to100
Subflows
Usecore.workflow.execute to run a subflow.
workflow_id. Trigger data is passed through trigger_inputs.
Validation rules
These are the main workflow rules:- All action refs must be unique.
- Every dependency in
depends_onmust reference a real action. - Cycles in the action graph are invalid.
interactioncannot be combined withfor_each.- Outer scopes cannot reference actions inside a nested scatter or loop scope.
- Inner scopes can reference actions in parent scopes.
core.transform.gathermust close the scatter scope it depends on.core.loop.endmust close the loop scope it depends on.