Expressions is how you reference and manipulate data inline in action inputs, run-if conditions, loop expressions, and output schemas. Tracecat supports the following expression contexts:

PrefixExpression syntaxDescription
ACTIONSACTIONS.<action_slug>.result.<jsonpath>Reference the result of an action
TRIGGERTRIGGER.<jsonpath>Reference data passed via webhook or UI
SECRETSSECRETS.<name>.<key>Reference a secret
FNFN.<fn_name>(<arg1>, <arg2>, ...)Call an inline function

To use an expression, you must use the ${{ <context>.<expression> }} syntax:

${{ <context>.<expression> }}

Expressions are evaluated into values at the start of each action run.

ACTIONS context

Tracecat uses JSONPath and dot notation to select outputs from previous actions. JSONPath can also be used to filter and transform nested JSONs.

Both ACTIONS and TRIGGER expression contexts support JSONPath syntax. If you are new to JSONPath or need a refresher, check out our JSONPath syntax cheatsheet.

You can reference outputs from a previous action in the same workflow using the ACTIONS context. Actions are referenced by a sluggified version of their name.

TRIGGER context

Check out the workflow triggers tutorial for a detailed guide setting up webhooks for workflows.

Workflows can be triggered via webhook, manual UI trigger, or the Execute Child Workflow action. Use the TRIGGER context to reference the data from the trigger as a JSON object.

SECRETS context

Tracecat comes with a built-in secrets manager. This allows you to store and retrieve sensitive data scoped to a workspace without exposing the value in plaintext. Secrets are encrypted at rest and stored in the database.

Secrets stored in the secrets manager can be accessed using the SECRETS prefix:

${{ SECRETS.<name>.<key> }}

Tracecat will automatically replace the expression with the secret value at runtime. Retrieved secrets are deleted from memory after the workflow run completes.

FN context

Check out the full list of supported functions in the functions cheatsheet.

Tracecat supports inline functions in the FN context. Here are some examples of functions you can use with FN:

For the following function examples, we’ll use the Example alert JSON as sample data. Feel free to copy and paste this into your own workflow to follow along.

# --- JSON Processing ---
# Parse a JSON string into an object
result: ${{ FN.deserialize_json(ACTIONS.get_alert.result.raw_data) }}

# Convert an object to a JSON string
result: ${{ FN.serialize_json(ACTIONS.transform_data.result) }}

# Format JSON for readability
result: ${{ FN.prettify_json(ACTIONS.get_alert.result.alert) }}

# Safely access a potentially missing property
result: ${{ FN.lookup(ACTIONS.get_alert.result.alert.user, "department") }}

# Convert a list of objects into an object indexed by a given key ("timestamp")
result: ${{ FN.index_by_key(ACTIONS.get_alert.result.alert.events, "timestamp") }}

# Convert a list of objects into an object with key ("timestamp") and value ("action")
result: ${{ FN.index_by_key(ACTIONS.get_alert.result.alert.events, "timestamp", "action") }}

# Merge multiple objects
result: >-
  ${{ FN.merge([
    ACTIONS.get_user_info.result,
    ACTIONS.get_device_info.result,
    {"alert_id": ACTIONS.get_alert.result.alert.id}
  ]) }}

# --- Date/Time Processing ---
# Convert ISO string to datetime
result: ${{ FN.to_datetime(ACTIONS.get_alert.result.alert.created_at) }}

# Format a datetime
result: ${{ FN.format_datetime(ACTIONS.get_alert.result.alert.created_at, "%Y-%m-%d %H:%M:%S") }}

# Convert datetime to timestamp (seconds since epoch)
result: ${{ FN.to_timestamp(ACTIONS.get_alert.result.alert.created_at) }}

# Calculate time difference in hours
result: >-
  ${{ FN.hours_between(
    ACTIONS.get_alert.result.alert.additional_context.last_successful_login,
    ACTIONS.get_alert.result.alert.created_at
  ) }}

# --- Text Processing ---
# Extract text using regex
result: ${{ FN.regex_extract("<timestamp>(.*?)</timestamp>", ACTIONS.get_alert.result.alert.raw_logs) }}

# Extract text from HTML
result: ${{ FN.extract_text_from_html(ACTIONS.get_webpage.result.html_content) }}

# Transform text
result: ${{ FN.uppercase(ACTIONS.get_alert.result.alert.title) }}

# --- IP Addresses ---
# Check IP address version
result: ${{ FN.check_ip_version(ACTIONS.get_alert.result.alert.source_ip) }}

# Check if an IP is public
result: ${{ FN.ipv4_is_public(ACTIONS.get_alert.result.alert.source_ip) }}

# Check if an IP is private
result: ${{ FN.ipv4_is_private(ACTIONS.get_alert.result.alert.source_ip) }}

Check out the docs on Data manipulation to learn more about the different data types and how to manipulate them.

Was this page helpful?