Data Mapping
Learn how data flows between nodes, how to reference values from previous steps, and how to transform data for downstream consumption.
How Data Flows
Every node in a workflow produces an output — a JSON object containing the results of its operation. When you connect node A to node B, B can reference any field in A's output.
References use a double-curly-brace syntax: {{nodeId.path.to.field}}. When the execution engine reaches a node, it resolves all references by looking up the outputs of completed upstream nodes.
// Gmail node output
{
"messages": [
{ "subject": "Invoice #1234", "from": "billing@acme.com" }
]
}
// In a downstream Slack node's message field:
"New email from {{gmail.messages[0].from}}: {{gmail.messages[0].subject}}"
// Resolves to:
"New email from billing@acme.com: Invoice #1234"The Data Picker
You don't have to type references manually. The data picker is a visual tool that lets you browse available data and insert references with a click.
Opening the Picker
Click the {{}} icon next to any input field in the node configuration panel. A panel appears showing all upstream nodes and their output schemas.
Browsing Data
The picker displays a tree structure. Expand a node to see its output fields. Expand arrays to see individual items. Click any leaf value to insert its reference into the active input field.
- String fields show the value in quotes.
- Number fields show the numeric value.
- Arrays show the item count and let you drill into individual elements.
- Objects can be expanded to show nested fields.
Live Data Preview
If you have run the workflow at least once, the data picker shows actual output values from the most recent execution. This makes it easy to verify you are referencing the right field.
Path Syntax
The reference syntax supports several access patterns:
| Pattern | Example | Description |
|---|---|---|
| Dot notation | {{node.field}} | Access a top-level field. |
| Nested access | {{node.data.user.name}} | Drill into nested objects. |
| Array index | {{node.items[0]}} | Access a specific array element by index. |
| Array length | {{node.items.length}} | Get the number of items in an array. |
Inside loops
{{loop.item}} to reference the current iteration's value and {{loop.index}} for the zero-based index.Transforming Data
Sometimes the output of one node does not match the expected input of the next. The Transform node lets you reshape data between steps:
- Rename fields — map 'first_name' to 'firstName' for API compatibility.
- Compute new fields — concatenate strings, add numbers, format dates.
- Filter arrays — keep only items that match a condition.
- Flatten or nest — restructure JSON for the downstream API's expected format.
- Type coercion — convert strings to numbers, dates to timestamps, etc.
// Input from Gmail
{
"messages": [
{ "subject": "Q1 Report", "from": "cfo@acme.com", "date": "2025-04-01" }
]
}
// Transform configuration
{
"title": "{{gmail.messages[0].subject}}",
"sender": "{{gmail.messages[0].from}}",
"received_at": "{{gmail.messages[0].date}}"
}
// Output
{
"title": "Q1 Report",
"sender": "cfo@acme.com",
"received_at": "2025-04-01"
}Template Strings
Any text field in a node configuration can contain template variables. Mix static text with dynamic references:
"Hello {{contact.firstName}}, your order #{{order.id}} has shipped!"
// Resolves to:
"Hello Sarah, your order #A-7823 has shipped!"Templates work in message bodies, subject lines, API parameters, file names, and anywhere else you see a text input field.
Best Practices
- Always use the data picker for complex references — it prevents typos and validates paths.
- Name your nodes descriptively (e.g., 'Fetch unread emails') so references are readable in downstream nodes.
- Use a Transform node before complex action nodes to prepare clean, well-structured input.
- Test nodes individually to verify outputs before wiring them into a larger workflow.
- When working with arrays, add a Loop node rather than hardcoding array indices.