---
title: Using the Transform Data Native Action
slug: using-the-transform-data-native-action
docTags: 
createdAt: 2025-08-11T11:13:48.000Z
---

Data transformation, such as converting data into specific formats, has traditionally required expertise in Python or JSONata. However, with Swimlane Turbine, you can achieve these tasks easily using the **Transform Data** native action within a playbook, without the need for complex coding.

## Overview

The **Transform Data** native action allows you to modify and manipulate data efficiently within your playbooks. Whether you need to reformat, extract, or combine data, this action provides a user-friendly interface to achieve these tasks, enabling seamless automation without requiring advanced coding skills.

## Key Benefits of the Transform Data Action

- **No Coding Required:** Perform complex data transformations without writing Python or JSONata code.
- **Visual Transformation Builder:** A user-friendly interface that simplifies data manipulation.
- **Explicit block inputs:** Each block lists **inputs** in a dedicated **Inputs** area (the same idea as the **Script** action). You declare what data the block can use, then **reference those inputs** from the basic (no-code) **FIRST** / **THEN** steps or from the advanced expression. Mark **individual inputs** as **sensitive** using the **lock** icon next to each input when required.
- **Test runs and discovered types:** You can **test** a block, inspect the result, and **discover the output type** (including complex objects) so downstream blocks and actions are not limited to a generic *dynamic* label at design time.
- **Outputs tab:** An **Outputs** tab lets you review action outputs, see what was **discovered** from tests, and mark outputs as **sensitive**.
- **Error outputs for downstream mapping:** When a block fails, its error message is available as a playbook property you can map into later actions (similar to Script action errors).
- **Block workflow:** Configuration uses a **large-format** dialog on an **Inputs** tab, with **expand and collapse** on blocks, **reorder** by **drag and drop** when you need to, and optional **block descriptions**. Each block has **Inputs** and **Transformation** areas; the **Test** panel opens from a **Test** control in the block header when you need it. **Duplicate**, **delete**, **Switch to advanced**, and **Test** sit on the block header. Transformation types show **descriptions in tooltips** when you browse the list.
- **Versatility:** Supports various transformation types to cater to different data processing needs.
- **Efficiency:** Streamlines data handling processes, reducing the time required to implement transformations.

## When to Use Transform Data

The **Transform Data** action is essential whenever you need to modify, extract, or reformat data within your playbook. Common scenarios include:

### Data Format Conversion

- **Parsing JSON strings** from record triggers, record searches, or HTTP responses into JSON objects
- **Converting date/time formats** between different representations (Unix timestamps, ISO-8601, custom formats)
- **Converting data types** (numbers to strings, arrays to objects, and so on)
- **Parsing structured formats** like CSV, XML, or YAML into JavaScript objects

### Data Extraction and Navigation

- **Extracting nested properties** from complex JSON objects using JSONata paths
- **Accessing deeply nested data** structures that require path-based navigation
- **Plucking specific fields** from arrays of objects

### Data Filtering and Aggregation

- **Filtering arrays** based on specific criteria or conditions
- **Aggregating data** (sum, average, min, max) from arrays or object properties
- **Removing duplicates** or unwanted items from arrays
- **Sorting data** by value or by object properties

### Data Manipulation

- **Combining or merging** data from multiple sources
- **Splitting strings** into arrays or arrays into smaller chunks
- **Transforming string formats** (case conversion, padding, encoding/decoding)
- **Normalizing data** to ensure consistent formats across different sources

### Data Preparation for Downstream Actions

- **Preparing data** for HTTP requests, record creation, or other actions that require specific formats
- **Transforming API responses** into formats suitable for record fields
- **Normalizing data** from different sources before combining or comparing

## How Transform Data Integrates

The **Transform Data** action seamlessly integrates with other playbook components, allowing you to access data from various sources and pass transformed data to downstream actions.

### Accessing Playbook Data

At runtime, a playbook still surfaces data from the usual places (playbook inputs, other actions, loops, variables, and so on) using expression paths such as `$inputs` and `$actions` as documented in your playbooks. In **Transform Data** configuration, you connect that data to a block by **defining block inputs** in the inputs panel for the block, then **referencing those inputs** by name from each **FIRST** / **THEN** step in basic mode, or from the JSONata editor in advanced mode. In **advanced** mode, **Add Playbook Property** and **Add Expression** under the code editor add the **Inputs** row and insert the path in one step. The data is **declared** in the inputs list and **referenced** in the steps.

