Step and trigger types reference
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.
Step types
Steps are the individual actions in a workflow.
They execute in order from first to last.
Each step has a type, an ID, and a set of inputs.
Every step produces outputs that later steps can reference through the workflow context using CEL expressions, for example, ${steps.my-step.outputs.responseBody}.
For details on connecting steps with the workflow context, refer to Use CEL expressions.
General
HTTP call (http.call)
Make an HTTP request to any URL with any method and body. Supports bearer token and basic authentication using secrets.
Inputs:
Outputs:
Execute code (code.execute)
Run sandboxed code inside a workflow. The full workflow context is available as a built-in variable, and additional named arguments can be passed as a JSON object. Code runs in an isolated sandbox with no network access and a temporary filesystem.
Currently supported languages: Python.
Inputs:
Outputs:
Injected variables:
Two variables are automatically available inside the sandbox:
The context variable has the following structure:
{
"inputs": { },
"steps": {
"step-id": {
"outputs": { }
}
},
"resources": {
"incident": { },
"alertgroup": { }
}
}context["inputs"]contains the trigger event data or manual test input.context["steps"]contains outputs from all previously executed steps, keyed by step ID.context["resources"]contains resolved resource data (incidents, alert groups). Thesecretnamespace is always stripped before code execution.
Example: process data from a previous step
This example shows a workflow where a code step reads the response from an earlier HTTP call, processes it, and outputs structured JSON for a downstream filter step:
steps:
- id: fetch-status
type: http.call
name: "Get service status"
inputs:
method: "GET"
url: "https://api.example.com/status"
- id: analyze
type: code.execute
name: "Analyze status response"
inputs:
language: python
code: |
import json
response = context["steps"]["fetch-status"]["outputs"]["responseBody"]
data = json.loads(response)
unhealthy = [s for s in data.get("services", []) if s["status"] != "healthy"]
threshold = args.get("threshold", 1)
print(json.dumps({
"unhealthy_count": len(unhealthy),
"unhealthy_services": [s["name"] for s in unhealthy],
"should_alert": len(unhealthy) >= threshold,
}))
args:
threshold: "${inputs.alertThreshold}"
- id: check-alert
type: filter
name: "Alert if threshold exceeded"
inputs:
condition: "steps['analyze'].outputs.success == true"
failOnExit: "true"Example: simple scheduled check
steps:
- id: run-check
type: code.execute
inputs:
language: python
code: |
has_inputs = len(context.get("inputs", {})) > 0
print(f"Scheduled run, has trigger inputs: {has_inputs}")Downstream steps reference code output using CEL expressions, for example, ${steps['analyze'].outputs.stdout}.
Flow control
Transform (transform)
Evaluate a template string with embedded CEL expressions to generate dynamic content.
Use ${expression} syntax to embed expressions that reference workflow inputs and previous step outputs.
Inputs:
Outputs:
Filter (filter)
Gate workflow execution on a CEL condition.
If the condition evaluates to false, the workflow stops and no further steps execute.
Inputs:
Outputs:
Switch (switch)
Conditionally execute different sets of steps based on CEL expressions.
Each branch has a condition and its own list of steps.
The first branch whose condition evaluates to true runs.
Include a default branch with no condition as a fallback.
Branches:
A switch step uses a branches array instead of inputs.
Each branch has a condition (a CEL expression) and a steps list.
Omit the condition to mark a branch as the default fallback.
- id: route-by-severity
type: switch
branches:
- condition: "inputs.data.severity == 'critical'"
steps:
- id: page-oncall
type: irm.page-team
inputs:
teamIdentifier: "platform"
- steps:
- id: post-update
type: slack.message.post
inputs:
channelID: "C0123456789"
messageText: "Non-critical incident received"Outputs:
Wait (wait)
Pause workflow execution for a specified number of seconds.
Inputs:
Outputs:
Incident
Incident steps operate on Grafana Incidents. You can pass incident IDs directly or reference them from incident resources loaded into the workflow context. For details on loading incident data, refer to Load incident data.
Create incident (incident.create)
Create a new Grafana Incident with a title, severity, and optional labels.
Inputs:
Outputs:
Add participant to incident (incident.add-participant)
Add a user to a Grafana Incident with a specific role.
Inputs:
Outputs:
Set incident field (incident.set-field)
Update a field on a Grafana Incident, including title, status, severity, or role assignments.
Inputs:
Outputs:
Slack
Create Slack channel (slack.channel.create)
Create a new public or private Slack channel.
Inputs:
Outputs:
Post message to Slack channel (slack.message.post)
Post a message to a Slack channel. Supports plain text, Block Kit blocks for rich formatting, attachments, and threaded replies.
Inputs:
Outputs:
Archive Slack channel (slack.channel.archive)
Archive a Slack channel.
Inputs:
Outputs:
Add bookmark to Slack channel (slack.channel.add-bookmark)
Add a bookmark link to a Slack channel.
Inputs:
Outputs:
Add users to Slack channel (slack.channel.add-users)
Invite users to a Slack channel by their Slack user IDs.
Inputs:
Outputs:
IRM
Page user via IRM (irm.page-user)
Create an IRM/OnCall escalation to page a user by email address.
Inputs:
Outputs:
Page team via IRM (irm.page-team)
Create an IRM/OnCall escalation to page an entire team. Optionally associates the escalation with an incident, which invites team members to join the incident, and includes urgency and message context.
Inputs:
Outputs:
Invite user to incident (irm.invite-user-to-incident)
Create an IRM escalation to invite a user to an incident.
Inputs:
Outputs:
Invite user to alert group (irm.invite-user-to-alert-group)
Create an IRM escalation to invite a user to an alert group.
Inputs:
Outputs:
Get on-call users for a schedule (irm.schedule-current-oncall)
Look up the users currently on-call for an OnCall schedule. Use this step to drive subsequent paging or notification steps with the right responder.
Inputs:
Outputs:
Get on-call users for a team (irm.team-current-oncall)
Look up the users currently on-call for a team by resolving the team’s direct paging integration. Use this step when you want to notify whoever is on-call for a team without specifying a schedule.
Inputs:
Outputs:
Microsoft Teams
Steps that post messages to or create resources in Microsoft Teams.
Prerequisites:
Before using any Microsoft Teams step, install the Microsoft Teams app through Grafana IRM integrations and set up at least one hook for it. This creates the link between your Grafana stack and your Microsoft Teams tenant, which the workflow engine uses to look up your Azure tenant ID at runtime. You can disable or remove the hook once it’s set up. It only needs to exist long enough for the initial link to be created.
The msteams.meeting.create step needs the Calendars.ReadWrite application permission on the app registration
used by your Microsoft Teams integration, with admin consent granted. New installs of the Microsoft Teams app
already request and consent this permission automatically, so this step is only needed if the app was installed
before msteams.meeting.create support was added. In that case, add the permission in the app registration’s API
permissions page and grant admin consent for it. No additional Teams-specific admin setup is required.
Create Teams meeting (msteams.meeting.create)
Create a Microsoft Teams online meeting on behalf of an organizer, by creating an event with an online meeting
attached on the organizer’s Outlook calendar. Requires the Calendars.ReadWrite Azure AD application permission.
Refer to the Prerequisites above.
This adds an event to the organizer’s Outlook calendar, but the event is created with free/busy status set to free, so it doesn’t mark the organizer as busy or conflict with other meetings on their calendar.
To compute startDateTime or endDateTime relative to another timestamp, use CEL’s built-in timestamp() and
duration() functions, for example ${timestamp(inputs.eventTime) + duration('1h')}. Refer to
Use CEL expressions.
Inputs:
Outputs:
Post message to Teams channel (msteams.message.post)
Post a text message or Adaptive Card to a Microsoft Teams channel.
At least one of messageText or adaptiveCard is required.
To reply in a thread, pass conversationID and threadActivityID from a previous Post Message step.
Inputs:
Outputs:
Trigger types
Triggers define when a workflow starts. You configure triggers in the startWhen section of a workflow definition.
For details on configuring triggers, refer to Configure triggers.
Event trigger
An event trigger starts a workflow when an incoming event matches a regular expression pattern.
Events arrive on NATS subjects following the format {app}.{instance-id}.{resource-type}.{event-type}.
The engine strips the {instance-id} segment before matching, so your patterns are tested against {app}.{resource-type}.{event-type}.
You define event triggers using matching rules. Each rule contains a regex pattern that the engine tests against the stripped event name. If any rule matches, the workflow starts.
Configuration:
Example:
startWhen:
matchingRules:
- eventNameRegex: "grafana_irm_app\\.incident\\.updated"
- eventNameRegex: "grafana_irm_app\\.alertgroup\\.updated"A workflow can have multiple matching rules. The workflow triggers if any rule matches.
Available event sources
The following table lists the event sources that can trigger workflows:
Event names follow the pattern {app}.{resource-type}.{event-type}.
Schedule trigger
A schedule trigger starts a workflow at recurring times using a cron expression. Schedules use the standard five-field Unix cron format and run in UTC.
Configuration:
Example:
startWhen:
schedules:
- "0 9 * * 1-5"
- "0 0 1 * *"A workflow can have multiple schedules. Each schedule triggers the workflow independently.
Cron field reference:
Manual trigger
A manual trigger starts a workflow from the editor on demand. Any workflow can be triggered manually regardless of whether it has event or schedule triggers configured.
To trigger a workflow manually in the editor, click Run and provide a CloudEvents-shaped JSON event in the Trigger Workflow dialog. For details, refer to Configure triggers.
Manual-only workflows have an empty startWhen section:
startWhen:
matchingRules: []
schedules: []Combine triggers
A workflow can have both event and schedule triggers. The workflow starts when any matching rule matches an incoming event or when any schedule fires.
startWhen:
matchingRules:
- eventNameRegex: "grafana_irm_app\\.incident\\.updated"
schedules:
- "0 9 * * 1-5"

