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

# Transform

> Clean, derive, or reshape data between nodes

The **Transform** node runs operations that read from and write to the session context. Use it for data shaping, cleanup, combining fields, accumulating results across a loop, or execution-state updates.

Each operation has a `type`, a `target` dot-path under `context.*`, and (for non-`DELETE` ops) a `value` that is a raw [JSONata](https://jsonata.org/) expression. Operations in the same node run top-to-bottom and each one sees the writes of the ones before it.

<Warning>
  The `value` field is **raw JSONata**, not a template. Do not wrap it in `{{...}}` — reference variables directly (e.g. `context.inputs.email ~> $trim`, not `{{context.inputs.email}} ~> $trim`).
</Warning>

## Parameters

| Parameter    | Type  | Required | Description                                                 |
| ------------ | ----- | -------- | ----------------------------------------------------------- |
| `operations` | array | Yes      | Ordered list of operations, each `{ type, target, value? }` |

### Operation Fields

| Field    | Type   | Required              | Description                                                                                           |
| -------- | ------ | --------------------- | ----------------------------------------------------------------------------------------------------- |
| `type`   | string | Yes                   | `SET` or `DELETE`                                                                                     |
| `target` | string | Yes                   | Dot-path under `context.*` where the result is written. Missing intermediate objects are auto-created |
| `value`  | string | Yes (except `DELETE`) | Raw JSONata expression evaluated against the session context                                          |

## Operation Types

| Type     | Semantics                                                                     |
| -------- | ----------------------------------------------------------------------------- |
| `SET`    | Assign the evaluated value to `target`, creating the path if it doesn't exist |
| `DELETE` | Remove the value at `target`. `value` is ignored                              |

<Note>
  For object-merging and array manipulation, use `SET` combined with JSONata's built-in `$merge` and `$append` functions — there is no dedicated merge or append operation type.
</Note>

| Want                                  | Use                                                         |
| ------------------------------------- | ----------------------------------------------------------- |
| Shallow-merge an object into a target | `SET context.x = $merge([context.x, {new_field: 'value'}])` |
| Flat-concatenate two arrays           | `SET context.combined = $append(context.a, context.b)`      |
| Append one element to an array        | `SET context.results = $append(context.results, [item])`    |

## Examples

### Normalize an Input

Clean up an email before typing it into a form:

```json theme={null}
{
  "id": "abc123",
  "name": "Normalize email",
  "action": "TRANSFORM",
  "parameters": {
    "operations": [
      {
        "type": "SET",
        "target": "context.email_clean",
        "value": "context.inputs.email ~> $trim ~> $lowercase"
      }
    ]
  }
}
```

Reference it downstream with `{{context.email_clean}}`.

### Combine Fields

Derive a full name from two inputs:

```json theme={null}
{
  "id": "abc123",
  "name": "Build full name",
  "action": "TRANSFORM",
  "parameters": {
    "operations": [
      {
        "type": "SET",
        "target": "context.full_name",
        "value": "context.inputs.first & ' ' & context.inputs.last"
      }
    ]
  }
}
```

### Combine Two Arrays

Flat-concatenate two arrays using JSONata's `$append`:

```json theme={null}
{
  "id": "abc123",
  "name": "Combine arrays",
  "action": "TRANSFORM",
  "parameters": {
    "operations": [
      {
        "type": "SET",
        "target": "context.combined",
        "value": "$append(context.inputs.array1, context.inputs.array2)"
      }
    ]
  }
}
```

`$append([1, 2], [3, 4])` produces `[1, 2, 3, 4]`. Note that `&` is **string** concatenation in JSONata, not array — use `$append` for arrays.

### Accumulate Loop Results

Inside a loop body, append processed items into an array using `$append`:

```json theme={null}
{
  "id": "abc123",
  "name": "Collect order summary",
  "action": "TRANSFORM",
  "parameters": {
    "operations": [
      {
        "type": "SET",
        "target": "context.collected_orders",
        "value": "$append(context.collected_orders, [{'id': context.runtime.current_order.id, 'total': $number(context.runtime.current_order.amount)}])"
      }
    ]
  }
}
```

The single-element array (`[{...}]`) wrapping is what makes `$append` flat-concatenate one item — passing the bare object would also work (`$append` flattens), but the array form makes intent obvious.

### Enrich an Extracted Object

Add metadata to a record that was extracted earlier:

```json theme={null}
{
  "id": "abc123",
  "name": "Tag with source",
  "action": "TRANSFORM",
  "parameters": {
    "operations": [
      {
        "type": "SET",
        "target": "context.extracted_profile",
        "value": "$merge([context.extracted_profile, {'extracted_at': $now(), 'source': 'crm'}])"
      }
    ]
  }
}
```

### Clean Up Before End

Drop scratch paths so they don't show up in the webhook payload:

```json theme={null}
{
  "id": "abc123",
  "name": "Clean scratch",
  "action": "TRANSFORM",
  "parameters": {
    "operations": [
      { "type": "DELETE", "target": "context.internal_scratch" },
      { "type": "DELETE", "target": "context.tmp_html" }
    ]
  }
}
```

## Notes

* Targets must start with `context.`. Anything else is rejected by validation because downstream nodes can't read it.
* Later operations in the same node see earlier writes, so you can derive values in stages within one Transform.