### Data Flow in Playbooks

Transform Data fits into the playbook execution flow as follows:

1. **Input Stage**: Each block receives playbook data through what you **declare** in that block’s **inputs** list (mapped from playbook inputs, previous actions, published values, loops, variables, and so on). Runtime paths such as `$inputs` and `$actions` are unchanged; the configuration surface makes the mapping explicit.
2. **Transformation Stage**: The action processes data through transformation blocks:
   - Each block executes sequentially
   - Transformations within a block chain together (FIRST → THEN → THEN...)
   - Multiple blocks can process different aspects of the data
3. **Output Stage**: Transformed data is available for:
   - **Downstream actions and blocks** in the **same playbook**: Reference block results directly; you do not need to promote outputs for in-playbook use.
   - **Output promotion**: Expose selected outputs **outside** the current playbook (for example when Playbook A calls Playbook B and must read Playbook B’s promoted outputs).
   - **Variables**: Transformed data can be stored in variables
   - **Record Operations**: Transformed data can be used in Create Record, Update Record, or Search Records actions

### Integration with Other Actions

Transform Data commonly integrates with:

- **Record Triggers**: Parse JSON strings from record field values before processing
- **HTTP Request**: Transform API responses into usable formats
- **Search Records**: Process and filter search results
- **Create/Update Records**: Prepare data in the correct format for record fields
- **Condition Actions**: Transform data before evaluating conditions
- **Loop Actions**: Transform data within loop iterations
- **Variable Actions**: Store transformed data in variables for later use

### Referencing Transform Outputs

Each transformation **block** produces a result that downstream actions and blocks in the **same playbook** can use without extra promotion. Reference a block output with:

- `$actions.transformationActionName.result.blockName`

Replace `transformationActionName` with the action’s name in the playbook and `blockName` with the block **key** (for example `block_1`).

The **Outputs** tab lists action outputs, shows which ones were **discovered** (for example from a test), and lets you mark outputs as **sensitive**.

### Reference Transformation Errors in Downstream Actions

When a **Transform Data** block fails, Turbine stores error details on the playbook run for that action and block. You can map those values into downstream action inputs the same way you reference Script action error output.

| Item                         | Detail                                                                                                                                  |
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| **When it applies**          | A block fails during a playbook run (expression error, validation failure, or an intentional `$error` / `$assert` in advanced JSONata). |
| **Where to look in the run** | Open the failed block in the run view to see the error message (including custom messages from `$error` or `$assert`).                  |
| **Property path pattern**    | `$actions.<transformationActionName>.error.<blockKey>` — for example `$actions.transformData.error.block_1.message`                     |
| **Typical fields**           | `message` (required), and when available `code` or `position` for expression errors                                                     |

Replace `transformationActionName` with the action name in the playbook and `blockKey` with the block **key** (for example `block_1`).

**Example workflow:**

1. Add a **Transform Data** action with an advanced block that validates input and calls `$error("Missing required field: email")` when validation fails.
2. Add a downstream action (for example **Create Record** or **HTTP Request**) that should run only on failure, or that needs the error text in a field or body.
3. In the downstream action, map an input from `$actions.<transformActionName>.error.<blockKey>.message`.

For writing expressions that emit custom errors, see [Advanced Transformations](docId:0Ubu_8ysQiBtsET8sWiwp).

### Output Promotion

**Output promotion** is for making playbook data available **outside** the current playbook, not for wiring the next action on the canvas. For example, when Playbook A invokes Playbook B, Playbook A can consume outputs that Playbook B **promoted** at the playbook level.

When your environment supports promoted outputs for native actions, use **Promote** on a block or output to expose it at the playbook boundary. Promoted outputs follow the promotion model used elsewhere in Turbine (Canvas and Classic).

### Entrypoint Configuration

Each Transform Data action has an **entrypoint** that determines which transformation block executes first. This allows you to:

- Control the order of transformation execution
- Create multiple transformation paths
- Organize complex transformations into manageable blocks

## How Transform Data Works

The **Transform Data** native action uses a block-based transformation system where transformations are organized into **blocks**, and each block contains one or more transformation operations that are executed sequentially.

### Understanding Transformation Blocks

Each transformation block consists of:

