> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tracecat.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Functions

> Quick reference for every Tracecat expression function and operator, with signatures and examples for transforming data inside workflows and agents.

## Examples

Build a prompt or short string:

<CodeGroup>
  ```yaml Expression theme={null}
  prompt: ${{ FN.format("Investigate alert {0} with severity {1}", TRIGGER.alert_id, TRIGGER.severity) }}
  ```

  ```json Result theme={null}
  {
    "prompt": "Investigate alert al-123 with severity high"
  }
  ```
</CodeGroup>

Time manipulation for alert search windows:

<CodeGroup>
  ```yaml Expression theme={null}
  start_time: ${{ FN.to_isoformat(FN.now() - FN.minutes(15)) }}
  end_time: ${{ FN.to_isoformat(FN.now()) }}
  ```

  ```json Result theme={null}
  {
    "start_time": "2026-03-18T12:45:00",
    "end_time": "2026-03-18T13:00:00"
  }
  ```
</CodeGroup>

Deserialize or serialize JSON:

<CodeGroup>
  ```yaml Expression theme={null}
  parsed: ${{ FN.deserialize_json(TRIGGER.raw_json) }}
  serialized: ${{ FN.serialize_json({"status": "ok", "count": 3}) }}
  ```

  ```json Result theme={null}
  {
    "parsed": {
      "status": "open",
      "count": 3
    },
    "serialized": "{\"status\":\"ok\",\"count\":3}"
  }
  ```
</CodeGroup>

Format rows into a Markdown table:

<CodeGroup>
  ```yaml Expression theme={null}
  table: ${{ FN.to_markdown_table(ACTIONS.list_findings.result) }}
  ```

  ```json Result theme={null}
  {
    "table": "| id | severity |\n| --- | --- |\n| f-1 | high |\n| f-2 | medium |"
  }
  ```
</CodeGroup>

Count or reshape a small value:

<CodeGroup>
  ```yaml Expression theme={null}
  count: ${{ FN.length(ACTIONS.gather_results.result) }}
  unique_tags: ${{ FN.unique(TRIGGER.tags) }}
  ```

  ```json Result theme={null}
  {
    "count": 3,
    "unique_tags": ["auth", "critical"]
  }
  ```
</CodeGroup>

This page is generated from `tracecat/expressions/functions.py`.

## Function reference

<ResponseField name="FN.add" type="function">
  `FN.add(a: float | int, b: float | int) -> float | int`

  Add two numbers together.
</ResponseField>

<ResponseField name="FN.and" type="function">
  `FN.and(a: bool, b: bool) -> bool`

  Logical AND operation.
</ResponseField>

<ResponseField name="FN.at" type="function">
  `FN.at(sequence: Sequence[Any], index: int) -> Any`

  Return the element at the given index.
</ResponseField>

<ResponseField name="FN.capitalize" type="function">
  `FN.capitalize(x: str) -> str`

  Capitalize a string.
</ResponseField>

<ResponseField name="FN.check_ip_version" type="function">
  `FN.check_ip_version(ip: str) -> int`

  Get IP address version (4 or 6).
</ResponseField>

<ResponseField name="FN.compact" type="function">
  `FN.compact(x: list[Any]) -> list[Any]`

  Drop null values from a list. Similar to compact function in Terraform.
</ResponseField>

<ResponseField name="FN.concat" type="function">
  `FN.concat(*items: str) -> str`

  Concatenate multiple strings.
</ResponseField>

<ResponseField name="FN.contains" type="function">
  `FN.contains(item: Any, container: Sequence[Any]) -> bool`

  Check if item exists in a sequence.

  Aliases: `FN.is_in`
</ResponseField>

<ResponseField name="FN.contains_any_of" type="function">
  `FN.contains_any_of(a: Sequence[Any], b: Sequence[Any]) -> bool`

  Check if any of the elements of the first sequence exist in the second sequence.
</ResponseField>

<ResponseField name="FN.contains_none_of" type="function">
  `FN.contains_none_of(a: Sequence[Any], b: Sequence[Any]) -> bool`

  Check if all of of the elements of the first sequence don't exist in the second sequence.
