Skip to content

Tasks and references

A task’s form has two kinds of field: ones that hold a value, and ones that name where a value comes from. The second kind is a reference, written ${...}.

A reference’s source says where the value comes from.

${name}, ${name.field}, or ${name:-fallback} reads a workflow variable. Variables are values you set for the run — the workflow’s own, or supplied when a run starts (for example, from a webhook payload). Dot notation reaches into a nested value, and :- supplies a default when the variable is unset. The editor badges these references var.

${slug.output} reads what a task produced. Three pseudo-fields are available on every task:

Field What it is
raw_input The upstream value exactly as it arrived, before any of this task’s own input was merged in. Always available.
input The task’s input after upstream data and its own configuration are combined.
output What the task produced, available after it has finished.

Append a path to reach a field: ${fetch-user.output.email}.

${secrets.<name>.<key>} reads a stored credential, for example ${secrets.billing.api_key}. A secret reference is exactly three segments, and a fallback default is not allowed — an unset credential fails the run instead of silently becoming a literal value. See Secrets.

A reference can be the whole value of a field: pick it with the ${x} button beside the field label, and the field shows the reference instead of a value.

It can also sit inside text, wherever the field takes text:

https://api.example.com/users/${fetch-user.output.id}
Bearer ${secrets.billing.api_key}

Both sources work the same way in either shape.

A task can receive a value from upstream: the previous step in a sequence, the parent group or loop, or the value a run starts with. That value fills the fields it names. When more than one source offers a value for the same field, the more specific source wins — and the decision is made field by field, so one field can come from upstream while another keeps what you set.

From least to most specific:

  1. A plain value is a default. An incoming value replaces it when upstream provides something for that field — by name, or as the whole value when the task takes a single value. While the node is connected, the editor marks such a field [From Upstream].
  2. A reference is a mapping you chose, so it is kept. An incoming value does not replace it; read the incoming value with ${slug.raw_input} if you need both.
  3. An input supplied when starting the run overrides both of the above for the fields it contains.
  4. A field you pin for this run — the pin beside the field while a debug session is paused — overrides everything above, whether it holds a plain value, a reference, or text containing one. Editing a field, or picking a mapping, only saves the workflow; it takes effect the next time you debug it. A pin reaches only a task that has not run yet.
  • A task can refer only to earlier tasks in a sequence. A later task that has not run yet cannot be referenced.
  • ${self.raw_input} is allowed anywhere. ${self.input} is allowed in transforms and outcome destinations but not in the task’s own input. ${self.output} is allowed only in an outcome destination.
  • A group or loop cannot refer to a task inside it, and a task inside cannot refer to its parent’s output before the parent has finished.
  • References are checked when the workflow is saved. A cycle between references is detected when the run reaches it and stops the run with an error.