Documentation for automated readers
A curated documentation index is available at: https://grafana.com/llms.txt
A complete documentation index is available at: https://grafana.com/llms-full.txt
These indexes can help with page discovery before fetching individual documents.
This page is also available in Markdown, which may be easier for automated readers and AI tools to parse than HTML. The Markdown version is available at https://grafana.com/docs/grafana-cloud/platform/workflows/reference/blueprints/learn-expressions-and-branching.md, or by sending Accept: text/markdown to https://grafana.com/docs/grafana-cloud/platform/workflows/reference/blueprints/learn-expressions-and-branching/. For broader documentation discovery, the curated index is available at https://grafana.com/llms.txt and the complete index is available at https://grafana.com/llms-full.txt.
Learn: expressions and branching
Note
Grafana Workflows is currently in public preview. Grafana Labs offers limited support, and breaking changes might occur prior to the feature being made generally available.
A runnable tour of CEL expressions, step outputs, switch branches, and filters. No setup or integrations needed. Click Run and try different payloads.
This Grafana Workflows blueprint is in the Basics category of the Blueprints library.
Before you begin
This blueprint needs no integrations or secrets.
Steps
Steps run in order from first to last. A step inside a switch branch runs only when Workflows chooses that branch.
| Step | ID | Type | Description |
|---|---|---|---|
| Build a greeting | greeting | transform | Shows ${...} interpolation, has() for optional fields, the ternary operator, and now(). Run it with and without a name in the payload data. |
| Branch on priority | classify | switch | Runs the first branch whose condition is true, or the default branch when none match. Try priority high, low, or leave it out. |
High priority path (branch 1 of classify) | high-priority | transform | Runs only when priority is high. It can read greeting because greeting ran before the switch. |
Low priority path (branch 2 of classify) | low-priority | transform | Runs only when priority is low. |
Default path (default branch of classify) | no-priority | transform | The default branch, with no condition. Runs when no other branch matches. |
| Continue only if notify is true | only-if-notify | filter | Ends the run here, successfully, unless the payload sets notify to true. Set failOnExit to true to make it fail instead. |
| Summarize the run | summary | transform | Reads the output of an earlier top-level step and the switch output that says which branch ran. |
For the inputs and outputs of each step type, refer to Step and trigger types reference.
Before you turn on the workflow, customize any steps that need input from you, such as a channel ID or a schedule name. Each step’s description says what to set.
Workflow definition
Save this definition as a YAML file to create the workflow with gcx, the Workflows API, or Terraform, or give it to a coding agent as an example.
Replace FOLDER_UID with the UID of the folder for the workflow.
Blueprints start disabled, so finish customizing the steps before you set enabled to true.
For details, refer to Manage workflows as code.
apiVersion: workflows.ext.grafana.app/v1alpha1
kind: Definition
metadata:
name: learn-expressions-and-branching
annotations:
grafana.app/folder: <FOLDER_UID>
spec:
name: 'Learn: expressions and branching'
enabled: false
startWhen:
matchingRules: []
schedules: []
steps:
- id: greeting
type: transform
name: Build a greeting
description: >-
Shows ${...} interpolation, has() for optional fields, the ternary operator, and now().
Run it with and without a name in the payload data.
inputs:
template: "Hello ${has(inputs.data.name) ? inputs.data.name : 'there'}! This run started at ${now()}."
- id: classify
type: switch
name: Branch on priority
description: Runs the first branch whose condition is true, or the default branch when none match. Try priority high, low, or leave it out.
branches:
- condition: "has(inputs.data.priority) && inputs.data.priority == 'high'"
steps:
- id: high-priority
type: transform
name: High priority path
description: Runs only when priority is high. It can read greeting because greeting ran before the switch.
inputs:
template: 'High priority. ${steps.greeting.outputs.result}'
- condition: "has(inputs.data.priority) && inputs.data.priority == 'low'"
steps:
- id: low-priority
type: transform
name: Low priority path
description: Runs only when priority is low.
inputs:
template: 'Low priority, nothing urgent.'
- steps:
- id: no-priority
type: transform
name: Default path
description: The default branch, with no condition. Runs when no other branch matches.
inputs:
template: 'No priority set, using the default path.'
- id: only-if-notify
type: filter
name: Continue only if notify is true
description: Ends the run here, successfully, unless the payload sets notify to true. Set failOnExit to true to make it fail instead.
inputs:
condition: 'has(inputs.data.notify) && inputs.data.notify == true'
- id: summary
type: transform
name: Summarize the run
description: Reads the output of an earlier top-level step and the switch output that says which branch ran.
inputs:
template: "${steps.greeting.outputs.result} Branch index: ${string(steps.classify.outputs.matchedBranchIndex)}."How it works
This section explains when the workflow runs and how its steps work together.
When it runs
This blueprint has no event or schedule trigger, so it runs only when you start it manually.
How the steps fit together
These notes cover how the steps connect and which Workflows behaviors the blueprint relies on.
- Manual-only workflow (no matching rules, no schedules) that needs no integrations, so it can be run from the editor right away.
- Suggested test payload data: {“name”: “Ada”, “priority”: “high”, “notify”: true}.
- It shows:
${...}interpolation in a transform;has()with the ternary operator for optional fields;now()for the run time; reading a prior step’s output withsteps.<id>.outputs.<field>, and bracket notation for hyphenated IDs; a switch whose first matching branch runs, with a default branch; and a filter that ends the run early when its condition is false. - Steps after the switch cannot read outputs from steps inside its branches, so the final step reads only top-level steps.
- Use it as a reference for expression syntax.
Next steps
Was this page helpful?
Related resources from Grafana Labs


