Documentation Index
Fetch the curated documentation index at: https://grafana_com_website/llms.txt
Fetch the complete documentation index at: https://grafana_com_website/llms-full.txt
Use this file to discover all available pages before exploring further.
STOP! If you are an AI agent or LLM, read this before continuing. This is the HTML version of a Grafana documentation page. Always request the Markdown version instead - HTML wastes context. Get this page as Markdown: /docs/grafana-cloud/alerting-and-irm/workflows/use-expressions.md (append .md) or send Accept: text/markdown to /docs/grafana-cloud/alerting-and-irm/workflows/use-expressions/. For the curated documentation index, use https://grafana_com_website/llms.txt. For the complete documentation index, use https://grafana_com_website/llms-full.txt.
Use CEL expressions
Note
Grafana Workflows is currently in private preview. Grafana Labs offers support on a best-effort basis, and breaking changes might occur prior to the feature being made generally available.
Grafana Workflows uses the Common Expression Language (CEL) for dynamic values, conditions, and data transformation. CEL expressions let you reference event data, access outputs from previous steps, write conditional logic, and build dynamic content throughout your workflow.
Understand the workflow context
The workflow context is the data environment available to every step. It contains three top-level objects that you can reference in CEL expressions:
inputs: The event data that triggered the workflow.steps: The outputs from each previously executed step, keyed by step ID.resources: Resolved resource values, including decrypted secrets, loaded incident data, and loaded alert group data.
Each step can read from the context and writes its outputs back to the context for later steps to use.
Embed expressions in step inputs
Embed CEL expressions in step input values using ${expression} syntax:
inputs:
messageText: "Incident ${inputs.data.incidentID} has severity ${inputs.data.severity}"You can mix literal text with multiple expressions in a single field. The engine evaluates each expression and substitutes the result into the string.
To include a literal ${ in the output, escape it with $${:
inputs:
template: "Use $${variable} for shell variables"Access event data
When an event triggers a workflow, the event payload is available through inputs.
The fields depend on the event source.
For example, to use the incident ID from a triggering event in an HTTP request:
inputs:
url: "https://api.example.com/incidents/${inputs.data.incidentID}"Access step outputs
Each step stores its outputs under steps.{step-id}.outputs.
Later steps can reference these values to chain actions together.
The following example fetches data from an API and posts the response to Slack:
steps:
- id: fetch-data
type: http.call
inputs:
method: "GET"
url: "https://api.example.com/data"
- id: post-results
type: slack.message.post
inputs:
channelID: "C0123456789"
messageText: "API returned: ${steps.fetch-data.outputs.responseBody}"When a step ID contains hyphens, use bracket notation:
${steps['fetch-data'].outputs.responseBody}For details on the outputs each step type produces, refer to Step types reference.
Access incident and alert group data
Workflows that trigger on incident events automatically load the full incident into the context at
resources.incident.event. Similarly, workflows triggered by alert group events automatically load the alert group at
resources.alertgroup.event. You can also declare additional resources in the resources.incidents or resources.alertgroups sections of the
definition.
inputs:
message: "Incident ${resources.incident.event.title} is ${resources.incident.event.status}"
severity: "${resources.incident.event.severity}"For alert groups:
inputs:
message: "Alert group ${resources.alertgroup.event.title} is ${resources.alertgroup.event.state}"
count: "${resources.alertgroup.event.alerts_count}"For workflows with explicitly declared resources, use the reference name you defined:
inputs:
relatedTitle: "${resources.incident.related.title}"
alertGroupState: "${resources.alertgroup.current.state}"For details on declaring resources, refer to Load incident data and Load alert group data.
Write conditions
CEL supports standard comparison and logical operators for use in filter steps and switch branch conditions:
inputs.data.severity == "critical"
inputs.data.count > 10
inputs.data.status == "active" && inputs.data.priority == "high"
inputs.data.region == "us" || inputs.data.region == "eu"A filter step evaluates a condition and stops the workflow if the result is false.
A switch step evaluates branch conditions in order and runs the first matching branch.
For details on how to use filter and switch steps, refer to Create workflows.
Use built-in functions
Workflows extends CEL with custom functions for working with JSON data:
| Function | Description | Example |
|---|---|---|
json_parse(string) | Parse a JSON string into a structured object | json_parse(steps.api.outputs.responseBody).name |
json_stringify(value) | Convert a value to a JSON string | json_stringify(inputs.data) |
Standard CEL string functions are also available, including contains, startsWith, endsWith, matches, and size.
Handle type conversions
JSON numbers deserialize as floating-point values.
The CEL environment automatically converts whole-number floats to integers, so expressions like inputs.data.count > 10 work without explicit type conversion.
Cross-type numeric comparisons are enabled.
Next steps
Was this page helpful?
Related resources from Grafana Labs