</ResponseField>

<ResponseField name="FN.datetime" type="function">
  `FN.datetime(year: int, month: int, day: int, hour: int = 0, minute: int = 0, second: int = 0) -> datetime`

  Create datetime from year, month, day, hour, minute, and second.
</ResponseField>

<ResponseField name="FN.days" type="function">
  `FN.days(x: int) -> timedelta`

  Create timedelta with specified days.
</ResponseField>

<ResponseField name="FN.days_between" type="function">
  `FN.days_between(start: datetime | str, end: datetime | str) -> float`

  Days between two datetimes.
</ResponseField>

<ResponseField name="FN.deserialize_json" type="function">
  `FN.deserialize_json(obj, /)`

  Deserialize JSON to Python objects.
</ResponseField>

<ResponseField name="FN.deserialize_ndjson" type="function">
  `FN.deserialize_ndjson(x: str) -> list[dict[str, Any]]`

  Parse newline-delimited JSON string into list of objects.
</ResponseField>

<ResponseField name="FN.deserialize_yaml" type="function">
  `FN.deserialize_yaml(x: str) -> Any`

  Deserialize YAML string to object.
</ResponseField>

<ResponseField name="FN.difference" type="function">
  `FN.difference(a: Sequence[Any], b: Sequence[Any]) -> list[Any]`

  Return a list of elements that are in the first sequence but not in the second.
</ResponseField>

<ResponseField name="FN.div" type="function">
  `FN.div(a: float | int, b: float | int) -> float`

  Divide first number by second number.
</ResponseField>

<ResponseField name="FN.does_not_contain" type="function">
  `FN.does_not_contain(item: Any, container: Sequence[Any]) -> bool`

  Check if item does not exist in a sequence.

  Aliases: `FN.is_not_in`, `FN.not_in`
</ResponseField>

<ResponseField name="FN.drop_nulls" type="function">
  `FN.drop_nulls(items: list[Any]) -> list[Any]`

  Remove all null or empty string values from a list.
</ResponseField>

<ResponseField name="FN.endswith" type="function">
  `FN.endswith(x: str, suffix: str) -> bool`

  Check if a string ends with a specified suffix.
</ResponseField>

<ResponseField name="FN.extract_asns" type="function">
  `FN.extract_asns(text: str) -> list[str]`

  Extract Autonomous System Numbers, e.g. AS1234, from a string.
</ResponseField>

<ResponseField name="FN.extract_cves" type="function">
  `FN.extract_cves(text: str) -> list[str]`

  Extract CVE IDs, such as CVE-2021-34527, from a string.
</ResponseField>

<ResponseField name="FN.extract_domains" type="function">
  `FN.extract_domains(text: str, include_defanged: bool = False) -> list[str]`

  Extract domain names from a string.
</ResponseField>

<ResponseField name="FN.extract_emails" type="function">
  `FN.extract_emails(text: str, normalize: bool = False) -> list[str]`

  Extract unique emails from a string. When `normalize` is True, lowercases the email and strips the subaddress (the `+...` part before `@`).
</ResponseField>

<ResponseField name="FN.extract_ip" type="function">
  `FN.extract_ip(text: str, include_defanged: bool = False) -> list[str]`

  Extract unique IPv4 and IPv6 addresses from a string.
</ResponseField>

<ResponseField name="FN.extract_ipv4" type="function">
  `FN.extract_ipv4(text: str, include_defanged: bool = False) -> list[str]`

  Extract unique IPv4 addresses from a string.
</ResponseField>

<ResponseField name="FN.extract_ipv6" type="function">
  `FN.extract_ipv6(text: str, include_defanged: bool = False) -> list[str]`

  Extract unique IPv6 addresses from a string. Includes defanged variants as an option.
</ResponseField>

<ResponseField name="FN.extract_mac" type="function">
  `FN.extract_mac(text: str) -> list[str]`

  Extract MAC addresses from a string.
</ResponseField>

<ResponseField name="FN.extract_md5" type="function">
  `FN.extract_md5(text: str) -> list[str]`

  Extract MD5 hashes from a string.