- **Header and metadata:** A **title** (for display), a stable **key** (for references and result paths), and an optional **description** you can use to document intent.
- **Inputs:** A defined list of the data this block is allowed to use, shown in the **Inputs** area for the block.
- **Transformation:** The **FIRST** / **THEN** chain in basic mode, or the JSONata **code editor** in advanced mode.
- **Test:** Optional test panel (toggle **Test** in the block header) for test data, a **Test** run, **Result**, and **Discovered Outputs** for the block.

Transformations are chained together, with each transformation receiving the output from the previous one. This allows you to build complex data transformations by combining multiple simple operations.

### Key Concepts

- **Block-based Structure**: Transformations are organized into blocks that you can rename, duplicate, **drag to reorder** (updating the block chain), or delete.
- **Sequential Execution**: Transformations within a block execute in order (FIRST → THEN → THEN...).
- **Data Flow**: The output of one transformation becomes the input for the next transformation.
- **Multiple Blocks**: You can create multiple transformation blocks, each processing different aspects of your data.
- **Sensitive Data:** You can mark **individual inputs** as sensitive (lock icon) so values are protected consistently. The **Outputs** tab supports marking outputs as **sensitive** as well.

## Setting Up the Transform Data Native Action

You have already created your playbook, and you are ready to transform data. Use the following steps to open **Transform Data** configuration and build blocks.

1. From the **Add** panel, drag the **Transform** action onto the playbook canvas.
2. Open **Transform Data** and select **Configure**.

The configuration opens in a **large-format** dialog on the **Inputs** tab, which lists your transformation **blocks** in order.

Each block is laid out in three areas:

| Area               | Purpose                                                                                                                                                                                                                                                                                |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Inputs**         | Declare properties the block can use (**+ Add property**). Mark inputs as **sensitive** with the lock icon.                                                                                                                                                                            |
| **Transformation** | Build the **FIRST** / **THEN** chain in basic mode, or the **code editor** in advanced mode.                                                                                                                                                                                           |
| **Test**           | Open from the **Test** control in the block header (collapsed by default). Provide test data (**Custom JSON** or a **previous run**), run **Test**, view **Result** or **Discovered Outputs**, and use **Copy inputs to editor** when you want the current test payload in the editor. |

### Work with blocks

- **Add blocks:** Use **CREATE YOUR FIRST BLOCK** (when the list is empty) or **ADD BLOCK** to add another block. Each block is one chain of transformations.
- **Reorder blocks:** Use the **drag** handle in the block header to drag and drop blocks into the order you want. Execution still follows the linked **entrypoint** and **next** block chain as defined in your playbook; reordering updates that chain when you apply changes.
- **Block header:** The header shows the block **title** (click the title or the **edit** control to change it, then **save**). Use **Duplicate** to copy a block, or the **delete** control to remove a block.
- **Test panel:** Click **Test** in the block header to show or hide the test panel for that block. The panel starts **hidden** so **Inputs** and **Transformation** use the full block height until you open it.
- **Switch to advanced:** When the block is **expanded**, choose **Switch to advanced** in the block header. A confirmation asks **Are you sure you want to switch to advanced mode?** Switching is **irreversible** for that block; existing basic steps are converted. Click **Confirm** to continue or **Cancel** to stay in basic mode. See [Advanced Transformations](docId:0Ubu_8ysQiBtsET8sWiwp).
- **Code editor configuration:** In advanced mode, open **Code Editor Configuration** to toggle **Show line numbers**, **Show expand/collapse arrows**, and **Show fold gutter**, and to choose a **Theme** (for example Dracula, Monokai, or Eclipse).
- **Block key and optional description:** Below the title, the block’s **key** (snake case) identifies it for references and result paths. Use the **lock** control to edit the key. Renaming a key can break existing references. In the **Transformation** area, you can add an optional **block description** (for example, what this block is for) above the **FIRST** / **THEN** steps.
- **Expand and collapse:** Blocks can be **collapsed** to move through long chains faster. With **multiple** blocks, they typically start **collapsed**; with a **single** block, the product typically keeps it **expanded** by default. Collapse also makes **drag and drop** reordering easier.
- **Explicit inputs vs transformation steps:** Use the **Inputs** area to declare data the block is allowed to use. You can add inputs manually. For an existing action, any stored block **data** appears in this list so you can see and edit it. Reference those **inputs** from the **Transformation** fields.
- **Per-input sensitive:** Mark specific **inputs** as sensitive using the **lock** icon next to the input.

:::hint{type="warning"}
If you **Apply** changes and return later, the **block title** you see may stay as saved until you edit it again. Use the title or **edit** control, then save. The block **key** is edited separately via the **lock** control and governs how the block is referenced in expressions and result paths.
:::

