> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.meetgail.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.meetgail.com/_mcp/server.

# Using Expressions in Nodes

> Calculate, compare, and choose between values using CEL, the expression language behind workflows.

An expression is a small formula that produces a value when a workflow runs. Use
one whenever a setting should be worked out from the data in a run rather than
typed in ahead of time: a premium with tax added, a condition that checks a
score, a label chosen from a status. Under the hood these are written in CEL, the
expression language, but you rarely need to think about the name; on this page we
just call them expressions.

Expressions show up in many places: the conditions on a
[Check](/platform/workflows/node-reference/logic-and-flow/check) or
[Conditional](/platform/workflows/node-reference/logic-and-flow/conditional) node, the
formula on a [Map](/platform/workflows/node-reference/logic-and-flow/map) node, inside a
[string template](/platform/workflows/core-concepts/expressions/string-templates), and in
any node setting that accepts one.

## Referencing values

An expression reads values that earlier steps produced by naming the group, the
step, and the value:

```text
node.contact.email
config.default_sender
secret.crm_api_key
```

You usually pick these from the builder's value picker rather than typing them.
See [Variables & Data Flow](/platform/workflows/core-concepts/variables-data-flow) for
the full picture of where values come from.

## What you can write

Expressions cover the everyday building blocks of logic and math.

| You want to...            | Write something like                                     | Result                   |                          |                        |
| ------------------------- | -------------------------------------------------------- | ------------------------ | ------------------------ | ---------------------- |
| Do arithmetic             | `node.quote.premium * 1.08`                              | The premium plus 8% tax  |                          |                        |
| Join text together        | `node.contact.first_name + " " + node.contact.last_name` | `Sarah Chen`             |                          |                        |
| Compare values            | `node.score.value >= 80`                                 | `true` or `false`        |                          |                        |
| Check text                | `node.status.value == "active"`                          | `true` or `false`        |                          |                        |
| Combine conditions        | `node.is_verified.value && node.score.value > 70`        | `true` only if both hold |                          |                        |
| Either/or conditions      | \`node.is\_error.value                                   |                          | node.is\_timeout.value\` | `true` if either holds |
| Choose between two values | `node.score.value >= 70 ? "Pass" : "Fail"`               | One of the two labels    |                          |                        |
| Build a list              | `[node.primary.url, node.secondary.url]`                 | A list of two values     |                          |                        |
| Build a set of fields     | `{"name": node.contact.name, "age": node.contact.age}`   | A small record           |                          |                        |
| Read a list item          | `node.items.list[0]`                                     | The first item           |                          |                        |
| Count a list              | `node.items.list.size()`                                 | How many items           |                          |                        |

The `? :` form reads as "if this, then the first value, otherwise the second." It
is the most common way to pick a value based on a condition.

## A worked example

Chen Insurance Group scores each inbound quote request in an earlier step. A
Check node then turns that score into a decision using two expressions, tried in
order:

```text
node.risk.score >= 80 && node.documents.complete
node.risk.score >= 50
```

If the applicant's score is 80 or higher and their documents are complete, the
first condition wins and the request is approved. Otherwise, if the score is at
least 50, the second wins and it goes to review. If neither is true, the node's
default outcome applies. This is how a run reacts to real data instead of fixed
values.

Text inside quotes is compared exactly, including uppercase and lowercase, so
`"Active"` and `"active"` are not the same. Match the exact value the earlier
step produces.

Expressions can also call functions, like counting a list or formatting a phone
number. See the
[Function Reference](/platform/workflows/core-concepts/expressions/function-reference)
for what is available.

## Related

#### [Function Reference](/platform/workflows/core-concepts/expressions/function-reference)

The functions you can call inside an expression.

#### [String Templates](/platform/workflows/core-concepts/expressions/string-templates)

Drop expression results into text like emails and messages.

#### [Variables & Data Flow](/platform/workflows/core-concepts/variables-data-flow)

Where the values an expression reads come from.

#### [Check](/platform/workflows/node-reference/logic-and-flow/check)

Turn a set of conditions into one labeled outcome.