</ResponseField>

<ResponseField name="FN.extract_sha1" type="function">
  `FN.extract_sha1(text: str) -> list[str]`

  Extract SHA1 hashes from a string.
</ResponseField>

<ResponseField name="FN.extract_sha256" type="function">
  `FN.extract_sha256(text: str) -> list[str]`

  Extract SHA256 hashes from a string.
</ResponseField>

<ResponseField name="FN.extract_sha512" type="function">
  `FN.extract_sha512(text: str) -> list[str]`

  Extract SHA512 hashes from a string.
</ResponseField>

<ResponseField name="FN.extract_urls" type="function">
  `FN.extract_urls(text: str, http_only: bool = False, include_defanged: bool = False) -> list[str]`

  Extract URLs from text, optionally including defanged ones.
</ResponseField>

<ResponseField name="FN.flatten" type="function">
  `FN.flatten(iterables: Sequence[Sequence[Any]]) -> list[Any]`

  Flatten nested sequences into a single list.
</ResponseField>

<ResponseField name="FN.flatten_dict" type="function">
  `FN.flatten_dict(x: str | dict[str, Any] | list[Any], max_depth: int = 100) -> dict[str, Any]`

  Return object with single level of keys (as jsonpath) and values.
</ResponseField>

<ResponseField name="FN.format" type="function">
  `FN.format(template: str, *values: Any) -> str`

  Format a string with the given arguments.
</ResponseField>

<ResponseField name="FN.format_datetime" type="function">
  `FN.format_datetime(x: datetime | str, format: str) -> str`

  Format datetime into specified format (e.g. '%Y-%m-%d %H:%M:%S').
</ResponseField>

<ResponseField name="FN.from_base64" type="function">
  `FN.from_base64(x: str) -> str`

  Decode base64 string to string.
</ResponseField>

<ResponseField name="FN.from_base64url" type="function">
  `FN.from_base64url(x: str) -> str`

  Decode URL-safe base64 string to string.
</ResponseField>

<ResponseField name="FN.from_timestamp" type="function">
  `FN.from_timestamp(x: float | int | str, unit: str = s) -> datetime`

  Convert timestamp in milliseconds ('ms') or seconds ('s') to datetime.
</ResponseField>

<ResponseField name="FN.get_day" type="function">
  `FN.get_day(x: datetime | str) -> int`

  Get day of month (1-31) from datetime.
</ResponseField>

<ResponseField name="FN.get_day_of_week" type="function">
  `FN.get_day_of_week(x: datetime | str, format: "Literal[number, full, short]" = number) -> int | str`

  Extract day of week from datetime. Returns 0-6 (Mon-Sun) or day name if format is "full" or "short".
</ResponseField>

<ResponseField name="FN.get_hour" type="function">
  `FN.get_hour(x: datetime | str) -> int`

  Get hour (0-23) from datetime.
</ResponseField>

<ResponseField name="FN.get_interaction" type="function">
  `FN.get_interaction() -> dict[str, str] | None`

  Get the interaction context from the current action in the workflow execution.
</ResponseField>

<ResponseField name="FN.get_minute" type="function">
  `FN.get_minute(x: datetime | str) -> int`

  Get minute (0-59) from datetime.
</ResponseField>

<ResponseField name="FN.get_month" type="function">
  `FN.get_month(x: datetime | str, format: "Literal[number, full, short]" = number) -> int | str`

  Extract month from datetime. Returns 1-12 or month name if format is "full" or "short".
</ResponseField>

<ResponseField name="FN.get_second" type="function">
  `FN.get_second(x: datetime | str) -> int`

  Get second (0-59) from datetime.
</ResponseField>

<ResponseField name="FN.get_year" type="function">
  `FN.get_year(x: datetime | str) -> int`

  Get year from datetime.
</ResponseField>

<ResponseField name="FN.greater_than" type="function">
  `FN.greater_than(a: Any, b: Any) -> bool`

  Check if a is greater than b.
</ResponseField>

<ResponseField name="FN.greater_than_or_equal" type="function">
  `FN.greater_than_or_equal(a: Any, b: Any) -> bool`

  Check if a is greater than or equal to b.