:::hint{type="danger"}
Renaming a block **key** can break downstream actions if the block is referenced elsewhere in the playbook. A warning dialog can appear to remind you of that risk.
:::

### Configuring the Transformation (basic / no-code)

In each block, you first wire **inputs**, then build the **FIRST** / **THEN** chain.

1. **Inputs:** In the **inputs** section for the block, add or review the data this block is allowed to use. For an existing action, the same data that is stored in the block’s **data** in the playbook definition appears in this list so you can see and edit it in one place.
2. **FIRST** row: Open **Select a Transformation** and pick a type. Descriptions for each function appear in **tooltips** when you hover the options in the list.
3. For each parameter, you can use a **literal** value (for example type a number directly), or use a **control** (often a **dropdown**) to pick which **declared input** to use. The list **filters** as you type, and you can use **keyboard navigation** to move through choices.
4. **THEN** rows: Use **CREATE YOUR FIRST TRANSFORMATION** (when the block has no step yet) or **TRANSFORM AGAIN** to add another step. The next row is **THEN** and uses the output of the step above.

**Objects and arrays:** You can add **object**- or **array**-typed properties to the inputs. Reference them in parameters using the full path with **dot notation** or **bracket notation** where the product provides it, including nested properties from discovered complex outputs in another block.

**Tip:** If a value comes from a JSON string on a record field, use **Parse JSON** in the chain (with the right **input** wired) before other steps that expect an object.

### Configuring the Transformation (advanced / JSONata)

In **advanced** mode, wire **inputs** and write JSONata in the **code editor**. See [Advanced Transformations](docId:0Ubu_8ysQiBtsET8sWiwp) for expression syntax, `$error`**&#x20;/&#x20;**`$assert`, and **Code Editor Configuration**.

| Shortcut                                          | Use when                                                                                                            |
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| **+ Add property** (Inputs area)                  | You want to declare inputs manually, then type paths in the editor.                                                 |
| **Add Playbook Property** (under the code editor) | You want to pick playbook data from the drawer; Turbine adds the **Inputs** row and inserts the path at the cursor. |
| **Add Expression** (under the code editor)        | You want to enter a playbook expression; Turbine adds the **Inputs** row and inserts the path at the cursor.        |

When you **rename** or **delete** an input in the **Inputs** panel, Turbine updates matching references in the JSONata expression. When you edit the expression only, remove unused **Inputs** rows yourself.

### Test a block and work with discovered outputs

**In-product testing** is available for a single block at a time. Click **Test** in the block header to open the test panel if it is hidden.

- **Test:** Run **Test** to execute the current block. You can **resize** the **Test** area if needed. The **Result** tab shows the output (for example a number or object). Use **Copy inputs to editor** to copy the current test inputs into the editor.
- **Previous run:** When available, choose a **previous playbook run** so the **inputs for that block** load from that run.
- **Custom JSON:** If the inputs are empty (for example a default **empty object**), choosing **Custom JSON** from the dropdown can load a shape based on the **current inputs** and set **default values** by type.
- **Discovered outputs:** After a successful test, open the **Discovered Outputs** tab to see output **types** (not only “dynamic” in the model). Add those findings to the block’s **known outputs**, including **complex** objects and nested properties, so a **downstream block** can reference a prior block’s output with a **known** type in the input picker.

### Outputs tab

The **Outputs** tab (at the action level) gives you a single place to see **outputs** for the action, mark them **sensitive**, and see which outputs were **discovered** from tests. Input sensitivity is configured in each block’s **Inputs** area, not on this tab.

### Backward compatibility and cleanup

- **Existing playbooks:** Opening an existing **Transform Data** action shows the same underlying data in the **inputs** list, including any values that are stored in each block’s **data** in the playbook and values you added through **Add Playbook Property**, **Add Expression**, or manual **+ Add property**.
- **Input rename and delete (advanced mode):** When you **rename** or **delete** an input in the **Inputs** panel, Turbine rewrites matching paths in the JSONata expression (deleted inputs appear as `$DELETED` in the code).
- **Removing a reference in code only:** If you delete a reference by editing the expression and do not change **Inputs**, the product does **not** remove the matching row from the **inputs** list. **Remove the input** yourself when it is no longer needed.

### Attachments

**Attachments** are unchanged: you do not upload new static files inside **Transform Data**. Use a **playbook property** that already carries the attachment and pass it through. Broader file-based **batch** processing is tracked as a separate feature area.

