n8n Set Node:
how to map, rename, and fix data fast.
Most beginner n8n workflows look like a game of telephone where nobody agreed on field names. A webhook sends email_address, the Sheets node expects Email, the Slack node gets the raw payload instead of the message, and then everything breaks in a slightly different way each time. The Set node is how you fix all of that before it propagates downstream.
I use the Set node constantly. Not because it's exciting. Because real workflows are full of ugly data and downstream nodes are picky little divas. The Set node is where I make both sides behave.
What the Set node actually does (it's the janitor of your workflow)
The n8n Set node lets you create fields, rename fields, map values from one key to another, hardcode values, and strip out junk you don't want to carry forward. That's it. It is a data-shaping node. Not logic. Not looping. Not magic. Just data cleanup and prep.
If a webhook gives you first_name but the next node expects name, Set fixes it. If Stripe sends a giant nested payload and you only need four fields, Set can flatten the parts you care about. If you want to add a field like source = "website" or status = "new lead", Set does that too.
This is why the Set node shows up all over real workflows. APIs rarely agree on field names. Form tools love sending extra garbage. AI outputs are useful but inconsistent. The next node in line usually wants cleaner inputs than the last node gave you. So you put a Set node in the middle and stop pretending raw payloads are fine.
If your workflow would be easier to read after giving the data better names, fewer fields, or a couple fixed values, you probably want a Set node.
When to use Set vs Code vs Edit Fields
Most people overcomplicate this way too early. If all you need is straightforward field mapping, use Set. Don't jump straight to a Code node because writing JavaScript makes you feel powerful. Half the time that's just adding maintenance debt for no reason.
Use Set when:
- you want to rename fields
- you want to create a few new fields
- you want to map values with expressions like
{{ $json.name }} - you want to hardcode flags, labels, or status values
- you want to keep only a clean subset of fields
Use a Code node when:
- you need real transformation logic
- you need loops, conditionals, parsing, or array reshaping
- you need to do something annoying enough that a visual field editor becomes a punishment
As for Edit Fields: depending on your n8n version, Set may appear as Edit Fields in the UI or at least overlap with it heavily. Same basic job: shape the data. If you're looking at a tutorial and the naming doesn't match your screen, that's probably why. n8n likes renaming shit just enough to make beginners doubt themselves.
Stay visual as long as the workflow stays readable. Once the field logic turns into a weird little maze, move to Code. The Set node is for clean, obvious transformations you want to understand at a glance six weeks later.
The four jobs the Set node does most often
1. Rename fields so the next node stops complaining
This is the big one. You get data from one service with annoying field names, and another service expects nicer ones. Example: a webhook sends first_name, last_name, and phone_number. Your CRM node wants name and phone.
name = {{ $json.first_name }} {{ $json.last_name }}
phone = {{ $json.phone_number }}
email = {{ $json.email }}
That's a perfectly normal Set node. Nothing fancy. But it makes the next node cleaner because now every downstream step can reference {{ $json.name }} instead of reconstructing the full name over and over.
2. Hardcode values you want on every item
Sometimes you just need to tag data with context. Maybe every lead from a certain form should carry source = "homepage quiz". Maybe every record entering an Airtable table should start with status = "new". Maybe you want a fixed label like pipeline = "starter-pack".
source = "website"
status = "new lead"
pipeline = "n8n-starter-pack"
This matters more than people think. Hardcoded fields are how you keep attribution sane across automations. If you skip this, six weeks later you're staring at a spreadsheet wondering where half your leads came from.
3. Clean or flatten ugly payloads
Webhook payloads love nesting. APIs do it too. You'll get something like $json.body.customer.name or $json.data.object.customer_details.email. That might be technically correct, but it sucks to work with across ten more nodes.
The Set node is where you flatten it into human-readable fields.
customer_name = {{ $json.body.customer.name }}
customer_email = {{ $json.body.customer.email }}
order_total = {{ $json.body.order.total }}
order_id = {{ $json.body.order.id }}
Now the rest of the workflow can reference short, obvious keys. Better debugging. Better readability. Less swearing later.
4. Keep only the fields that matter
One of the most useful Set node settings is the ability to keep only the fields you define. This is how you stop dragging 200 irrelevant fields through the rest of the workflow like dead weight.
If a webhook sends a full payload but the next API call only needs name, email, plan, and source, keep those four and drop the rest. Cleaner execution data. Easier debugging. Less chance of accidentally referencing stale junk later.
Depending on n8n version, this shows up as something like Keep Only Set or similar behavior under field editing options. Turn it on intentionally. If you forget, your new fields get added but the giant original payload stays attached.
Practical workflow pattern: clean webhook data before sending to an API
This is the Set node pattern I use constantly: Webhook → Set → IF / HTTP Request / CRM node.
Let's say a lead form posts this payload:
{
"full_name": "Jamie Carter",
"email_address": "jamie@example.com",
"business_name": "Carter Studio",
"project_type": "automation",
"budget_range": "$1k-$3k",
"submitted_at": "2026-03-22T19:14:08Z",
"tracking": {
"utm_source": "twitter",
"utm_campaign": "spring-launch"
}
}
Your CRM or Airtable step probably doesn't want that exact shape. So the Set node turns it into something cleaner:
name = {{ $json.full_name }}
email = {{ $json.email_address }}
company = {{ $json.business_name }}
service = {{ $json.project_type }}
budget = {{ $json.budget_range }}
lead_source = {{ $json.tracking.utm_source }}
campaign = {{ $json.tracking.utm_campaign }}
status = "new"
received_at = {{ $json.submitted_at }}
After that, the workflow is way easier to reason about. The IF node can check {{ $json.service }}. The CRM node can map directly from name, email, and company. The Telegram alert can read like a normal human sentence instead of a forensic reconstruction of the original webhook.
This is also where you fix data before sending it to touchy APIs. Maybe the next service needs phone with no spaces. Maybe it needs a lowercase email. Maybe it expects a literal string like lead_status = "open". Do that cleanup here instead of scattering it across four downstream nodes like a maniac.
Real n8n Set node expressions and examples
The Set node gets most of its usefulness from expressions. You're not typing static values most of the time. You're pulling from previous node output and shaping it into something more useful.
Copy a field directly
{{ $json.name }}
Build a full name from separate fields
{{ $json.first_name }} {{ $json.last_name }}
Pull a nested value
{{ $json.customer.billing.email }}
Set a fallback if a field might be missing
{{ $json.company || "Unknown company" }}
Normalize text a little before the next node
{{ $json.email.toLowerCase() }}
That last one is where the Set node starts pushing right up against Code node territory. A little inline cleanup is fine. Small string transforms, default values, direct mapping — great. Once you're writing mini-programs inside expressions, stop and ask whether a Code node would actually be clearer.
Mistakes people keep making with the n8n Set node
Using Set for logic it was never meant to handle
The Set node is not your all-purpose thinking node. If your expression starts looking like a tax form and a JavaScript exam had a baby, move the logic out. Set should make the data cleaner, not more cryptic.
Forgetting to drop unused fields
People add three nice clean fields in Set and then unknowingly keep the original 80-field payload attached. Later they reference the wrong field because both versions still exist. If the original payload is no longer useful, strip it down and move on.
Renaming fields too late
If every node after your webhook is using ugly raw names, you've waited too long. Rename early. Your future self is the one who has to debug this workflow while tired and annoyed.
Overwriting something important by accident
If you create a new field with the same name as an existing one, you're replacing it. Sometimes that's what you want. Sometimes it's how you quietly nuke useful data. Be deliberate.
Use one Set node near the top of a workflow to make incoming data sane. Then the rest of the workflow gets to speak in clean field names instead of whatever nonsense the source system invented.
Pairing the Set node with IF, HTTP Request, and AI nodes
The Set node gets more useful when you treat it as the prep step for something else, not as an endpoint in itself. Here's how it actually pairs in practice:
Set → IF node
IF nodes get cleaner and less error-prone when the field they're checking has a predictable, normalized name. Don't build your IF branch off $json.data.object.customer_details.email_address. Run a Set node first, map it to email, then let the IF node check {{ $json.email }}. Six weeks from now when you're debugging at 11pm, you'll appreciate the extra thirty seconds you spent doing this up front.
Set → HTTP Request node
HTTP Request nodes are picky about field names because you're sending them to an actual API that has its own expectations. A Set node before an HTTP Request is how you make sure the payload you're building matches what the API actually wants without having to configure weird mappings inside the request node itself.
Set → AI agent or AI nodes
This one trips people up a lot. AI nodes in n8n expect clean, specific inputs for their prompts. If you're dropping a raw webhook payload into a prompt template, you're asking the AI to reason about garbage. Run a Set node first: extract the fields that matter, discard the noise, give the AI prompt a clean few variables to work with. You'll get better outputs and you'll stop wondering why the AI keeps referencing weird technical field names in its responses.
Why this node matters more than it looks
The Set node is not sexy. Nobody brags about it. But it's one of the nodes that makes the difference between a workflow that's easy to maintain and one that's a brittle pile of mystery fields and regret. Good automation is mostly clean handoffs. The Set node is how you create those handoffs.
And once you start noticing it, you'll see it everywhere: before IF nodes, before CRM writes, before API calls, before AI prompts, before alerts. It's the little translation layer that keeps the rest of the workflow from having to care where the data originally came from.
Every workflow that runs reliably has a Set node (or three) doing quiet cleanup work between the noisy parts. That's not a coincidence. If you want to see what that looks like in working automations, not toy examples, the Starter Pack is 14 production workflows with the field mapping and handoffs already built in.
See the Set node used inside real workflows
My n8n Automation Starter Pack gives you 14 workflow files pulled from a live business stack, with the field mapping, cleanup, routing, and handoff logic already built in. It's $97 one-time, instant download, with a 30-day money-back guarantee.
See Code Intelligence MCP →One-time $97 · Instant download · 30-day money-back guarantee