Merge Node
Combine data from multiple workflow branches into a single context. Supports five merge strategies — from simple object combination to inner joins and cartesian products.
How It Works
The Merge node accepts 2–10 input branches and waits for all of them to complete before merging their data. Choose a strategy that fits your use case.
Merge Strategies
Combine
Merge all branch contexts into a single object. Keys from later branches overwrite keys from earlier branches on collision.
Branch A: Shiprocket — Track Shipment → { shiprocket: { current_status: "In Transit" } }
Branch B: Razorpay — Fetch Payment → { razorpay: { status: "captured", amount: 50000 } }
Merge (Combine)
→ Output: { shiprocket: {...}, razorpay: {...} }
→ Gmail — Send Email
body: "Payment: {{razorpay.status}} | Shipping: {{shiprocket.current_status}}"Position
Zip arrays from two branches by index. Pairs item[0] from branch A with item[0] from branch B, and so on.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
fillMode | string | No | shortest | "shortest" — stop at end of shortest array | "longest" — pad with null |
Cross Join
Create the cartesian product of two arrays — every item from branch A paired with every item from branch B (N × M output rows).
Branch A: [ { sku: "TS-S" }, { sku: "TS-M" }, { sku: "TS-L" } ]
Branch B: [ { warehouse: "Mumbai" }, { warehouse: "Delhi" } ]
Merge (Cross Join) → 6 pairs:
{ sku: "TS-S", warehouse: "Mumbai" }
{ sku: "TS-S", warehouse: "Delhi" }
{ sku: "TS-M", warehouse: "Mumbai" }
...Key Match (Inner Join)
Join two arrays where a shared key value matches — like a SQL inner join. Items without a matching key are excluded.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
keyPath1 | string | Yes | — | Dot-path key in branch 1 array, e.g. orderId |
keyPath2 | string | Yes | — | Dot-path key in branch 2 array, e.g. order_id |
Key Difference
Return only items from branch 1 that do NOT have a matching key in branch 2 — like a SQL LEFT ANTI JOIN. Use to find orders that have not been shipped.
Output Variables
| Variable | Type | Description |
|---|---|---|
{{merge.result}} | array | object | The merged output — object for Combine, array for all others |
{{merge.count}} | number | Number of items in result (array strategies) |
{{merge.mode}} | string | The strategy used: combine | position | crossjoin | keymatch | keydiff |
{{merge.mergedAt}} | string | ISO timestamp when merge completed |
Complete Workflow Examples
Parallel Data Fetch + Combine
Use case: Fetch payment details and shipping status in parallel, then send a combined status email.
Webhook Trigger (GET /order-status?orderId=...)
├─ Branch A → Razorpay — Fetch Payment
│ paymentId: {{body.paymentId}}
└─ Branch B → Shiprocket — Track Shipment
awbCode: {{body.awb}}
→ Merge (Combine)
→ Gmail — Send Email
to: {{body.email}}
body: "Payment: {{razorpay.status}}
Shipping: {{shiprocket.current_status}}
ETA: {{shiprocket.tracking_data.etd}}"Find Unshipped Orders (Key Difference)
Use case: Find all paid orders that don't have a Shiprocket order yet.
Schedule Trigger (daily 8 AM)
├─ Branch A → Razorpay — List Payments (captured, last 24h)
└─ Branch B → Shiprocket — Get Orders List (last 24h)
→ Merge (Key Difference)
keyPath1: id (Razorpay payment ID)
keyPath2: channel_order_id (Shiprocket's external order ID)
→ Loop over {{merge.result}}
→ Slack — Send Message
channel: #ops
text: "Missing shipment for payment {{item.id}} — {{item.email}}"