## Available Transformations

The Transform Data action provides a wide range of transformation functions organized by category. The following transformations are available from **Select a Transformation**; hover an option in the list to read its **tooltip** description in the product.

### Array Transformations

- **Average** - Calculate the average value of numeric array elements. Returns the mean of all numeric values in the array.
- **Average By** - Calculate the average value of a plucked property of objects within an array of objects. Uses a JSONata path to extract the property values before calculating the average.
- **Count If** - Count all items of an array that are equal to a specific value. Returns the number of matching elements.
- **Count If By** - Count all items of an array of objects that contain a plucked property equal to a specific value. Uses a JSONata path to access the property for comparison.
- **Filter** - Filter an array to the values that match a regular expression, a specific value, or non-null value. Supports both exact matches and regex patterns.
- **Filter By** - Filter an array of objects to those that contain a property or deeply nested property whose values match a regular expression, a specific value, or non-null value. Uses a JSONata path to access the property.
- **Flatten** - Flatten an array containing potentially nested arrays to a single array. Removes one level of nesting.
- **Force Array** - Wrap a value in an array if it is not already an array. Ensures the output is always an array type.
- **Get At** - Get the item of an array at a specific index. Supports negative indices (for example, -1 for the last item).
- **Maximum** - Find the maximum value in an array of numbers. Returns the largest numeric value.
- **Maximum By** - Find the maximum value of a plucked property of the objects within an array of objects. Uses a JSONata path to extract property values.
- **Mean** - Compute the mean of the values in an array of numbers. Calculates the arithmetic mean.
- **Mean By** - Compute the mean of the values plucked from objects within an array of objects. Uses a JSONata path to extract values.
- **Minimum** - Find the minimum value in an array of numbers. Returns the smallest numeric value.
- **Minimum By** - Find the minimum value of a plucked property of the objects within an array of objects. Uses a JSONata path to extract property values.
- **Prepend** - Get an array containing the value or array of values of the second input followed by the value or array of values of the first input. Combines arrays or prepends values.
- **Remove Duplicates** - Remove duplicate items from an array. Returns a new array containing unique values only.
- **Remove Item** - Remove all instances of an item from an array. Filters out all occurrences of the specified item.
- **Slice** - Get the subarray of items that exist between the specified starting and ending indices of an array. Extracts a range of elements.
- **Sort** - Sort the items of an array of strings or numbers by value. Supports ascending and descending order with locale-aware comparison.
- **Sort By** - Sort the items of an array of objects by the value of a plucked property of the objects within the array. Uses a JSONata path to determine sort order.
- **Sum** - Sum the values of an array of numbers. Returns the total of all numeric values.
- **Sum By** - Sum the values of a plucked property of the objects within an array of objects. Uses a JSONata path to extract property values before summing.

### Date and Time Transformations

- **Adjust Date / Time** - Adjust an ISO-8601 date/time or a Unix epoch by adding or subtracting a specified amount of time. Supports operations (Adding/Subtracting), amount, and units (Milliseconds, Seconds, Minutes, Hours, Days, Weeks, Months, Years). Returns the adjusted timestamp in ISO-8601 format.
- **Append Time Zone** - Append or overwrite the time zone or offset of an ISO-8601 date/time without adjusting the underlying date/time. Useful for adding timezone information to dates that lack it.
- **Convert Date / Time** - Convert an ISO-8601 date/time or a Unix epoch to an ISO-8601 date/time, custom formatted date/time, or a Unix epoch. Supports output formats: ISO-8601, Unix (seconds), Unix (milliseconds), SQL, or Custom format string.
- **Get Date / Time** - Parse a date/time and convert it to an ISO-8601 date/time. Can get the current time or parse a date/time from playbook data. Supports various input formats (ISO-8601, Unix, SQL, Custom) and timezone handling.
- **Set Time Zone** - Set the time zone or offset of an ISO-8601 date/time, adjusting the underlying date/time accordingly. Converts the date/time to the specified timezone.
- **To ISO Date** - Convert an ISO-8601 date/time or a Unix epoch to an ISO-8601 date. Extracts only the date portion, discarding the time component.
- **To ISO Time** - Convert an ISO-8601 date/time or a Unix epoch to an ISO-8601 time. Extracts only the time portion, discarding the date component.

### Numeric Transformations