</ResponseField>

<ResponseField name="FN.hash_md5" type="function">
  `FN.hash_md5(x: str | bytes) -> str`

  Generate MD5 hash of input string or bytes.
</ResponseField>

<ResponseField name="FN.hash_sha1" type="function">
  `FN.hash_sha1(x: str | bytes) -> str`

  Generate SHA1 hash of input string or bytes.
</ResponseField>

<ResponseField name="FN.hash_sha256" type="function">
  `FN.hash_sha256(x: str | bytes) -> str`

  Generate SHA256 hash of input string or bytes.
</ResponseField>

<ResponseField name="FN.hash_sha512" type="function">
  `FN.hash_sha512(x: str | bytes) -> str`

  Generate SHA512 hash of input string or bytes.
</ResponseField>

<ResponseField name="FN.hours" type="function">
  `FN.hours(x: int) -> timedelta`

  Create timedelta with specified hours.
</ResponseField>

<ResponseField name="FN.hours_between" type="function">
  `FN.hours_between(start: datetime | str, end: datetime | str) -> float`

  Hours between two datetimes.
</ResponseField>

<ResponseField name="FN.intersection" type="function">
  `FN.intersection(a: Sequence[Any], b: Sequence[Any]) -> list[Any]`

  Return a list containing the intersection of elements from two sequences.
</ResponseField>

<ResponseField name="FN.ipv4_in_subnet" type="function">
  `FN.ipv4_in_subnet(ipv4: str, subnet: str) -> bool`

  Check if IPv4 address is in the given subnet.
</ResponseField>

<ResponseField name="FN.ipv4_is_public" type="function">
  `FN.ipv4_is_public(ipv4: str) -> bool`

  Check if IPv4 address is public/global.
</ResponseField>

<ResponseField name="FN.ipv6_in_subnet" type="function">
  `FN.ipv6_in_subnet(ipv6: str, subnet: str) -> bool`

  Check if IPv6 address is in the given subnet.
</ResponseField>

<ResponseField name="FN.ipv6_is_public" type="function">
  `FN.ipv6_is_public(ipv6: str) -> bool`

  Check if IPv6 address is public/global.
</ResponseField>

<ResponseField name="FN.is_empty" type="function">
  `FN.is_empty(x: Sequence[Any]) -> bool`

  Check if sequence has length 0.
</ResponseField>

<ResponseField name="FN.is_equal" type="function">
  `FN.is_equal(a: Any, b: Any) -> bool`

  Check if a is equal to b.
</ResponseField>

<ResponseField name="FN.is_in" type="function">
  `FN.is_in(item: Any, container: Sequence[Any]) -> bool`

  Check if item exists in a sequence.

  Aliases: `FN.contains`
</ResponseField>

<ResponseField name="FN.is_json" type="function">
  `FN.is_json(x: str) -> bool`

  Check if a string is valid JSON.
</ResponseField>

<ResponseField name="FN.is_not_empty" type="function">
  `FN.is_not_empty(x: Sequence[Any]) -> bool`

  Check if sequence has length greater than 0.

  Aliases: `FN.not_empty`
</ResponseField>

<ResponseField name="FN.is_not_equal" type="function">
  `FN.is_not_equal(a: Any, b: Any) -> bool`

  Check if a is not equal to b.

  Aliases: `FN.not_equal`
</ResponseField>

<ResponseField name="FN.is_not_in" type="function">
  `FN.is_not_in(item: Any, container: Sequence[Any]) -> bool`

  Check if item does not exist in a sequence.

  Aliases: `FN.does_not_contain`, `FN.not_in`
</ResponseField>

<ResponseField name="FN.is_not_null" type="function">
  `FN.is_not_null(x: Any) -> bool`

  Check if value is not None.

  Aliases: `FN.not_null`
</ResponseField>

<ResponseField name="FN.is_null" type="function">
  `FN.is_null(x: Any) -> bool`

  Check if value is None.
</ResponseField>

