Variables
A variable is a value you define once and reuse anywhere in a workflow. Instead of typing the same email address, threshold, or piece of wording into five different blocks — and then editing all five when it changes — you put it in a variable and point the blocks at it.
Variables belong to the workflow you're editing. Each one has a name, a type, and a value, and you manage them all from the floating Variables panel in the editor.
This page also covers references in general — how a block reads a variable, a trigger input or an earlier block's result, and the tools the editor gives you for writing them.
Opening the Variables Panel
You can open the panel two ways from inside the workflow editor:
| How | Where |
|---|---|
| The Variables button | In the panel header at the top of the editor — see Toolbar & Controls |
| Right-click the empty canvas | Choose Variables from the menu |
The panel floats above the canvas rather than sitting in a tab, so you can keep it open while you work on your blocks.
- Drag it by its header to move it wherever you like. It stays inside the window, and it remembers where you left it.
- Close it with the × in its header, or press Esc.
Before you add anything, the panel shows "No variables yet".
Adding a Variable
- Open the Variables panel.
- Click the + button in the panel header.
- A new card appears, already open for editing and named variable1 (then variable2, and so on).
- Fill in the Name, choose a Type, and enter a Value.
- Click Save.
Each variable is a small collapsible card. Click the card's title to open or close it.
| On the card | What it shows |
|---|---|
| Title | The variable's name |
| Type badge | The type, on the right of the title |
| Warning icon | Appears next to the name when that variable has a problem — so you can spot it even while the card is closed |
| Trash icon | Deletes the variable |
| Name / Type / Value | The three fields, shown when the card is open |
Variables are listed in alphabetical order by name, so a card can move in the list as you rename it.
Types
Pick the type from the Type dropdown on the card.
| Type | Use it for | Example value |
|---|---|---|
| Plain | Ordinary text — a name, an email address, a phrase | Weekly summary |
| Number | Any number, whole or decimal | 0 |
| Boolean | A yes/no switch — must be true or false | true |
| Object | A set of named fields, written in JSON | {} |
| Array | A list of items, written in JSON | [] |
Object and Array get a larger, resizable box so longer JSON stays readable. The other types use a single-line field.
Choose the type that matches how the value will be used. A threshold you compare against belongs in a Number, not in Plain text — that way a block that expects a number always gets one.
Naming Rules
A variable's name is how you refer to it later, so the panel keeps names simple and unambiguous.
| Rule | Message you'll see if it's broken |
|---|---|
| The name can't be empty | "Name cannot be empty" |
| Use letters, numbers and underscore only — no spaces, dots or punctuation | "Use letters, numbers, and underscore only" |
Every name in the workflow must be different. Upper and lower case don't count as a difference — Total and total clash | "Another variable already uses this name" |
The message appears under the Name field, and the card's warning icon stays visible even when the card is closed.
Names must avoid spaces and dots because a reference is written as a single token — <variable.reportEmail>. A space or a dot in the middle would break the reference.
Values and Validation
The Value field is checked against the type as you type. A value that doesn't fit its type is flagged straight away, and you can't save until it's fixed.
| Type | What's accepted | Message if it doesn't fit |
|---|---|---|
| Plain | Any text | — |
| Number | A number | "Must be a number" |
| Boolean | true or false | "Must be true or false" |
| Object | Valid JSON describing a set of fields | "Must be a JSON object" or "Invalid JSON" |
| Array | Valid JSON describing a list | "Must be a JSON array" or "Invalid JSON" |
Leaving a value empty is allowed for every type — useful when you want to define the variable now and fill it in later.
Saving
Variable edits are held in the panel until you save them explicitly. The footer of the panel tells you where you stand.
| Footer text | What it means |
|---|---|
Reference as <variable.name> | Everything is saved and valid — this is the reminder of how to use your variables |
| Unsaved changes | You have edits that haven't been saved yet |
| Fix errors to save | At least one variable has a name or value problem. Look for the cards with a warning icon |
The Save button becomes available only when you have unsaved changes and no errors. While it saves it reads "Saving...".
:::info Saving variables doesn't touch your canvas The panel's Save saves your variables only. The blocks and connections on the canvas are left exactly as they are, so you can tidy up variables without worrying about the flow itself. :::
If a save can't go through, a message appears: "Could not save variables. Please try again." Your edits stay in the panel, so nothing is lost.
If the workflow changed somewhere else
If the same workflow was changed elsewhere — another tab, another device, or the Copilot building it — the panel refuses to overwrite that work. A banner appears instead:
"This workflow changed elsewhere. Refresh to load the latest before saving."
Click Refresh to load the latest version into the panel, then re-apply your edits and save again.
Closing with unsaved edits
If you close the panel while you still have unsaved changes, you're asked to confirm: Discard variable changes? — "You have unsaved variable changes. Close without saving?" Choose Keep editing to go back, or Discard to close and drop them.
Using a Variable in Your Blocks
Once a variable is saved, refer to it from any block's fields by writing its name between angle brackets, prefixed with variable:
<variable.reportEmail>
When the workflow runs, that reference is replaced with the variable's value. You can use it anywhere a block takes a value — a prompt, a recipient, a URL, a condition, a loop's settings.
The kinds of reference
Variables are one of several things you can point a block at. They all use the same angle-bracket shape.
| Reference | What it points at | Example |
|---|---|---|
<variable.NAME> | A variable you defined in the Variables panel | <variable.reportEmail> |
<input.NAME> | A field from the data the run started with — the trigger's input | <input.customerId> |
<blockName.field> | An earlier block's output | <agent.content> |
<loop.index>, <loop.currentItem> | Inside a loop block: the number of the current pass, and in a For Each the current item | <loop.currentItem> |
<parallel.index>, <parallel.currentItem> | The same, inside a Parallel block | <parallel.currentItem> |
<form.submitter.NAME> | In a run started by a form: the person who sent it — id, name or email | <form.submitter.email> |
<input.NAME>fields come from the trigger. On a manual Start block you define them yourself as Name + Type; on a webhook or API trigger they arrive with the incoming request. See Running Workflows.<blockName.field>uses the block's name and the name of one of its outputs — for example an Agent block named agent exposes its answer as<agent.content>. Upper and lower case and spaces in the block name don't matter: a block called Arketic Parse File is read as<arketicparsefile.data>. Each block's outputs are listed in Blocks.<form.submitter.…>is empty when the form is open to everyone, because nobody signs in. See Forms.
Because loop, parallel, variable, input and form have these special meanings, a block can't be given any of them as its name.
Picking a reference instead of typing it
You don't have to remember block and field names.
Type @ in a field. In a text field — a single line, a longer text box or a message — type @ at the start or after a space. A list opens with the blocks that come before this one and each of their output fields, and every row shows the reference it will insert.
| Key | What it does |
|---|---|
| Keep typing | Narrows the list by block or field name |
| ↑ / ↓ | Moves through the list |
| Enter or Tab | Inserts the highlighted reference |
| Esc | Closes the list without inserting anything |
The list offers earlier blocks only. <variable.…> and <input.…> references are typed by hand. An @ inside an email address doesn't open the list.
Drag a field from the Upstream view. In a block's configuration view the Input column has two views, Upstream and Resolved. Upstream lists the outputs of every block that comes before this one. Drag a field from there into a field of the editor and its reference is inserted where you drop it. Before the workflow has run, the list shows each block's known output fields with the note "Fields below come from each block's schema. Run once to populate real values and previews."
Checking a reference before you run
Under a field that contains references, the editor lists each one with a coloured dot and — once the workflow has run — the value it had in the last run. Hover a row to see the whole value. Up to four references are listed; after that you see "+2 more references".
| What the row says | What it means |
|---|---|
| "resolved from last run" | The value shown is what the reference produced last time |
| "from last run — workflow edited since" | The value is from the last run, but you changed the workflow afterwards |
| "run once to preview" | The workflow hasn't run yet, so there is nothing to show |
| "no output from this block yet" | The block the reference points at produced nothing in the last run |
| "empty in the last run" | The reference is valid, but the value was empty last time |
| "No block named “…” — will be sent as plain text" | No block has that name — check the spelling |
| "“…” has no such field — try … — resolves to nothing at run time" | The block exists but has no output by that name. The message suggests the ones it does have |
"input value — resolves at runtime" (also for variable and loop) | The value only exists while the workflow runs, so it can't be previewed |
Functions in a reference
A reference can change its value on the way in, by ending with a function:
<agent.content.upper()>
<input.orderDate.formatDate("dd.MM.yyyy")>
<variable.tags.join(", ")>
To add one without typing, click the fx button at the end of the reference's row under the field and pick a function from the list. It is added to the end of that reference.
| Function | What it does |
|---|---|
first() | First item of a list |
last() | Last item of a list |
length() | How many items a list has, or how many characters a text has |
join(", ") | Glues a list into one line, with the separator you give |
split(",") | Cuts text into a list at a separator |
upper() | UPPERCASE. For Turkish text pass the language: upper("tr") |
lower() | lowercase. For Turkish text pass the language: lower("tr") |
trim() | Drops spaces at the start and the end |
replace("a", "b") | Replaces every occurrence of one piece of text with another |
default("—") | Uses this value instead when the original is missing or empty |
formatDate("dd.MM.yyyy") | Formats a date. The pattern is built from yyyy, MM, dd, HH, mm and ss |
round() | Rounds a number; round(2) keeps two decimals |
A few rules:
- Functions can be chained and run left to right:
<input.name.trim().upper("tr")>. - What goes in the brackets is fixed text in quotes or a number — not another reference.
- A function comes last. You can't read a field after one:
<agent.items.first().name>doesn't work. - Functions work on every kind of reference — block outputs,
<input.…>,<variable.…>and the loop values alike. - On a reference to a block, a misspelled function is flagged under the field straight away: "There is no function called “…”. Available: …". A wrong number of values in the brackets gets "“…” takes … argument(s), got …" with an example. Whatever the kind of reference, a function that is left wrong makes the step fail when the workflow runs.
:::tip Most run problems are data problems When a run fails, it's usually not that a block broke — it's that a reference pointed at a value that wasn't there: a renamed block, a trigger field that didn't arrive, a misspelled variable name. Open the run in Logs and read the failed step's Input and Output. The value you expected will be missing right there. :::
Reading and Writing Variables During a Run
Variables aren't only fixed settings — a workflow can also read and update them while it runs, using the Variables block from the Data category of the block palette.
| Field | What it does |
|---|---|
| Operation | Read fetches the variable's current value, Write sets it |
| Variable name | Which variable to read or write |
| Value (write only) | The value to store. Shown only when the operation is Write |
The block's result is value, so a later step reads it as <blockName.value>.
This is useful for carrying a value across a loop, or for building up a result step by step before a final block uses it.
Good Practice
- Name for the reader, not the keyboard.
reportRecipienttells you what it holds;v2doesn't. - Put anything you'd otherwise repeat into a variable — email addresses, thresholds, standard wording, a fixed label. Then one edit updates every block that uses it.
- Keep types honest. If a value is a number, make it a Number. The validation is there to catch the mismatch before a run does.
- Don't use variables for secrets. API keys and account sign-ins belong in Connections, where they're stored securely and never shown back to you.
- Rename with care. If you rename a variable or a block, update every reference that used the old name, or those blocks will look for something that no longer exists.