- **Absolute Value** - Compute the absolute value of a number. Returns the non-negative value of the input number.
- **Adjust** - Adjust a number by adding, subtracting, multiplying by, dividing by, or computing the modulo with another number. Supports basic arithmetic operations.
- **Ceiling** - Adjust a number by rounding it up (ceiling). Rounds up to the nearest integer or specified precision.
- **Floor** - Adjust a number by rounding it down (flooring). Rounds down to the nearest integer or specified precision.
- **Greater Than** - Check if the first number is greater than the second. Returns a boolean value.
- **Greater Than Or Equal** - Check if the first number is greater than or equal to the second. Returns a boolean value.
- **In Range** - Check if a number is between two values, non-inclusive of the ending value. Determines if a value falls within a specified range.
- **Less Than** - Check if the first number is less than the second. Returns a boolean value.
- **Less Than Or Equal** - Check if the first number is less than or equal to the second. Returns a boolean value.
- **Random** - Generate a random number between inclusive lower and upper bounds. Can generate either floating-point or integer values.
- **Round** - Adjust a number by rounding it. Rounds to the nearest integer or specified precision.

### Object Transformations

- **Deep Flatten** - Deeply flatten an object. Converts nested object structures into a flat structure with dot-notation keys.
- **Deep Merge** - Deep merges two given objects. Combines objects recursively, with values from the second object taking precedence.
- **Extract Property** - Extract the value of a property or deeply nested property of an object. Uses a JSONata property path to navigate through nested structures (for example, `user.profile.email` or `$.data.items[0].name`).
- **Get Keys** - List the keys of a given object. Returns an array containing all property names of the object.
- **Get Values** - List the property values of a given object. Returns an array containing all property values of the object.
- **Is Equal** - Perform a deep comparison between two values to determine if they are equivalent. Returns true if values are deeply equal, false otherwise.
- **Pick Properties** - Create an object composed of the picked properties. Selects specific properties from an object to create a new object.
- **Remove Property** - Remove a property on an object. Supports nested property paths using dot notation. Returns a new object with the specified property removed.
- **Stringify** - Convert an object into stringified form. Converts the object to a JSON string representation.

### String Transformations

- **Base64 Decode** - Convert a string from base 64 representation. Decodes base64-encoded text with optional character encoding specification.
- **Base64 Encode** - Convert a string to base 64 representation. Encodes text to base64 with optional character encoding specification (default UTF-8).
- **Camel Case** - Convert a string to camel case. Transforms text to camelCase format (for example, "hello world" → "helloWorld").
- **Capitalize** - Convert the first character of a string to upper case and the remaining to lower case. Capitalizes only the first letter.
- **Contains** - Determine if a string contains at least one occurrence of a search term. Supports case-sensitive and case-insensitive matching. Returns a boolean value.
- **Defang** - Replace and/or surround certain characters in a string to render it unactionable (for example, non-clickable). Used for security purposes to prevent accidental execution of URLs, IPs, and similar values.
- **Ends With** - Check if a string ends with another. Returns true if the string ends with the target value.
- **Evaluate Expression** - Parse and evaluate a string containing literal JSON or a JSONata expression. Allows you to execute complex JSONata expressions for advanced transformations.
- **Hash** - Compute the hash of a value. Supports multiple hash algorithms including MD5, SHA1, SHA224, SHA256, SHA384, SHA512, and SHA3 variants. Returns the hashed value in hexadecimal format.
- **Levenshtein Distance** - Find the edit/Levenshtein distance between two strings. Calculates the minimum number of single-character edits needed to transform one string into another.
- **Match** - Find occurrences of a search term in a string and returns an array of all indices where the search term is located. Supports case-sensitive and case-insensitive matching.
- **Pad** - Pad a string on the left and right sides if it is shorter than length. Padding characters are truncated if they cannot be evenly divided by length.
- **Pad End** - Pad a string on the right side if it is shorter than length. Adds padding characters to the end of the string.
- **Pad Start** - Pad a string on the left side if it is shorter than length. Adds padding characters to the beginning of the string.
- **Parse JSON** - Convert stringified JSON text to a JSON value. Parses a JSON string into a JavaScript object that can be used in subsequent transformations.
- **Refang** - Restore a defanged string to its original value to re-render it actionable (for example, clickable). Reverses the defang operation.
- **Repeat** - Repeat a string N times. Creates a new string by repeating the input string the specified number of times.
- **Replace** - Find occurrences of a search term in a string and replaces each occurrence with another string. Supports case-sensitive and case-insensitive replacement with global replacement by default.
- **Split** - Find occurrences of a delimiter in a string and splits the string into an array of substrings for each occurrence. Divides a string into an array based on the delimiter.
- **Starts With** - Check if a string starts with another. Returns true if the string begins with the target value.
- **Strip** - Remove all whitespace (tabs, spaces, and newlines) from both the left and right side of text. Spaces in between words will not be removed.
- **URL Decode** - Convert URL-safe characters in a given string to URL-unsafe characters. Decodes URL-encoded strings (for example, "%20" → " ").
- **URL Encode** - Convert URL-unsafe characters in a given string to URL-safe characters. Encodes strings for use in URLs (for example, " " → "%20").
- **UUID v4** - Generate a v4 universally unique identifier (UUID). Creates a random UUID following the UUID v4 specification.