<ResponseField name="FN.is_working_hours" type="function">
  `FN.is_working_hours(x: datetime | str, start: str, end: str, include_weekends: bool = False, timezone: str | None = None) -> bool`

  Check if datetime is between two times (HH:MM or HH:MM:SS strings).
</ResponseField>

<ResponseField name="FN.iter_product" type="function">
  `FN.iter_product(*iterables: Sequence[Any]) -> list[tuple[Any, ...]]`

  Generate cartesian product of sequences.
</ResponseField>

<ResponseField name="FN.join" type="function">
  `FN.join(items: Sequence[str], sep: str) -> str`

  Join sequence of strings with separator.
</ResponseField>

<ResponseField name="FN.length" type="function">
  `FN.length(obj, /)`

  Return the number of items in a container.
</ResponseField>

<ResponseField name="FN.less_than" type="function">
  `FN.less_than(a: Any, b: Any) -> bool`

  Check if a is less than b.
</ResponseField>

<ResponseField name="FN.less_than_or_equal" type="function">
  `FN.less_than_or_equal(a: Any, b: Any) -> bool`

  Check if a is less than or equal to b.
</ResponseField>

<ResponseField name="FN.lookup" type="function">
  `FN.lookup(d: dict[Any, Any], k: Any) -> Any`

  Safely get value from an object.
</ResponseField>

<ResponseField name="FN.lowercase" type="function">
  `FN.lowercase(x: str) -> str`

  Convert string to lowercase.
</ResponseField>

<ResponseField name="FN.map_keys" type="function">
  `FN.map_keys(x: dict[str, Any], keys: dict[str, str]) -> dict[str, Any]`

  Map keys in an object to new keys.
</ResponseField>

<ResponseField name="FN.max" type="function">
  `FN.max(a: Any, b: Any) -> Any`

  Return the maximum of two values.
</ResponseField>

<ResponseField name="FN.merge" type="function">
  `FN.merge(x: list[dict[Any, Any]]) -> dict[Any, Any]`

  Merge list of objects. Similar to merge function in Terraform.
</ResponseField>

<ResponseField name="FN.min" type="function">
  `FN.min(a: Any, b: Any) -> Any`

  Return the minimum of two values.
</ResponseField>

<ResponseField name="FN.minutes" type="function">
  `FN.minutes(x: int) -> timedelta`

  Create timedelta with specified minutes.
</ResponseField>

<ResponseField name="FN.minutes_between" type="function">
  `FN.minutes_between(start: datetime | str, end: datetime | str) -> float`

  Minutes between two datetimes.
</ResponseField>

<ResponseField name="FN.mod" type="function">
  `FN.mod(a: float | int, b: float | int) -> float | int`

  Calculate modulo (remainder) of first number divided by second.
</ResponseField>

<ResponseField name="FN.mul" type="function">
  `FN.mul(a: float | int, b: float | int) -> float | int`

  Multiply two numbers together.
</ResponseField>

<ResponseField name="FN.normalize_email" type="function">
  `FN.normalize_email(email: str) -> str`

  Convert sub-addressed email to a normalized email address.
</ResponseField>

<ResponseField name="FN.not" type="function">
  `FN.not(x: bool) -> bool`

  Logical NOT operation.
</ResponseField>

<ResponseField name="FN.not_empty" type="function">
  `FN.not_empty(x: Sequence[Any]) -> bool`

  Check if sequence has length greater than 0.

  Aliases: `FN.is_not_empty`
</ResponseField>

<ResponseField name="FN.not_equal" type="function">
  `FN.not_equal(a: Any, b: Any) -> bool`

  Check if a is not equal to b.

  Aliases: `FN.is_not_equal`
</ResponseField>

<ResponseField name="FN.not_in" type="function">
  `FN.not_in(item: Any, container: Sequence[Any]) -> bool`

  Check if item does not exist in a sequence.

  Aliases: `FN.does_not_contain`, `FN.is_not_in`
</ResponseField>

<ResponseField name="FN.not_null" type="function">
  `FN.not_null(x: Any) -> bool`

  Check if value is not None.

  Aliases: `FN.is_not_null`
</ResponseField>

