Module · Data
Set Variable
Lesson 11 of 11 · 5 min
By now you have written a few references like {{universaldatabasetrigger_1.new_data.owner_email}}. They work, and they get unwieldy: the same long path repeated in five nodes, and a rename upstream that breaks all five.
Set Variable gives a value a name. Compute or capture it once, then read it as {{variableset_1.all_variables.deal_owner_email}} wherever you need it.
A worked example
Two variables, set once
Click the node to see both entries — each one is a row in the same list.
Scroll for all 3 steps →
One node sets as many variables as you like; each is a row. That matters for readability — a single “here is what this workflow works with” node beats five scattered assignments.
What each row says
| Field | What it holds |
|---|---|
variables | Array of variables to set |
debug_output | Include debug output with variable values for copying Defaults to true. |
variables
- What it holds
- Array of variables to set
debug_output
- What it holds
- Include debug output with variable values for copying Defaults to
true.
| Setting | What it does | Values |
|---|---|---|
variable_name | What you will call it downstream. | Required. |
scope | How long it lives. | workflow · global · session |
value_source | Where the value comes from. | input · field · static · template · expression |
value_type | How to interpret it. | string · number · boolean · json |
variable_name
- What it does
- What you will call it downstream.
- Values
- Required.
scope
- What it does
- How long it lives.
- Values
workflow·global·session
value_source
- What it does
- Where the value comes from.
- Values
input·field·static·template·expression
value_type
- What it does
- How to interpret it.
- Values
string·number·boolean·json
value_type is easy to skip and worth setting. A number stored as a string compares as text, and the classic symptom is a Condition deciding that 9 is greater than 100.
The three scopes
| Scope | Lives for | Use it for |
|---|---|---|
workflow | This run only. | Almost everything. The default, and the safe one. |
session | A conversation, across runs. | Chat and voice agents that need to remember within one exchange. |
global | The whole organisation, permanently. | Genuine settings — a threshold, a default owner. |
workflow
- Lives for
- This run only.
- Use it for
- Almost everything. The default, and the safe one.
session
- Lives for
- A conversation, across runs.
- Use it for
- Chat and voice agents that need to remember within one exchange.
global
- Lives for
- The whole organisation, permanently.
- Use it for
- Genuine settings — a threshold, a default owner.
Global variables outlive the run, and they are shared. A global written here is saved against the organisation and is visible to every workflow, including ones somebody else built. Writing per-record data into a global — this contact's email, this deal's amount — means two runs at once overwrite each other, and the resulting bug looks like the CRM is wrong rather than the workflow. Keep per-record values in workflow scope.
When a variable earns its place
- The same long reference appears three times. Name it once.
- A value is assembled from several pieces — a greeting, a URL, a summary line — and the assembly should happen in one visible place.
- A workflow-level setting that a reader should see at the top rather than buried in a node's config.
And the case against: a variable used exactly once is indirection for its own sake. The reader now has to find where it was set to know what it holds, and the original reference would have told them immediately.
Reading it back
Variables come out under the node that set them: {{variableset_1.all_variables.<name>}}. The node also reports variables_set and total_variables, and with debug_output on — it is on by default — the resolved values appear in the execution log, which is the fastest way to see that a template resolved to an empty string rather than what you expected.
Try it
- Add a Set Variable after a trigger and give one value from that trigger a short name.
- Read it in the next node, and confirm it resolves in the execution log.
- Add a second row with
value_typeset tonumber, then compare it in a Condition with>— and try it again as astringto see the comparison change. - Leave global scope alone until you have a value that genuinely belongs to the organisation rather than the run.
Next: Transform Data — for when the value needs reshaping, not just naming.