### Regular Expression Transformations

- **Contains** - Check if a string contains at least one occurrence of a regular expression pattern. Supports regex flags ('i' for ignore case, 'm' for multiline). Returns a boolean value.
- **Match** - Find occurrences of a regular expression pattern in a string and returns an array of the matched strings. Can return either matches or capture groups, with optional limit on number of matches.
- **Match One** - Find the first occurrence of a regular expression pattern in a string and returns the matched string. Returns the first match or an empty string if no match is found.
- **Replace** - Find occurrences of a regular expression pattern in a string and replaces each occurrence with another string. Supports regex flags and optional limit on number of replacements.
- **Split** - Find occurrences of a regular expression pattern in a string and splits the string into an array of substrings for each occurrence. Uses regex pattern as delimiter with optional limit.

### Value Transformations

- **From CSV** - Parse a CSV string. Converts CSV text into an array of objects (if headers are included) or an array of arrays. Supports header detection.
- **From XML** - Parse an XML string. Converts XML text into a JavaScript object using compact format.
- **From YAML** - Parse a YAML string. Converts YAML text into a JavaScript object.
- **Is Array** - Check if a value is an array. Returns true if the value is an array, false otherwise.
- **Is Blank** - Determine if a value is an empty string, array, object or falsy. Returns true for empty values, null, undefined, empty strings, empty arrays, or empty objects.
- **Is Empty** - Determine if a value is an empty string, array, or object. Similar to Is Blank but excludes boolean false from being considered empty.
- **Is Null Or Undefined** - Check if a value is null or undefined. Returns true only for null or undefined values.
- **Is Object** - Check if a value is an object. Returns true if the value is an object (but not an array), false otherwise.
- **Is String** - Check if a value is a string. Returns true if the value is a string type, false otherwise.
- **To CSV** - Serialize a value to CSV. Converts an array of objects to CSV format with headers.
- **To XML** - Serialize a value to XML. Converts a JavaScript object to XML format using compact representation.
- **To YAML** - Serialize a value to YAML. Converts a JavaScript object to YAML format.

## Examples

Create any **block inputs** you need before you bind **FIRST** / **THEN** parameters. The steps below focus on the transformation chain itself.

### Example 1: Extracting Data from a JSON Object

**Scenario:** You receive data in JSON format and need to extract specific fields for further processing.

1. Drag and drop the **Transform Data** action onto the playbook canvas.
2. Configure the transformation to extract the desired data:
   - **FIRST**: If your data is a JSON string, select **Parse JSON** from the transformation type drop-down to convert it to a JSON object.
   - **THEN**: Select **Extract Property** and provide a JSONata path to navigate to the specific JSON fields (for example, `$.user.name` or `user.email`).

**Output:** The extracted data is ready for subsequent actions.

### Example 2: Combining Array Values

**Scenario:** Combine multiple values from an array into a single string or combine two arrays.

1. Drag and drop the **Transform Data** action.
2. Configure the transformation:
   - **FIRST**: Select **Prepend** from the transformation type drop-down to combine arrays or values.
   - **THEN**: Provide the values or arrays you want to combine.

**Alternative:** For string concatenation, you can use **Evaluate Expression** with a JSONata expression like `$join([first_name, last_name], " ")` to combine strings with a separator.

**Output:** Combined values or arrays ready for use.

### Example 3: Converting Date Formats

**Scenario:** Convert a date from one format to another (for example, from Unix timestamp to ISO-8601, or from custom format to ISO-8601).