<ResponseField name="FN.now" type="function">
  `FN.now(as_isoformat: bool = False, timespec: str = auto) -> datetime | str`

  Return workflow logical time (local, naive) or current time if outside workflow.
</ResponseField>

<ResponseField name="FN.or" type="function">
  `FN.or(a: bool, b: bool) -> bool`

  Logical OR operation.
</ResponseField>

<ResponseField name="FN.parse_csv" type="function">
  `FN.parse_csv(x: str) -> list[dict[str, Any]]`

  Parse CSV string into list of objects.
</ResponseField>

<ResponseField name="FN.parse_datetime" type="function">
  `FN.parse_datetime(x: str, format: str) -> datetime`

  Parse string to datetime using specified format.
</ResponseField>

<ResponseField name="FN.parse_time" type="function">
  `FN.parse_time(x: str) -> time`

  Parse HH:MM:SS or HH:MM formatted string to a time object.
</ResponseField>

<ResponseField name="FN.pow" type="function">
  `FN.pow(a: float | int, b: float | int) -> float | int`

  Raise first number to the power of second number.
</ResponseField>

<ResponseField name="FN.prefix" type="function">
  `FN.prefix(x: str | list[str], prefix: str) -> str | list[str]`

  Add a prefix to a string or list of strings.
</ResponseField>

<ResponseField name="FN.prettify_json" type="function">
  `FN.prettify_json(x: Any) -> str`

  Convert object to formatted JSON string.
</ResponseField>

<ResponseField name="FN.range" type="function">
  `FN.range(start: int, end: int, step: int = 1) -> list[int]`

  Create a range of integers from start to end (exclusive), with a step size.
</ResponseField>

<ResponseField name="FN.regex_extract" type="function">
  `FN.regex_extract(pattern: str, text: str) -> str | None`

  Extract the first captured group from text; fallback to full match if none.
</ResponseField>

<ResponseField name="FN.regex_match" type="function">
  `FN.regex_match(pattern: str, text: str) -> bool`

  Check if text matches regex pattern.
</ResponseField>

<ResponseField name="FN.regex_not_match" type="function">
  `FN.regex_not_match(pattern: str, text: str) -> bool`

  Check if text does not match regex pattern.
</ResponseField>

<ResponseField name="FN.replace" type="function">
  `FN.replace(x: str, old: str, new: str) -> str`

  Replace all occurrences of old substring with new substring.
</ResponseField>

<ResponseField name="FN.seconds" type="function">
  `FN.seconds(x: int) -> timedelta`

  Create timedelta with specified seconds.
</ResponseField>

<ResponseField name="FN.seconds_between" type="function">
  `FN.seconds_between(start: datetime | str, end: datetime | str) -> float`

  Seconds between two datetimes.
</ResponseField>

<ResponseField name="FN.serialize" type="function">
  `FN.serialize(x: Any) -> str`

  Serialize a JSON-compatible value to string.
</ResponseField>

<ResponseField name="FN.serialize_json" type="function">
  `FN.serialize_json(x: Any) -> str`

  Convert object to JSON string.
</ResponseField>

<ResponseField name="FN.serialize_yaml" type="function">
  `FN.serialize_yaml(x: Any) -> str`

  Serialize object to YAML string.
</ResponseField>

<ResponseField name="FN.set_timezone" type="function">
  `FN.set_timezone(x: datetime | str, timezone: str) -> datetime`

  Convert datetime to different timezone. Timezone must be a valid IANA timezone name (e.g., "America/New\_York").
</ResponseField>

<ResponseField name="FN.slice" type="function">
  `FN.slice(x: str, start_index: int, length: int) -> str`

  Extract a substring from start\_index with given length.
</ResponseField>

<ResponseField name="FN.slugify" type="function">
  `FN.slugify(x: str) -> str`

  Slugify a string.
</ResponseField>

<ResponseField name="FN.split" type="function">
  `FN.split(x: str, sep: str) -> list[str]`

  Split a string into a list of strings by a seperator.
</ResponseField>

<ResponseField name="FN.startswith" type="function">
  `FN.startswith(x: str, suffix: str) -> bool`

  Check if a string starts wit a specified suffix.
