All dynamic content in n8n uses double curly braces:
{{expression}}
// ✅ Valid expressions{{$json.email}}{{$json.body.name}}{{$node["HTTP Request"].json.data}}// ❌ Invalid — missing or wrong braces$json.email // treated as literal text{$json.email} // single braces — invalid
Webhook data is NOT at the root of $json.Webhook nodes wrap all incoming data under a .body property. Always access webhook fields as {{$json.body.fieldName}}, never {{$json.fieldName}}.
// Full $json structure from a Webhook node{ "headers": {"content-type": "application/json"}, "params": {}, "query": {}, "body": { // ⚠️ User data is HERE "name": "John", "email": "john@example.com", "message": "Hello" }}
In a Slack node text field after a Webhook:
New form submission!Name: {{$json.body.name}}Email: {{$json.body.email}}Message: {{$json.body.message}}
// Simple nesting{{$json.user.email}}// Array access{{$json.data[0].name}}{{$json.items[0].id}}// Bracket notation for spaces in field names{{$json['field name']}}{{$json['user data']['first name']}}
Do not use {{}} expressions inside Code nodes. Code nodes use direct JavaScript/Python — the {{}} syntax is for expression fields in other node types only.
Code Nodes
Webhook Paths
Credential Fields
// ❌ WRONG in Code nodeconst email = '={{$json.email}}';const name = '{{$json.body.name}}';// ✅ CORRECT in Code nodeconst email = $json.email;const name = $json.body.name;// Or using the $input APIconst email = $input.item.json.email;const allItems = $input.all();
// ❌ WRONG — webhook paths must be staticpath: "{{$json.user_id}}/webhook"// ✅ CORRECT — use static pathspath: "user-webhook"// For dynamic parameters, use URL path params insteadpath: "user-webhook/:userId"
// ❌ WRONG — credentials use n8n's credential systemapiKey: "={{$env.API_KEY}}"// ✅ CORRECT// Configure API keys through the Credentials section, not parameters
// First item{{$json.users[0].email}}// Array length{{$json.users.length}}// Last item{{$json.users[$json.users.length - 1].name}}// Join all emails{{$json.users.map(u => u.email).join(', ')}}
// Dot notation (no spaces){{$json.user.email}}// Bracket notation (spaces or dynamic keys){{$json['user data'].email}}
Symptom: Output shows {{value}} instead of the actual value.
❌ {{{$json.field}}}✅ {{$json.field}}
Array access with dots
Symptom: Syntax error or undefined.
❌ {{$json.items.0.name}}✅ {{$json.items[0].name}}
Using = prefix outside JSON mode
Symptom: Output shows =john@example.com instead of john@example.com.
// In text fields (no = needed)❌ Email: ={{$json.email}}✅ Email: {{$json.email}}// In JSON mode (= IS needed to set whole value to expression){ "email": "={{$json.body.email}}"}
Missing .json in $node reference
Symptom: Undefined value when you know the node has data.