Skip to main content

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.

Every workflow action stores its output after it completes. Subsequent actions in the same workflow can reference those outputs using Liquid template syntax. This lets you chain actions together — for example, fetch data with an HTTP request and pass the response into an AI prompt or a second API call.

Syntax

Reference a previous action’s output using the tasks object and the action’s slug:
{{ tasks.<action-slug>.<property> }}
The action slug is a URL-friendly identifier derived from the action name. You can find it in the workflow editor below the action name field.

Available Properties

Each completed action exposes the following properties:
PropertyDescription
tasks.<slug>.nameAction name
tasks.<slug>.slugAction slug identifier
tasks.<slug>.statusExecution status (queued, started, completed, failed, canceled)
tasks.<slug>.outputAction output (structure varies by action type — see below)
tasks.<slug>.logsEvent logs from the action
tasks.<slug>.started_atWhen the action started
tasks.<slug>.completed_atWhen the action completed
tasks.<slug>.failed_atWhen the action failed (if applicable)

HTTP Request Action Output

The Fetch an HTTP endpoint action stores the full HTTP response. Access it through output.response:
PathDescription
tasks.<slug>.output.response.statusHTTP status code
tasks.<slug>.output.response.bodyResponse body (parsed as JSON when applicable)
tasks.<slug>.output.response.headersResponse headers

Accessing nested JSON

When the HTTP response returns JSON, you can traverse the parsed structure directly:
{{ tasks.my-http-request.output.response.body.data.id }}
{{ tasks.my-http-request.output.response.body.items[0].name }}

AI Chat Completion Action Output

The OpenAI, Anthropic, Google Gemini, and Mistral chat completion actions store the AI model’s response in output.response. The exact structure depends on the provider and model.

OpenAI

OpenAI uses two different API formats depending on the model: GPT models (gpt-4o, gpt-4o-mini, etc.) use the Chat Completions API:
{{ tasks.my-openai-task.output.response.choices[0].message.content }}
Reasoning models (o1-*, o3-*) use the Responses API, which returns a different structure:
{{ tasks.my-openai-task.output.response.output[0].content[0].text }}
If you switch between GPT and reasoning models, you must update the output path in any downstream actions that reference the task output.

Google Gemini

{{ tasks.my-gemini-task.output.response.candidates[0].content.parts[0].text }}

Other Action Outputs

Most built-in actions (Create Jira Issue, Create Linear Issue, Send Slack Message, etc.) store their response in output.response. The structure matches the response from the underlying integration API. Examples:
{{ tasks.create-a-jira-issue.output.response.key }}
{{ tasks.create-a-linear-issue.output.response.data.issueCreate.issue.url }}
{{ tasks.create-a-linear-issue.output.response.data.issueCreate.issue.identifier }}

Examples

Chain two HTTP requests

Fetch a service catalog entry, then use part of the response in a follow-up API call. Action 1 — “get-service-info” (HTTP GET):
URL: https://api.example.com/v1/catalog/{{ incident.services.first }}
Action 2 — “get-owner” (HTTP GET) referencing Action 1’s output:
URL: https://api.example.com/v1/catalog/{{ tasks.get-service-info.output.response.body.hierarchy.parents[0].tag }}

Use HTTP response in action URL parameters

Look up a user by email from a previous action’s response:
https://api.rootly.com/v1/users?filter[email]={{ tasks.get-on-call-from-opsgenie.output.response.body.data.onCallRecipients[0] | default: 'fallback@example.com' }}

Feed HTTP response into an OpenAI prompt

Fetch logs from an observability tool, then have AI analyze them. Action 1 — “get-logs” (HTTP GET to your logging API) Action 2 — “analyze-logs” (OpenAI Chat Completion) with prompt:
Analyze the following service logs for errors and anomalies.
Format your response for Slack using mrkdwn.

{{ tasks.get-logs.output.response.body.data.result }}

Pass AI output into a subsequent HTTP request

Generate a postmortem with AI, then post it to the incident timeline. Action 1 — “generate-postmortem” (OpenAI Chat Completion) Action 2 — “post-to-timeline” (HTTP POST):
URL: https://api.rootly.com/v1/incidents/{{ incident.id }}/events
Body:
{
  "data": {
    "attributes": {
      "visibility": "internal",
      "event": {{ tasks.generate-postmortem.output.response.choices[0].message.content | to_json }}
    },
    "type": "incident_events"
  }
}
Use the to_json filter when inserting task output into a JSON body. AI-generated text often contains quotes and newlines that break JSON syntax without proper escaping.

Use Jira/Linear issue output to update an alert

Create a ticket, then write the ticket URL back to a custom alert field. Action 1 — “create-a-linear-issue” (Create Linear Issue) Action 2 — “update-alert-with-ticket” (HTTP PATCH):
URL: https://api.rootly.com/v1/alerts/{{ alert.id }}
Body:
{
  "data": {
    "attributes": {
      "alert_field_values_attributes": [
        {
          "alert_field_id": "<your-field-id>",
          "value": "{{ tasks.create-a-linear-issue.output.response.data.issueCreate.issue.url }}"
        }
      ]
    },
    "type": "alerts"
  }
}

Assign a role based on an on-call lookup

Look up who is on-call, find them in Rootly, then assign them to an incident role. Action 1 — “get-on-call” (HTTP GET to your paging provider) Action 2 — “find-rootly-user” (HTTP GET):
https://api.rootly.com/v1/users?filter[email]={{ tasks.get-on-call.output.response.body.data.onCallRecipients[0] }}
Action 3 — “assign-role” (HTTP POST):
URL: https://api.rootly.com/v1/incidents/{{ incident.id }}/assign_role_to_user
Body:
{
  "data": {
    "type": "incidents",
    "attributes": {
      "user_id": "{{ tasks.find-rootly-user.output.response.body.data[0].id }}",
      "incident_role_id": "<your-role-id>"
    }
  }
}

Using Liquid Filters with Task Outputs

You can apply any Liquid filter to task output values. Common patterns:
{{ tasks.my-task.output.response.body.name | upcase }}

{{ tasks.my-task.output.response.body.email | default: 'fallback@example.com' }}

{{ tasks.my-task.output.response.body.query | replace: '+', '' }}

{{ tasks.my-task.output.response.body.items | size }}

Troubleshooting

Action output is empty

  • Verify the referenced action ran successfully. Check the workflow run log for errors.
  • Check that the action slug matches exactly — slugs are case-sensitive and use hyphens, not underscores (e.g., my-http-request, not my_http_request).

JSON path returns nothing

  • The HTTP response body is only parsed as JSON when the response Content-Type is application/json. If the API returns a different content type, body may be a raw string.
  • Use the workflow run log to inspect the actual response structure and verify your path.

Subsequent action does not see the previous output

  • Actions run sequentially in order. An action can only reference outputs from actions that appear above it in the workflow editor.
  • If the previous action has Skip on Failure enabled and failed, its output may be incomplete or missing.