</ResponseField>

<ResponseField name="FN.strip" type="function">
  `FN.strip(x: str, chars: str) -> str`

  Removes all leading and trailing characters.
</ResponseField>

<ResponseField name="FN.sub" type="function">
  `FN.sub(a: float | int, b: float | int) -> float | int`

  Subtract second number from first number.
</ResponseField>

<ResponseField name="FN.suffix" type="function">
  `FN.suffix(x: str | list[str], suffix: str) -> str | list[str]`

  Add a suffix to a string or list of strings.
</ResponseField>

<ResponseField name="FN.sum" type="function">
  `FN.sum(iterable: Iterable[float | int], start: float | int = 0) -> float | int`

  Return the sum of a 'start' value (default: 0) plus an iterable of numbers.
</ResponseField>

<ResponseField name="FN.symmetric_difference" type="function">
  `FN.symmetric_difference(a: Sequence[Any], b: Sequence[Any]) -> list[Any]`

  Return a list of elements that are in either sequence but not in both.
</ResponseField>

<ResponseField name="FN.tabulate" type="function">
  `FN.tabulate(x: list[dict[str, typing.Any]], format: Literal[markdown, html, csv, xml]) -> str`

  Format list of objects into `markdown`, `html`, `csv`, or `xml`
</ResponseField>

<ResponseField name="FN.titleize" type="function">
  `FN.titleize(x: str) -> str`

  Convert a string to titlecase.
</ResponseField>

<ResponseField name="FN.to_base64" type="function">
  `FN.to_base64(x: str) -> str`

  Encode string to base64.
</ResponseField>

<ResponseField name="FN.to_base64url" type="function">
  `FN.to_base64url(x: str) -> str`

  Encode string to URL-safe base64.
</ResponseField>

<ResponseField name="FN.to_datetime" type="function">
  `FN.to_datetime(x: Any, timezone: str | None = None) -> datetime`

  Convert to timezone-aware datetime object from timestamp (in seconds), ISO 8601 string or existing datetime.
</ResponseField>

<ResponseField name="FN.to_isoformat" type="function">
  `FN.to_isoformat(x: datetime | str, timespec: str = auto) -> str`

  Convert datetime to ISO format string.
</ResponseField>

<ResponseField name="FN.to_keys" type="function">
  `FN.to_keys(x: dict[Any, Any]) -> list[Any]`

  Extract keys from an object.
</ResponseField>

<ResponseField name="FN.to_markdown_list" type="function">
  `FN.to_markdown_list(x: list[str], ordered: bool = False) -> str`

  Format list of strings into Markdown list.
</ResponseField>

<ResponseField name="FN.to_markdown_table" type="function">
  `FN.to_markdown_table(x: list[dict[str, typing.Any]]) -> str`

  Format list of dictionaries into Markdown table.
</ResponseField>

<ResponseField name="FN.to_markdown_tasks" type="function">
  `FN.to_markdown_tasks(x: list[str]) -> str`

  Format list of strings into Markdown tasks.
</ResponseField>

<ResponseField name="FN.to_time" type="function">
  `FN.to_time(x: datetime | str) -> time`

  Convert datetime to time.
</ResponseField>

<ResponseField name="FN.to_timestamp" type="function">
  `FN.to_timestamp(x: datetime | str, unit: str = s) -> int`

  Convert datetime to timestamp in milliseconds ('ms') or seconds ('s').
</ResponseField>

<ResponseField name="FN.to_values" type="function">
  `FN.to_values(x: dict[Any, Any]) -> list[Any]`

  Extract values from an object.
</ResponseField>

<ResponseField name="FN.today" type="function">
  `FN.today() -> date`

  Return workflow logical time date (local) or current date if outside workflow.
</ResponseField>

<ResponseField name="FN.union" type="function">
  `FN.union(a: Sequence[Any], b: Sequence[Any]) -> list[Any]`

  Return a list containing the union of elements from two sequences.
</ResponseField>

<ResponseField name="FN.unique" type="function">
  `FN.unique(items: Sequence[Any]) -> list[Any]`

  List of hashable items (e.g. strings, numbers) to remove duplicates from.