1. Add the **Transform Data** action to the playbook.
2. Configure the transformation:
   - **FIRST**: Select **Get Date / Time** from the transformation type drop-down to parse the date from your data source.
   - **THEN**: Select **Convert Date / Time** and specify the output format (for example, ISO-8601, Unix seconds, Unix milliseconds, SQL, or Custom format).

**Output:** The date converted to the desired format.

### Example 4: Filtering Array Elements

**Scenario:** Filter an array to include only items that meet specific criteria (for example, users older than 18, or strings containing a specific pattern).

1. Use the **Transform Data** action.
2. Configure the transformation:
   - **FIRST**: Select **Filter** from the transformation type drop-down to filter by value or regular expression.
   - **THEN**: Provide the filter value or pattern. For filtering objects by property values, use **Filter By** and specify the JSONata path to the property (for example, `age`) and the filter value (for example, `18`).

**Output:** An array containing only items that match the filter criteria.

### Example 5: Parsing JSON Strings

**Scenario:** You have a JSON string from a record trigger or record search that needs to be parsed into a JSON object for further transformation.

1. Drag and drop the **Transform Data** action.
2. Configure the transformation:
   - **FIRST**: Select **Parse JSON** from the transformation type drop-down to convert the JSON string to a JSON object.
   - **THEN**: Apply additional transformations as needed (for example, extract properties, filter, and so on).

**Output:** The JSON string is converted to a JSON object that can be used in subsequent transformations.

### Example 6: Adjusting Date/Time Values

**Scenario:** Add or subtract time from a date (for example, add 5 days, subtract 2 hours).

1. Drag and drop the **Transform Data** action.
2. Configure the transformation:
   - **FIRST**: Select **Get Date / Time** from the transformation type drop-down if starting from a data source, or use an existing date value.
   - **THEN**: Select **Adjust Date / Time** and specify:
     - Operation: Adding or Subtracting
     - Amount: The number of time units
     - Unit: Milliseconds, Seconds, Minutes, Hours, Days, Weeks, Months, or Years

**Output:** The adjusted date/time in ISO-8601 format.

## Best Practices

- **Start Simple:** Begin with basic transformations and progressively add complexity as needed.
- **Test blocks:** Use the **Test** flow for a block when you need to validate JSONata or no-code steps, **discover** output types, and align **downstream** inputs.
- **Keep Track of Changes:** Document the purpose and expected outcome of each transformation block for easier maintenance.
- **Avoid Overcomplicating:** Use clear and straightforward transformations to ensure maintainability.
- **Use Parse JSON First:** When working with JSON strings from record triggers or searches, always use **Parse JSON** as the first transformation before extracting properties or performing other operations.
- **Chain Transformations:** Leverage the THEN functionality to chain multiple transformations together, building complex transformations from simple operations.

## Quoting Rules for String Parameters

Transformation expressions use JSONata, which requires **double quotes** (`"`) for all string values. Single quotes (`'`) are **not supported** and will cause the transformation to fail silently or produce unexpected results.

:::hint{type="info"}
Always use double quotes for string parameters in transformation expressions. Single-quote escaping (`\'`) is not valid in JSONata.
:::

### Correct Usage

| Expression                                | Result or notes                                                                              |
| ----------------------------------------- | -------------------------------------------------------------------------------------------- |
| `$stringCapitalize("hello world")`        | Produces: `Hello world`                                                                      |
| `$stringCapitalize("This is a 'test'")`   | Apostrophes inside the string are fine. Only the **outer** delimiters must be double quotes. |
| `$stringCapitalize("This is a \"test\"")` | Type `\"` inside the string to include a **literal** double quote in the value.              |

### Incorrect Usage

| Expression                                                               | Problem                                                                                                             |
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- |
| `$stringCapitalize('hello world')`                                       | Single quotes are not valid JSONata string delimiters.                                                              |
| An argument that uses **single quotes** (`'…'`) as the string delimiters | Not valid in JSONata. Use **double-quoted** strings only, and use `\"` for a literal double quote inside the value. |

:::hint{type="info"}
If you need to include literal single quotes inside a string, wrap the entire string in double quotes. Single quotes do not need escaping when they appear inside a double-quoted string, for example: `"This is a 'test'"`.

This quoting rule applies to both basic (no-code) and advanced (JSONata) transformation modes. For more information on advanced transformations, see [Advanced Transformations](docId:0Ubu_8ysQiBtsET8sWiwp).
:::

## Use Cases

For more practical applications, explore the [Transform Data Action - Use Cases](https://docs.swimlane.com/transform-data-action-use-cases).
