When to Use
- Parse a raw HTTP response body: An HttpRequest node returns a raw JSON string in the body field. Before accessing individual fields, use
parse to convert it to a live object that downstream nodes can navigate with dot-notation expressions.
- Stringify an object for an email or log body: A workflow assembles a complex object during processing. Use
stringify to convert it to pretty-printed JSON for inclusion in a debug email, Slack notification, or execution log entry.
- Minify JSON for database storage or API request body: A large metadata object should be stored as a compact JSON string in a single database column. Use
minify to remove all whitespace before the DB insert, reducing storage size.
- Extract a single deeply nested property without a full DataMapping node: An API response contains
transaction.payment.processor.transactionRef. Use extract with Property: "transaction.payment.processor.transactionRef" to pull out just that value in one step.
- Merge a base object with an update overlay: A customer record from the database serves as the base. A webhook payload contains field updates. Use
merge to shallow-merge the updates onto the base, producing the updated record object without writing any code.
- Remove null entries from an API response array: Some REST APIs return arrays with null placeholders for deleted items. Use
filter to clean the array before passing it to a CollectionOperation or Loop node.
Configuration
| Setting | Required | Description |
Operation |
Required |
The JSON operation to perform. One of: parse, stringify, minify, extract, merge, filter. |
Source |
Optional |
An inline JSON string or value to operate on. Supports BizFirst expressions: {{ $output.httpNode.body }}. When omitted, SourceOutput is used. |
SourceOutput |
Optional |
The node key of an upstream node whose output is used as the source for the operation. |
Property |
Optional |
Required for the extract operation. A dot-notation path to the property to extract. Example: "user.address.city", "data.items[0].id". |
MergeWith |
Optional |
Required for the merge operation. A JSON object (inline or expression) to shallow-merge onto the primary source. Properties in MergeWith overwrite matching properties in the source. |
Operations Reference
| Operation | Input | Output | Notes |
parse |
JSON string |
Object or Array |
Deserializes a JSON string into a live workflow object. Required before you can access individual fields of a raw JSON string response. Fails if the input is not valid JSON. |
stringify |
Object or Array |
Pretty-printed JSON string (2-space indentation) |
Useful for email bodies, Slack message payloads, and execution logs. Handles circular reference detection — circular references produce an error on the error port. |
minify |
Object, Array, or JSON string |
Compact JSON string (no whitespace) |
Produces the smallest possible valid JSON representation. Ideal for database single-column JSON storage and API request bodies where payload size matters. |
extract |
Object or Array |
The value at the specified Property path |
Uses dot-notation navigation. Returns null if the path does not exist. For simple single-field extraction — use DataMapping for multiple field mappings. |
merge |
Two objects: source + MergeWith |
Merged object |
Shallow merge only — nested objects from source are replaced entirely by the same key from MergeWith, not deep-merged. For deep merge, use a Function node. |
filter |
Array |
Array (nulls and undefined removed) |
Removes all null and undefined entries from the array. Does not remove falsy values like 0, false, or "" — only explicit null/undefined. |
Output Ports
| Port | When It Fires |
success | The operation completed without error. The result is available in transformed_data. |
error | The operation failed: invalid JSON input for parse, circular reference in stringify, invalid dot-notation path in extract, or missing required parameter for the chosen operation. |
Output Fields
| Field | Type | Description |
transformed_data | any | The result of the operation. Type depends on the operation: object (parse, merge), string (stringify, minify), any (extract), array (filter). |
operation | string | The operation name executed (e.g., "parse"). Useful for generic processing pipelines that handle multiple operation types. |
Sample Configurations
Parse — convert HTTP response body string to object
{
"nodeType": "json-transform",
"settings": {
"Operation": "parse",
"Source": "{{ $output.httpRequestNode.body }}"
}
}
// transformed_data: the parsed object ready for field access
Extract — pull a single nested property
{
"nodeType": "json-transform",
"settings": {
"Operation": "extract",
"SourceOutput": "apiResponseNode",
"Property": "data.customer.billing.address.postcode"
}
}
// transformed_data: "EC1A 1BB" (the postcode string)
Merge — overlay webhook updates onto database record
{
"nodeType": "json-transform",
"settings": {
"Operation": "merge",
"SourceOutput": "dbFetchNode",
"MergeWith": "{{ $output.webhookTrigger }}"
}
}
// transformed_data: the db record with webhook fields overlaid
Minify — compact for database storage
{
"nodeType": "json-transform",
"settings": {
"Operation": "minify",
"SourceOutput": "buildMetadataNode"
}
}
// transformed_data: "{\"key\":\"value\",\"count\":42}" (no whitespace)
Sample Output
Success Port
{
"transformedData": {
"orderId": "ORD-2025-00123",
"customerName": "Acme Corporation",
"lineItems": [
{ "sku": "PRD-001", "qty": 5, "unitPrice": 29.99, "lineTotal": 149.95 },
{ "sku": "PRD-007", "qty": 2, "unitPrice": 89.99, "lineTotal": 179.98 }
],
"subtotal": 329.93,
"tax": 26.39,
"total": 356.32,
"currency": "USD"
},
"_inputKeys": ["order_id", "customer", "items", "amounts"],
"_outputKeys": ["orderId", "customerName", "lineItems", "subtotal", "tax", "total", "currency"]
}
Expression Reference
| Expression | Value |
{{ $output.jsonTransformNode.transformed_data }} | The full result of the operation. |
{{ $output.jsonTransformNode.transformed_data.customer.id }} | After a parse operation, navigate into the resulting object. |
{{ $output.jsonTransformNode.operation }} | The operation name string. |
Node Policies & GuardRails
| Policy | Rationale |
Always parse raw HTTP response bodies before accessing fields | HTTP response body data from HttpRequest nodes arrives as a string. Attempting to use dot-notation on a string produces null results. Insert a JsonTransform parse node between HttpRequest and any DataMapping or IfCondition that accesses response fields. |
Use extract for single properties, DataMapping for multiple fields | If you need to extract only one field from a response, extract is concise and readable. If you need to rename and extract multiple fields, DataMapping with multiple Mappings rules is cleaner and more maintainable. |
merge is shallow — understand the implications | If the source contains nested objects and the MergeWith contains the same top-level key (even if it's a nested object), the entire nested object is replaced, not merged. Use a Function node for true deep-merge behaviour. |
Connect the error port for parse operations | If an upstream node produces malformed JSON or an empty string, the parse operation fails. The error port should route to a notification node so invalid upstream data does not silently stall the workflow. |
Pattern Examples
Pattern 1 — Parse and Extract in Sequence
An HttpRequest returns the body as a string. Parse it first, then extract the specific field needed downstream.
// HttpRequest returns: body = '{"data":{"transaction":{"id":"TXN-001","amount":5000}}}'
// Node 1: JsonTransform — parse the body string
{
"Operation": "parse",
"Source": "{{ $output.httpRequestNode.body }}"
}
// transformed_data = { data: { transaction: { id: "TXN-001", amount: 5000 } } }
// Node 2: JsonTransform — extract the transaction ID
{
"Operation": "extract",
"SourceOutput": "parseBodyNode",
"Property": "data.transaction.id"
}
// transformed_data = "TXN-001"
Pattern 2 — Merge Customer Record with Incoming Updates
A webhook delivers partial customer updates. Fetch the full record from the DB, then merge the webhook data over it before saving.
// DB record: { id: "C-001", name: "Alice", email: "alice@old.com", tier: "standard" }
// Webhook data: { email: "alice@new.com", tier: "premium" }
// JsonTransform — merge (webhook overwrites matching fields)
{
"Operation": "merge",
"SourceOutput": "dbFetchCustomerNode",
"MergeWith": "{{ $output.webhookTrigger }}"
}
// Result: { id: "C-001", name: "Alice", email: "alice@new.com", tier: "premium" }
Pattern 3 — Stringify for Debug Email
At the end of a complex processing workflow, stringify the full result object and include it in a debug notification email.
// JsonTransform — stringify the processing result
{
"Operation": "stringify",
"SourceOutput": "finalProcessingNode"
}
// Downstream EmailSmtp node body:
// "Processing complete. Full result:\n\n{{ $output.stringifyNode.transformed_data }}"