</ResponseField>

<ResponseField name="FN.unset_timezone" type="function">
  `FN.unset_timezone(x: datetime | str) -> datetime`

  Remove timezone information from datetime without changing the time.
</ResponseField>

<ResponseField name="FN.uppercase" type="function">
  `FN.uppercase(x: str) -> str`

  Convert string to uppercase.
</ResponseField>

<ResponseField name="FN.url_decode" type="function">
  `FN.url_decode(x: str) -> str`

  Converts percent-encoded characters back into their original form.
</ResponseField>

<ResponseField name="FN.url_encode" type="function">
  `FN.url_encode(x: str) -> str`

  Converts URL-unsafe characters into percent-encoded characters.
</ResponseField>

<ResponseField name="FN.utcnow" type="function">
  `FN.utcnow(as_isoformat: bool = False, timespec: str = auto) -> datetime | str`

  Return workflow logical time (UTC, aware) or current UTC time if outside workflow.
</ResponseField>

<ResponseField name="FN.uuid4" type="function">
  `FN.uuid4() -> str`

  Generate a random UUID string.
</ResponseField>

<ResponseField name="FN.wall_clock" type="function">
  `FN.wall_clock(as_isoformat: bool = False, timespec: str = auto) -> datetime | str`

  Return actual current wall clock time (local, naive).
</ResponseField>

<ResponseField name="FN.weeks" type="function">
  `FN.weeks(x: int) -> timedelta`

  Create timedelta with spcified weeks
</ResponseField>

<ResponseField name="FN.weeks_between" type="function">
  `FN.weeks_between(start: datetime | str, end: datetime | str) -> float`

  Weeks between two datetimes or dates.
</ResponseField>

<ResponseField name="FN.windows_filetime" type="function">
  `FN.windows_filetime(x: datetime | str) -> int`

  Convert datetime to Windows filetime.
</ResponseField>

<ResponseField name="FN.zip" type="function">
  `FN.zip(*iterables: Sequence[Any]) -> list[tuple[Any, ...]]`

  Zip multiple sequences together.
</ResponseField>

<ResponseField name="FN.zip_map" type="function">
  `FN.zip_map(x: list[str], y: list[str]) -> dict[str, str]`

  Zip two arrays into list of key-value pairs, then convert into mapping.
</ResponseField>

## Operator equivalents

<ResponseField name="||" type="operator">
  Equivalent function names: `FN.or`
</ResponseField>

<ResponseField name="&&" type="operator">
  Equivalent function names: `FN.and`
</ResponseField>

<ResponseField name="==" type="operator">
  Equivalent function names: `FN.is_equal`
</ResponseField>

<ResponseField name="!=" type="operator">
  Equivalent function names: `FN.is_not_equal`, `FN.not_equal`
</ResponseField>

<ResponseField name="<" type="operator">
  Equivalent function names: `FN.less_than`
</ResponseField>

<ResponseField name="<=" type="operator">
  Equivalent function names: `FN.less_than_or_equal`
</ResponseField>

<ResponseField name=">" type="operator">
  Equivalent function names: `FN.greater_than`
</ResponseField>

<ResponseField name=">=" type="operator">
  Equivalent function names: `FN.greater_than_or_equal`
</ResponseField>

<ResponseField name="+" type="operator">
  Equivalent function names: `FN.add`
</ResponseField>

<ResponseField name="-" type="operator">
  Equivalent function names: `FN.sub`
</ResponseField>

<ResponseField name="*" type="operator">
  Equivalent function names: `FN.mul`
</ResponseField>

<ResponseField name="/" type="operator">
  Equivalent function names: `FN.div`
</ResponseField>

<ResponseField name="%" type="operator">
  Equivalent function names: `FN.mod`
</ResponseField>

<ResponseField name="in" type="operator">
  Equivalent function names: `FN.contains`, `FN.is_in`
</ResponseField>

<ResponseField name="not in" type="operator">
  Equivalent function names: `FN.does_not_contain`, `FN.is_not_in`, `FN.not_in`
</ResponseField>
