Documentation Index
Fetch the complete documentation index at: https://docs.rootly.com/llms.txt
Use this file to discover all available pages before exploring further.
Rootly registers the filters below on top of the standard Liquid filters. Use them anywhere you can author a Liquid template — workflow tasks, message templates, post-mortem templates, custom field templates, and the in-product Liquid Explorer.
Lookups & Filtering
find
find: arg1, 'arg2'
arg1. String
arg2. String
// Pretending object is the following object [{"id": "apple"}, {"id": "banana"}]
{{ object | find: 'id', 'banana' }}
// Output
// {"id": "banana"}
where
Filters an array, returning every element that matches. Pair with find (returns the first match) when you need all results.
where: 'arg1', 'arg2'
arg1. String — key path, dot-separated for nested lookups
arg2. String (optional) — when omitted, keeps elements where arg1 is truthy
// Pretending object is [{"role":"commander","name":"Alice"},{"role":"commander","name":"Bob"},{"role":"scribe","name":"Cara"}]
{{ object | where: 'role', 'commander' }}
// Output
// [{"role":"commander","name":"Alice"},{"role":"commander","name":"Bob"}]
{{ incident.subscribers | where: 'role', 'commander' | size }}
// Count of commanders subscribed to the incident
get
// Pretending object is the following object {"id": "id", "incident": {"title": "Something is on fire!"}}
{{ object | get: 'incident.title' }}
// Output
// Something is on fire!
slice
slice: '\*arg'
arg. String
- … As many args as you need
// Pretending object is the following object {"key": "hello", "value": "world", "foo": "bar"}
{{ object | slice: 'key' }}
// Output
// {"key": "hello"}
{{ object | slice: 'key', 'foo' }}
// Output
// {"key": "hello", "foo": "bar"}
Arrays & Hashes
flatten
// Pretending object is the following object \["1", "2", \["3"\]\]
{{ object | flatten }}
// Output
// \["1","2","3"\]
push
Appends a value to the end of an array. A comma-separated string is split into an array first.
{{ '1,2,3' | push: '4' }}
// Output
// ["1", "2", "3", "4"]
pop
Removes the last n elements from an array.
{{ '1,2,3,4' | pop: 2 }}
// Output
// ["1", "2"]
shift
Removes the first n elements from an array.
{{ '1,2,3,4' | shift: 2 }}
// Output
// ["3", "4"]
unshift
Prepends a value to the start of an array. A comma-separated string is split into an array first.
{{ '2,3,4' | unshift: '1' }}
// Output
// ["1", "2", "3", "4"]
keys
Returns the keys of a hash as an array. Useful for iterating slug-keyed objects like team.services, team.functionalities, and team.groups.
// Pretending team.services is {"api": {...}, "web": {...}}
{{ team.services | keys }}
// Output
// ["api", "web"]
{% for slug in team.services | keys %}- {{ slug }}
{% endfor %}
values
Returns the values of a hash as an array.
{{ team.services | values | size }}
// Number of services on the team
to_values
// Pretending object is the following object {"key": "hello", "value": "world"}
{{ object | to_values }}
// Output
// \[{"value":"world"}\]
{{ object | to_values: 'key' }}
// Output
// \[{"value":"hello"}\]
JSON
to_json
Also available as json.
// Pretending object is the following object [{"key": "hello", "value": "world"}]
{{ object | to_json }}
// Output
// [{"key":"hello","value":"world"}]
parse_json
Parses a JSON string into a hash or array — the inverse of to_json. Useful when an alert payload field arrives as a stringified JSON blob.
{{ '{"key":"hello"}' | parse_json | get: 'key' }}
// Output
// hello
{{ alert.data.body | parse_json | get: 'severity' }}
// Reach into a stringified JSON payload nested in alert data
Returns the input unchanged if it can’t be parsed.
Dates & Time
smart_date
{{ 'now' | smart_date: 'tomorrow' }}
// Output
// 2023-06-29 12:00:00 -0700
date_add
date_add: amount, 'date_part'
amount. Integer (positive to add, negative to subtract)
date_part. String - one of: year, month, day, hour, minute, second, millisecond (plurals supported)
Adds a specified amount of time to a date. Works with ‘now’, ‘today’, ISO date strings, Time, and Date objects.
{{ 'now' | date_add: 1, 'day' | date: '%Y-%m-%d' }}
// Output
// 2023-06-30 (tomorrow)
{{ '2023-06-29T10:30:00Z' | date_add: 2, 'hours' | date: '%Y-%m-%d %H:%M' }}
// Output
// 2023-06-29 12:30
{{ incident.target_resolve_date | date_add: -30, 'minutes' }}
// Output
// 30 minutes before the target resolve date
date_minus
date_minus: amount, 'date_part'
amount. Integer (positive to subtract, negative to add)
date_part. String - one of: year, month, day, hour, minute, second, millisecond (plurals supported)
Subtracts a specified amount of time from a date. Works with ‘now’, ‘today’, ISO date strings, Time, and Date objects.
{{ 'now' | date_minus: 7, 'days' | date: '%Y-%m-%d' }}
// Output
// 2023-06-22 (a week ago)
{{ incident.created_at | date_minus: 1, 'hour' | date: '%Y-%m-%d %H:%M' }}
// Output
// 1 hour before the incident was created
{{ 'today' | date_minus: 6, 'months' }}
// Output
// 6 months ago
to_iso8601
// Pretending object is the following datetime
{{ object | to_iso8601 }}
// Output
// 2023-06-29T12:00:00-07:00
to_utc
Converts a date to UTC timezone. Works with ‘now’, ‘today’, ISO date strings, Time, and Date objects.
{{ incident.started_at | to_utc | date: '%Y-%m-%d %H:%M:%S' }}
// Output
// 2023-06-29 15:30:00 (converted to UTC)
{{ 'now' | to_utc | date: '%Y-%m-%d %H:%M:%S UTC' }}
// Output
// 2023-06-29 19:45:23 UTC
{{ '2023-06-29T10:30:00-05:00' | to_utc | date: '%Y-%m-%d %H:%M:%S' }}
// Output
// 2023-06-29 15:30:00
Useful for synchronizing incident timestamps with timeline values, ensuring all dates display in UTC regardless of user timezone.
in_time_zone
in_time_zone: 'time_zone'
time_zone. Any timezone listed in Timezones
{{ now | in_time_zone: 'Europe/London' | date: '%Y-%m-%d %H:%M %Z' }}
See Timezones for available values
distance_of_time_in_words
distance_of_time_in_words: 'arg', 'precise'
arg. String (optional)
precise. String (optional)
{{ 3720 | distance_of_time_in_words }}
// Output
// about 1 hour
{{ 3720 | distance_of_time_in_words: 0, 'precise' }}
// Output
// 1 hour and 2 minutes
{{ 'May 1, 2020' | distance_of_time_in_words: 'May 31, 2020' }}
// Output
// about 1 month
{{ 'May 1, 2020' | distance_of_time_in_words: 'May 31, 2020', 'precise' }}
// Output
// 4 weeks and 2 days
distance_of_time_in_words_to_now
distance_of_time_in_words_to_now: 'precise'
precise. String (optional)
{{ 'May 1, 2020' | distance_of_time_in_words_to_now }}
// Output
// over 2 years
{{ 'May 1, 2020' | distance_of_time_in_words_to_now: 'precise' }}
// Output
// 2 years and 7 months
Tables
to_table
to_table: 'table_type', 'title', 'time_zone', 'format'
table_type. String — events or action_items
title. String — table heading
time_zone. String — any timezone listed in Timezones
format. String — ascii, markdown, html, or atlassian_markdown
The events type renders timeline columns: Date, User, Event. The action_items type renders: Creation Date, Due Date, Kind, Priority, Status, Assignee, Summary.
{{ incident.events | to_table: 'events', 'Timeline', 'America/Los_Angeles', 'markdown' }}
{{ incident.action_items | to_table: 'action_items', 'Action Items', 'UTC', 'atlassian_markdown' }}
Regex
regex_match
Find first match and return array with full match and capture groups
regex_match: 'regex', 'flags'
regex a ruby regular expression
flags optional string with regex flags: ‘i’ (case insensitive), ‘m’ (multiline), ‘x’ (extended)
{{ 'Key1: value1' | regex_match: 'Key(\d+): (.+)' | first }}
// Output
// Key1: value1
{{ 'Key1: value1' | regex_match: 'Key(\d+): (.+)' | last }}
// Output
// value1
{{ 'user@example.com' | regex_match: '(\w+)@(\w+\.\w+)' | size }}
// Output
// 3 (full match + 2 capture groups)
// Case insensitive matching
{{ 'HELLO world' | regex_match: 'hello', 'i' | first }}
// Output
// HELLO
// Multiline matching
{{ "Line 1\nLine 2\nDone" | regex_match: 'line.*done', 'im' | first }}
// Output
// Line 1
// Line 2
// Done
Perfect for extracting data from email alert payloads:
{{ alert.body | regex_match: 'Severity: (.+)' | last }}
// Extract severity level from alert body
{{ alert.body | regex_match: 'Host: ([\w\.-]+)' | last }}
// Extract hostname from alert
regex_match_all
Find all matches and return array of results
regex_match_all: 'regex', 'flags'
regex a ruby regular expression
flags optional string with regex flags: ‘i’ (case insensitive), ‘m’ (multiline), ‘x’ (extended)
{{ 'foo 123 bar 456 baz 789' | regex_match_all: '\d+' | size }}
// Output
// 3
{{ 'foo 123 bar 456 baz 789' | regex_match_all: '\d+' | first }}
// Output
// 123
{{ 'foo 123 bar 456 baz 789' | regex_match_all: '\d+' | last }}
// Output
// 789
// Extract all email addresses
{{ 'Contact support@example.com or admin@test.org' | regex_match_all: '[\w\.-]+@[\w\.-]+\.\w+' | size }}
// Output
// 2
// Case insensitive matching
{{ 'ERROR: failed, error: timeout' | regex_match_all: 'error: (\w+)', 'i' | first }}
// Output
// failed
Ideal for parsing multiple values from alert payloads:
// Extract all IP addresses from alert body
{{ alert.body | regex_match_all: '\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b' }}
// Extract all key-value pairs
{{ alert.body | regex_match_all: 'Key\d+: ([^\n]+)' }}
regex_replace
Global replace
regex_replace: 'regex', 'replacement'
regexp a ruby regular expression
replacement a ruby regular expression
{{ 'foo bar 123 456' | regex_replace: '\d+', 'baz' }}
// Output
// foo bar baz baz
regex_replace_first
First match replace
regex_replace_first: 'regex', 'replacement'
regexp a ruby regular expression
replacement a ruby regular expression
{{ 'foo bar 123 456' | regex_replace_first: '\d+', 'baz' }}
// Output
// foo bar baz 456
regex_remove
Global match remove
regex_remove: 'regex'
regexp a ruby regular expression
{{ 'foo bar 123 456' | regex_remove: '\d+' }}
// Output
// foo bar
regex_remove_first
First match remove
regex_remove_first: 'regex'
regexp a ruby regular expression
{{ 'foo bar 123 456' | regex_remove_first: '\d+' }}
// Output
// foo bar 456
Slack Helpers
to_slack_markdown
Converts standard Markdown into Slack’s mrkdwn flavor (e.g., **bold** becomes *bold*, link syntax is rewritten, lists are formatted). Use in any task that posts to Slack.
{{ '**Critical**: payment service is down. See [runbook](https://example.com).' | to_slack_markdown }}
// Output
// *Critical*: payment service is down. See <https://example.com|runbook>.
Returns an empty string for non-string inputs.
format_text_for_slack
Escapes characters that would break a Slack JSON payload — converts double quotes to single quotes and escapes newlines and carriage returns.
{{ 'She said "hello"
line two' | format_text_for_slack }}
// Output
// She said 'hello'\nline two
Use when interpolating user-supplied text into a hand-built Slack Block Kit JSON payload.
String Manipulation
dasherize
{{ 'hello_world' | dasherize }}
// Output
// hello-world
parameterize
parameterize
separator (default to ’-‘)
{{ 'Hello World' | parameterize }}
// Output
// hello-world
{{ 'Hello World' | parameterize: '_' }}
// Output
// hello_world
camelize
{{ 'hello world' | camelize }}
// Output
// Hello world
titleize
{{ 'hello world' | titleize }}
// Output
// Hello World
singularize
{{ 'cars' | singularize }}
// Output
// car
pluralize
{{ 'car' | pluralize }}
// Output
// cars
humanize
{{ '0' | humanize }}
// Output
// No
{{ '1' | humanize }}
// Output
// Yes
{{ 'incident_management' | humanize }}
// Output
// Incident Management
shuffle
{{ '123456789' | shuffle }}
// Output
// 973426581
Encoding
base64_encode
Base64-encodes a string using strict encoding (no line breaks).
{{ 'Aladdin:open sesame' | base64_encode }}
// Output
// QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Common use — build a Basic auth header for a workflow HTTP task:
Authorization: Basic {{ secrets.username | append: ':' | append: secrets.password | base64_encode }}
base64_decode
Decodes a strict-Base64 string. Raises a Liquid argument error on invalid input.
{{ 'QWxhZGRpbjpvcGVuIHNlc2FtZQ==' | base64_decode }}
// Output
// Aladdin:open sesame
base64_url_safe_encode
Base64-encodes using the URL-safe alphabet (- and _ instead of + and /).
{{ 'subjects?ids=1,2,3' | base64_url_safe_encode }}
// Output
// c3ViamVjdHM_aWRzPTEsMiwz
base64_url_safe_decode
Decodes a URL-safe Base64 string.
{{ 'c3ViamVjdHM_aWRzPTEsMiwz' | base64_url_safe_decode }}
// Output
// subjects?ids=1,2,3
Markdown & HTML
markdown_to_html
Renders Markdown to sanitized HTML — useful when an integration expects HTML input (e.g., email templates, webhook payloads).
{{ '# Title
This is **bold** text.' | markdown_to_html }}
// Output
// <h1>Title</h1>
// <p>This is <strong>bold</strong> text.</p>
Output is sanitized to a safelist of tags and attributes; links get rel="nofollow noopener noreferrer". Returns an empty string for nil input.
html_to_markdown
Inverse of markdown_to_html. Handles most common HTML elements including headings, paragraphs, lists, links, code blocks, and tables.
{{ '<h1>Title</h1><p>This is <strong>bold</strong> text.</p>' | html_to_markdown }}
// Output
// # Title
//
// This is **bold** text.
{{ '<ul><li>Item 1</li><li>Item 2</li></ul>' | html_to_markdown }}
// Output
// - Item 1
// - Item 2
Returns empty string for nil or empty input. Preserves original HTML on conversion errors.
URLs
shortener
{{ 'https://rootly.com/account/incidents/123456' | shortener }}
// Output
// https://root.ly/1234
open_ai_completion
Sends the input string to OpenAI as the user prompt and returns the completion text. Useful for inline summarization or text transformation directly inside a Liquid template.
{{ alert.description | open_ai_completion }}
// Returns OpenAI's completion using the alert description as the prompt
For most use cases, prefer the dedicated AI workflow tasks (Create OpenAI Chat Completion, Create Anthropic Chat Completion, etc.) over this filter — they expose model selection, system prompts, temperature, and message history, which this filter does not.
Returns "something went wrong" on failure.
Integration Converters
Rootly’s severity, priority, and status enums don’t always map 1-to-1 to vendor enums. Converter filters translate a Rootly value to the equivalent vendor value when building HTTP payloads or workflow task arguments. They take no extra arguments unless noted.
{{ incident.severity | linear_severity_converter }}
// Maps Rootly severity to Linear's severity scale
{{ action_item.priority | clickup_priority_converter }}
// Maps Rootly priority to ClickUp's priority scale
| Filter | What it converts |
|---|
linear_severity_converter | Rootly severity → Linear |
linear_priority_converter | Rootly priority → Linear |
trello_archivation_converter | Rootly status → Trello archivation |
asana_completion_converter | Rootly status → Asana completion |
github_completion_converter | Rootly status → GitHub issue state |
gitlab_completion_converter | Rootly status → GitLab issue state |
shortcut_archivation_converter | Rootly status → Shortcut archivation |
shortcut_completion_converter | Rootly status → Shortcut completion |
zendesk_severity_converter | Rootly severity → Zendesk |
zendesk_priority_converter | Rootly priority → Zendesk |
zendesk_completion_converter | Rootly status → Zendesk (takes a type arg) |
service_now_severity_converter | Rootly severity → ServiceNow |
service_now_completion_converter | Rootly status → ServiceNow |
freshservice_severity_converter | Rootly severity → Freshservice |
freshservice_priority_converter | Rootly priority → Freshservice |
freshservice_completion_converter | Rootly status → Freshservice (takes a type arg) |
opsgenie_completion_converter | Rootly status → Opsgenie (takes a type arg) |
clickup_severity_converter | Rootly severity → ClickUp |
clickup_priority_converter | Rootly priority → ClickUp |
motion_severity_converter | Rootly severity → Motion |
motion_priority_converter | Rootly priority → Motion |