Template Variables
FireHydrant uses the Liquid templating language. A templating language allows you to set variables/placeholders that are replaced with actual data at execution time.
You can use template variables to reference many types of incident data, such as name and description, milestones, roles, user assignments, and more.
In FireHydrant, you can use template variables to dynamically interpolate FireHydrant incident data into multiple places, including:
- Runbook steps
- Jira field mappings
- Command Extensions
- ...and more!
As an example, in a Runbook step, you can use an incident's name and description with {{ incident.name }}
and {{ incident.description }}
in the fields. When the Runbook step executes on a real incident, those placeholders will be filled with the actual name and description of the incident.
To minimize impact to your instance through repeated test incidents, we recommend testing these template variables using the Liquid playground. Additionally, you can check out our liquid template examples in this GitHub repo.
Runbook steps now also feature an output preview, where you can select previous incidents as example data to preview how your templating would have looked:

Liquid/JSON preview on a Runbook step
Incident Fields and Variables
This list includes the properties in the FireHydrant API that are most often used as template variables. To see all available FireHydrant incident properties refer to the IncidentEntity model (for incident data) and PostmortemReportEntity model (for retrospective data).
All left-most fields are accessible under the main incident
object with {{ incident.VAR }}
, where VAR
is the name of the field. Visit the sections in the table of contents to the right to see each section's available variables.
General Incident Fields
Key | Type | Description |
---|---|---|
active | boolean | Whether the incident is still ongoing (true when in any milestone prior to resolved or post-incident phase) |
ai_incident_summary | string | AI-generated summary of the incident (requires AI features enabled ) |
created_at | datetime | UTC time when the incident was created in ISO 8601 format |
created_by | object | Object representing the user who declared the incident. For additional |
↳ email | string | Email address of the user who declared |
↳ id | string | UUID representing the user who declared the incident |
↳ name | string | Name of the user who declared the incident |
↳ source | string | Where the user declared the incident, for example firehydrant_user (web interface) or slack |
current_milestone | string | The current milestone that the incident is in |
customer_impact_summary | string | A description or summary of the customer impact |
description | string | A more detailed description of the incident |
id | string | UUID representing the incident |
incident_url | string | URL for the incident page in the web UI |
last_note | object | Object representing the very latest update and the time it was posted |
↳ body | string | Most recent incident update note |
↳ created_at | datetime | UTC timestamp of when the latest note was posted |
last_update | string | The same as last_note.body |
recent_updates | object[] | Array of recent update objects |
↳ body | string | Most recent incident update note |
↳ timestamp | string | ISO 8601 timestamp of when the note was made |
name | string | Name of the incident |
number | integer | Incident number auto-assigned by FireHydrant. This number automatically increments with each incident created and cannot be changed |
organization | object | Object representing the organization this incident was opened in |
↳ id | string | UUID representing the organization |
↳ name | string | Name of the organization |
organization_id | string | The same as organization.id |
private_id | string | Private ID of the incident's internal status page |
report_id | string | UUID for the retrospective report. This value is only populated if the incident is resolved . |
retro_exports | object[] | Array of objects representing all of the retrospective exports (e.g., Confluence, Google Docs, etc.) |
↳ created_at | datetime | UTC time of when the export was created in ISO 8601 format |
↳ display_text | string | Title of the exported document |
↳ href_url | string | URL of the exported document |
↳ icon_url | string | URL of the destination application's icon |
↳ id | string | UUID for the export |
severity | string | Current severity of the incident |
started_at | datetime | UTC time of when an incident was started/declared in ISO 8601 format |
tag_list | string[] | Array of tags attached to the incident |
links | object | Array of links on the incident |
↳ text | string | The label/title for the link |
↳ url | string | URL of the link |
Milestone Fields
Key | Type | Description |
---|---|---|
current_milestone | string | Current Milestone state of the incident represented by its slug |
milestones | object[] | Array of objects representing each time the incident transitioned milestones |
↳ created_at | datetime | UTC timestamp of when the milestone was set |
↳ duration | string | Measure of the milestone's duration in seconds, printed in the format of P[months]M[days]DT[hours]H[minutes]M[seconds]S |
↳ id | string | UUID of the milestone transition |
↳ occurred_at | datetime | UTC timestamp of the milestone |
↳ type | string | The milestone, represented by its slug |
↳ updated_at | datetime | UTC timestamp of when the milestone was last updated |
Role and User Assignment Fields
Key | Type | Description |
---|---|---|
role_assignments | object[] | Array of objects containing the assigned users and their roles |
↳ created_at | datetime | UTC timestamp for when the role was assigned |
↳ id | string | UUID for the assignment |
↳ incident_role | object | Object representing the incident role that the user was assigned to. For the full list of available parameters, see IncidentRoleEntity |
↳ status | string | Current status of this role assignment (active or inactive ) |
↳updated_at | datetime | UTC timestamp for when the role assignment was updated |
↳ user | object | Object representing the user for this assignment. For the full list of available parameters, see UserEntity |
team_assignments | object[] | Array of objects containing the assigned teams |
↳ created_at | datetime | UTC timestamp of when the team assignment occurred |
↳ id | string | UUID for the assignment (not the team's ID) |
↳ status | string | Current status of the team assignment (active or inactive ) |
↳ team | object | Object representing the team that was assigned. For the full list of available parameters, see TeamEntity |
↳ updated_at | datetime | UTC timestamp for when the team assignment was last updated |
Custom Fields
Key | Type | Description |
---|---|---|
custom_fields | object{} | Object containing custom field objects keyed by their slugs (for example, incident.custom_fields.deployment_silo ) |
↳ display_name | string | The human-friendly display name for the custom field |
↳ field_id | string | UUID representing the field |
↳ slug | string | Unique, humanized identifier for the field |
↳ value | string | String value for the field that varies in content. - If value_type = array , this field will be a string with all array values joined by a comma- If value_type = string , this will just be the specified string or chosen value- If value_type = datetime , this will be an ISO 8601 string of the date and time |
↳ value_array | string[] | Array of chosen values. Only exists if value_type = array |
↳ value_string | string | Value of the custom field. Only exists if value_type = string |
↳ value_type | string | Type of the custom field (string , array , datetime ) |
Custom field attributes (e.g., display_name, value) can be accessed directly by slug name or can be iterated using Liquid's for loop, which will return each custom field as an object.
## Accessing the value of custom field by slug
{{ incident.custom_fields.slug.value }}
## Iterating over all custom fields to display the name and the value
{% for field in incident.custom_fields %}
{{ field.name }}
{{ field.value }}
{% endfor %}
Audiences
Key | Type | Description |
---|---|---|
audiences | object{} | Object containing audience objects keyed by their slugs (for example, incident.audiences.executive-team ) |
↳ content | string | The content of the given summary for that audience |
↳ details | object{} | Object containing detail objects keyed by their slugs (for example, incident.audiences.executive-team.details.current-impact ) |
↳ content | string | The content of the given detail for the specified audience |
Service Catalog Fields
Key | Type | Description |
---|---|---|
services | object[] | Array of Service objects containing key parameters |
↳ id | string | UUID of the service |
↳ name | string | Name of the service |
↳ labels | object{} | Object containing the key:value pairs of all the labels for the service. |
↳ ↳ {KEY} | string | Whatever labels you've configured for a service. For example, if you have a label called region with value us-east-1 , then you would access this via *.labels.region or *.labels['region'] and these will return us-east-1 |
functionalities | object[] | Array of Functionality objects containing key parameters |
↳ id | string | UUID of the functionality |
↳ name | string | Name of the functionality |
↳ labels | object{} | Object containing the key:value pairs of all the labels for the functionality |
↳ ↳ {KEY} | string | Whatever labels you've configured for a functionality. For example, if you have a label called region with value us-east-1 , then you would access this via *.labels.region or *.labels['region'] and these will return us-east-1 |
environments | object[] | Array of Environment objects containing key parameters |
↳ id | string | UUID of the environment |
↳ name | string | Name of the environment |
impacts | object[] | Array of impact objects |
↳ id | string | UUID of the noted impact/instance. Note: This is not the UUID of the component itself (e.g., a service or functionality). For that, see below under impact |
↳ type | string | One of service , functionality , or environment |
↳ impact | object{} | Object containing the impacted component |
↳ ↳ id | string | UUID of the impacted component |
↳ ↳ name | string | Name of the impacted component |
↳ condition | object{} | Object containing the impacted component's condition |
↳ ↳ id | string | UUID of the condition |
↳ ↳ name | string | Name of the condition (e.g., unavailable , degraded , etc.). This is customizable. |
change_events | object[] | Array of change event objects |
↳ id | string | UUID of the change event |
↳ summary | string | Summary or title of the change event |
↳ services | object[] | Array of objects detailing the services impacted by this change event |
↳ ↳ id | string | UUID of the modified service |
↳ ↳ name | string | Name of the modified service |
↳ environments | object[] | Array of objects detailing the environments impacted by this change event |
↳ ↳ id | string | UUID of the modified environment |
↳ ↳ name | string | Name of the modified environment |
↳ started_at | string | Datetime of when the change event occurred |
↳ impact | string | One of suspect , caused , fixed , dismissed |
Tasks/Follow-Ups
tasks
orfollow_ups
(array of objects): List of tasks or follow-ups created on the incident. Tasks and follow-ups use the same data model, but some parameters will not be relevant depending on the type. See below.id
: FireHydrant UUID for this task/follow-upsummary
: Title/summarydescription
: The description. Alwaysnull
for Tasks.state
: The current state of the task/follow-up. Possible values areopen
,in_progress
,cancelled
, anddone
type
:task
orfollow_up
assignees
(array of objects): Who's assigned to the task/follow-upid
: FireHydrant UUID for the username
: User's namesource
:firehydrant_user
,bot_user
, orpatchy
. For Follow-Ups, will basically always befirehydrant_user
email
: User's email address
priority
: The priority, defined in Settings > Ticketing settings. Alwaysnull
for Tasks.created_by
(object): Who created the task/follow-upid
: FireHydrant UUID for the username
: User's namesource
:firehydrant_user
,bot_user
, orpatchy
. For Follow-Ups, will basically always befirehydrant_user
email
: User's email address
attachments
(object): Any links or other attachments. Always an empty array for Tasks.id
: UUID for the link attachment. Generally not used/needed for anythingtype
: Usuallylink
display_text
: External link's display text/titlehref_url
: The URL for the external linkicon_url
: Link to the icon FireHydrant uses for the integrationeditable
: Alwaysfalse
deletable
: Alwaysfalse
created_at
: ISO 8601 datetime representing when the ticket was createdupdated_at
: ISO 8601 datetime representing when the ticket was last updatedtag_list
(array of strings): List of ticketing tags (not to be confused with incident tags). Always empty for Tasks.incident_id
: FireHydrant UUID of the incident this task/follow-up was created fordue_at
: ISO 8601 format datetime of when the Task is due. Currently not supported for follow-ups.link
: Linked external resource, usually a project ticket for follow-ups. Always empty for Tasks.id
: FireHydrant UUID for the attachmenttype
: Alwayslink
display_text
: The ticket's code (e.g., "ABC-123")href_url
: The URL to the external ticketicon_url
: Link to the icon FireHydrant uses for the integrationeditable
: Alwaysfalse
deletable
: Alwaysfalse
Integrations-Related Fields
-
channel_name
: The name of the Slack channel for the incident. -
channel_reference
: The Slack-formatted encoded link for the Slack channel. You can use this reference number in a Slack message to create a link to the incident channel. -
channel_id
: The Slack ID for the channel (not formatted for creating links). -
channel_status
: Indicates whether the Slack channel is operational. -
private_status_page_url
: The url of the private status page for the incident. -
incident_tickets
** (array of objects):-
id
: The incident ticket ID. -
summary
: Summary of information in the ticket. -
Description
: Description of the incident as provided in the ticket. -
state
: State of the ticket: open , in_progress , done , etc. -
type
: Ticket type: Incident , follow_up , or task. -
assignees
: The incident ticket ID. -
created_by
(object):-
id
: ID of the user who created the ticket. -
name
: Name of the user who created the ticket. -
source
: Ticketing source: Slack , PagerDuty , FireHydrant , etc. -
email
: Email address for the user who created the ticket.
-
-
attachments
(array of objects):-
display_text
: The text displayed that links to the ticket. -
href_url
: The URL for the ticket. -
icon_url
: The URL for the icon of the ticketing provider. -
type
: The type of ticket.
-
-
Note:
At this time, only the incident ticket is included in this array of objects, not Tasks or Follow-Ups.
Alternatively, you may use ticket
, which is the only ticket of type: Incident, and also supports any of the attributes above. This ticket
object has the following attributes:
-
ticket
(object): Singular object containing the incident ticket-
link
: The reference to a corresponding external integration ticket or issue-
display_text
: The text displayed that links to the ticket. -
href_url
: The URL for the ticket. -
icon_url
: The URL for the icon of the ticketing provider. -
type
: The type of ticket; in this case, it's always "link"
-
-
-
conference_bridges
(array of objects):-
id
: UUID of the conference object as stored on FireHydrant (not the Zoom/Google Meet ID) -
attachments
(array of objects):-
type
: Attachment type: image, alert, etc. -
display_text
: The text displayed describes the conference bridge. -
href_url
: The URL for the conference bridge (for example,https://us02web.zoom.us/j/1234567890
) -
icon_url
: The URL for the icon of the conference bridge provider.
-
-
-
incident_channels
(array of objects): List of channels attached to the incidentid
: Slack ID for the channelname
: The name of the channelsource
: The originating source of the channel (e.g.slack
)url
: The URL for the channelicon_url
: URL for the source/channel's icon
Retrospective Fields
The retro
data object is only available after an incident has moved to the 'retrospective started' milestone. This object can be directly referenced like an incident, for example,{{ retro.name }}
.
-
retro
(object):-
name
: The name of the report -
published_at
: When the retro was completed -
questions
(array of objects): An array of custom questions set from the Retrospective Configuration tab-
title
: The title of the question -
body
: The answer to the question -
updated_at
: When the question was last updated
-
-
contributing_factors
(array of objects): An array of the Five Whys section in contributing factors-
summary
: The content of the contributing factor -
position
: The position in the list of Five Whys
-
-
incident_active_duration
: The duration that the incident was in an active state. Active is defined as the Started through Mitigated milestone -
starred_events
(array of objects): An array of the starred events from the incident-
occurred_at
: When the event occurred -
created_by
: Who created the event -
summary
: The content of the contributing factor -
body
: The content of the event
-
-
Special FireHydrant Liquid Variables and Filters
Liquid templating is a general templating system, but it does allow for the creation of custom filters, functions, and more. The following is a list of custom FireHydrant Liquid variables/functions that you can use:
Value | Type | Usage | Description |
---|---|---|---|
toJSON | Function | {{ some_variable | toJSON }} | Prints the specified variable/object in JSON. Useful for debugging |
date_pt date_mt date_ct date_et date_utc | Variable | incident-my_inc-{{ date_pt }} | Convenient variables for getting the current date (YYYY-MM-DD) according to US timezones. Note: Only available in Create or rename Incident Slack channel Runbook step |
Cookbook
The following section contains examples of using Liquid templating to interpolate incident data.
Slack Channel URL
- Summary: Get the URL to the Slack channel and display the link using markdown.
- Usage: Any external comms step, like Notify with Custom Message or Email, etc., where you want to link to the incident Slack channel.
[Incident Channel]({{ incident.incident_channels[0].url }})
Confluence Retro Additions
- Summary: Display Tags, Labels, and Jira tickets in Confluence export
- Usage: Add to the Export to Confluence runbook step
### Tags
| Tags |
|-----------|
{%- for tag in incident.tag_list %}
| {{ tag }} |
{%- endfor %}
### Labels
| Key | Value |
|-----|-------|
{%- for label in incident.labels %}
| {{ label[0] }} | {{ label[1] }} |
{%- endfor %}
### Jira
| Ticket Name | Link |
|-------------|------|
{%- for ticket in incident.incident_tickets[0].attachments %}
| {{ ticket.display_text }} | {{ ticket.href_url }} |
{%- endfor %}
Print Duration of Incident
- Summary: Return the current or total duration of the incident. Calculates from Resolved milestone or
now
if the incident is still open. - Usage: Custom message to channel or email runbook steps
{% assign started = incident.milestones | where: "type", "started" | first %}
{% assign started_at = started.occurred_at | date: "%s" %}
{% assign resolved = incident.milestones | where: "type", "resolved" | first %}
{% if resolved %}
{% assign resolved_at_or_now = resolved.occurred_at | date: "%s" %}
{% else %}
{% assign resolved_at_or_now = "now" | date: "%s" %}
{% endif %}
{% assign SECONDS_PER_MINUTE = 60 %}
{% assign SECONDS_PER_HOUR = SECONDS_PER_MINUTE | times: 60 %}
{% assign SECONDS_PER_DAY = SECONDS_PER_HOUR | times: 24 %}
{% assign remainder = resolved_at_or_now | minus: started_at | modulo: SECONDS_PER_DAY %}
{% assign days = resolved_at_or_now | minus: started_at | divided_by: SECONDS_PER_DAY | floor %}
{% assign hours = remainder | divided_by: SECONDS_PER_HOUR | floor %}
{% assign remainder = remainder | modulo: SECONDS_PER_HOUR %}
{% assign minutes = remainder | divided_by: SECONDS_PER_MINUTE | floor %}
{% assign seconds = remainder | modulo: SECONDS_PER_MINUTE %}
This incident has been active for {{ days }}d {{ hours }}h {{ minutes }}m {{ seconds }}s
Print all responders' names, emails, and roles
- Summary: Return all responders' information. This information is available in other places today like the Command Center or any Notify messages in Slack, but could be useful in e.g. an email.
- Usage: The Send an email notification runbook step, in Jira/Confluence step descriptions, etc.
{% for role in incident.role_assignments -%}
**{{ role.incident_role.name }}**: {{ role.user.name }} \<{{ role.user.email }}\>
{% endfor %}
Print overview message of current information and next update ETA
- Summary: Using Liquid's built in time mechanics, we do time conversions using simple math and then display with formatting.
- Usage: Anywhere, but likely Email or Custom Message steps
{% assign started = incident.milestones | where: "type", "started" | first %}
**CURRENT STATUS**: {{ incident.current_milestone }}
**SEVERITY**: {{ incident.severity }}
**DESCRIPTION**: {{ incident.description }}
**START TIME**: {{ started.occurred_at | date: "%s" | minus: 28800 | date: "%Y-%m-%d %H:%M" }}
**LAST UPDATE**:
- At: {{ incident.last_note.created_at | date: "$s" | minus: 28800 | date: "%Y-%m-%d %H:%M" }}
- Note: {{ incident.last_note.body }}
**NEXT UPDATE**: {{ incident.last_note.created_at | date: "%s" | minus: 27000 | date: "%Y-%m-%d %H:%M" }}
In the example above, updates are posted in 30-minute intervals and in PST. Dates are stored in UTC, so we first convert them to a date object that Liquid can work with using date
, and then we subtract seconds from the time to convert from UTC to PST with minus
before formatting the output to print.
Limitations
Currently, the use of where:
in Liquid templating can only be used to filter on a top-level parameter. For example, given the following JSON object:
[
{
"id": "3ebfb4da-e2a4-4ae7-9e44-e34df78589e0",
"status": "active",
"created_at": "2025-01-08T00:47:43.587Z",
"updated_at": "2025-01-08T00:47:43.587Z",
"incident_role": {
"id": "a75e35b4-b228-4f1a-b455-6de2aec46a1b",
"name": "Incident Commander",
"summary": "The Incident Commander is responsible for overall management, communication, and task delegation during incidents.",
"description": "The Incident Commander holds the high-level state of an incident and is responsible for overall management, communicating with stakeholders, triaging and delegating work, and most importantly, motivating and driving the team through the situation.",
"created_at": "2022-02-09T17:18:05.678Z",
"updated_at": "2023-05-09T16:48:44.554Z",
"discarded_at": null
},
"user": {
"id": "a561dd61-5ff6-480b-aaaf-87bba4ed6d74",
"name": "John Doe",
"email": "[email protected]",
"slack_user_id": "U032E92MN6S",
"slack_linked?": true,
"created_at": "2022-02-09T17:18:06.577Z",
"updated_at": "2023-10-13T21:25:28.643Z",
"signals_enabled_notification_types": [
"sms",
"apns"
]
}
}
]
...you can filter on top-level parameters like status = "active"
, but you would not be able to do checks against any nested parameters (e.g., incident_role.name = "Incident Commander"
). This is due to a limitation in the Liquid templating Ruby gem we use underneath the hood.
The recommended workaround is to use more primitive filters like for
and if
statements. For example:
// DOES NOT WORK
{% assign incidentManagers = incident.role_assignments | where: "incident_role.name", "Incident Mnaager" %}
// DOES WORK
{% for role in incident.role_assignments %}
{% if role_assignment.incident_role.name == "Incident Manager" %}
// etc...
{% endif %}
{% endfor %}
Other Resources
Updated 9 days ago