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 expression. Operations in the same node run top-to-bottom and each one sees the writes of the ones before it.
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).
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 |
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.
| 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
Clean up an email before typing it into a form:
{
"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:
{
"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:
{
"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:
{
"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.
Add metadata to a record that was extracted earlier:
{
"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:
{
"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.