Introduction
This is the capstone lesson of the course. You have learned how to use the Code node, the Set node, the IF node, the Merge node, and how to shape data with expressions. Now you will wire all of those pieces together into a single workflow that does something real: pull data from two sources, clean and filter it, transform it into a target shape, merge the streams, and produce a final output ready for downstream use.
The scenario used throughout this lesson is practical and representative of what you will encounter in production: you have an orders list from one HTTP endpoint and a customers list from another. The goal is to produce an enriched order report that contains only paid orders, attaches the customer name and email, and formats dates for display.
Fetching Data from Two Sources in Parallel
Start with two HTTP Request nodes running in parallel. Both are triggered by the same Manual Trigger or Schedule Trigger node. The first fetches orders, the second fetches customers. In n8n, you split execution by connecting one trigger to both HTTP Request nodes.
For the orders endpoint, set the URL and make sure the response format is JSON. The raw response typically looks like this:
For the customers endpoint:
Both nodes output arrays of items. n8n automatically splits arrays into individual items, so each order and each customer becomes its own item flowing through the rest of the workflow.
Filtering and Transforming Each Stream
Before merging, clean each stream independently. This keeps logic isolated and easier to debug.
For orders, connect an IF node after the orders HTTP Request. Set the condition to check that the field status equals the string paid. Only the true branch continues. This eliminates pending, cancelled, or refunded orders before they ever reach the merge.
Next, connect a Code node after the IF true output to reshape the order item and format the date:
For customers, connect a Set node after the customers HTTP Request. Use it to explicitly keep only the fields you need and rename them for clarity. Set customer_key to the expression referencing the id field, keep name and email. This trims noise and makes the merge key unambiguous.
Merging the Two Streams
Connect both transformed streams into a Merge node. Use the Merge by Key mode. Set the key for input 1 (orders) to customer_id and the key for input 2 (customers) to customer_key. n8n will match each order to its customer record and output a combined item containing fields from both.
The merged item at this point contains order_id, customer_id, amount, order_date, customer_key, name, and email all at the top level of item.json. There may be redundant fields like customer_key which you added only for the join. Clean those up in the next step.
Final Shaping and Output
Add one more Code node after the Merge node. This is the final transformation step where you produce the exact output contract you promised to downstream consumers:
This node strips internal join keys, renames amount to amount_usd for explicitness, and produces a clean array of enriched order records. Connect this to whatever final node you need: an HTTP Request to POST results to a webhook, a Google Sheets node to append rows, or simply leave it as the terminal node during development and inspect the output in the n8n editor.
Summary
You have built a workflow that covers the full transformation lifecycle: parallel ingestion from two HTTP sources, independent filtering with IF, per-stream reshaping with Code and Set nodes, a key-based merge, and a final cleanup pass. Each node has a single clear responsibility, which makes the workflow readable and debuggable. When something breaks in production, you can pin data at any node and re-run from that point without touching upstream nodes. That composable structure, not any individual node, is the core skill this course has been building toward.
Lesson Checkpoint
Review what you learned and get feedback on your work.