name: n8n-workflow description: Create, modify, and understand n8n automation workflows. Use when building n8n workflow JSON files, configuring nodes (HTTP Request, Code, IF, Merge, Webhook, Schedule), writing expressions with {{ $json }}, or implementing flow logic (conditionals, loops, error handling). Triggers for requests involving n8n, workflow automation, or node-based pipeline creation.
n8n Workflow Creator
This skill provides guidance for creating valid n8n workflow JSON files.
๐จ Critical: Webhook Data Structure
Most common mistake: Webhook data is nested under .body, NOT at root!
// โ WRONG - Returns undefined
{{ $json.email }}
// โ
CORRECT - Webhook data is under .body
{{ $json.body.email }}
This applies to expressions AND Code nodes.
Workflow Structure
{
"name": "Workflow Name",
"nodes": [...],
"connections": {...},
"active": false,
"settings": { "executionOrder": "v1" }
}
The 5 Core Patterns
- Webhook Processing - Webhook โ Validate โ Transform โ Respond
- HTTP API Integration - Trigger โ HTTP Request โ Transform โ Action
- Database Operations - Schedule โ Query โ Transform โ Write โ Verify
- AI Agent Workflow - Trigger โ AI Agent (Model + Tools) โ Output
- Scheduled Tasks - Schedule โ Fetch โ Process โ Deliver โ Log
See patterns.md for complete examples.
Essential Nodes
| Node | Type | Use Case |
|---|---|---|
| Manual Trigger | n8n-nodes-base.manualTrigger |
Test execution |
| Schedule | n8n-nodes-base.scheduleTrigger |
Cron-based runs |
| Webhook | n8n-nodes-base.webhook |
HTTP endpoints |
| HTTP Request | n8n-nodes-base.httpRequest |
API calls |
| Code | n8n-nodes-base.code |
JavaScript/Python |
| Set | n8n-nodes-base.set |
Modify/create fields |
| IF | n8n-nodes-base.if |
Conditional branching |
| Merge | n8n-nodes-base.merge |
Combine branches |
| Loop Over Items | n8n-nodes-base.splitInBatches |
Batch processing |
See nodes.md for full configurations.
Expression Syntax
Expressions use {{ }} syntax:
{{ $json.fieldName }} // Current item
{{ $json.body.email }} // Webhook data (under .body!)
{{ $('NodeName').item.json.field }} // Other node's output
{{ $now }} // Current timestamp
โ Don't use {{ }} in:
- Code nodes (use JavaScript directly)
- Webhook paths
- Credential fields
See expressions.md for advanced patterns.
Code Node - Critical Rules
ALWAYS return array with json property:
// โ
CORRECT
const items = $input.all();
return items.map(item => ({ json: { ...item.json, processed: true } }));
// โ
CORRECT - Single item
return [{ json: { result: 'success' } }];
// โ WRONG - No return
const data = $input.first();
// forgot return!
// โ WRONG - Object instead of array
return { json: { result: 'success' } };
Best practices:
- Validate input:
if (!items || items.length === 0) return []; - Use null checks:
item.json?.user?.email || 'default' - Try-catch for API calls
- Filter early, process late
Common Gotchas
| Problem | Solution |
|---|---|
| Can't access webhook data | Use $json.body.field, not $json.field |
| Expression shows as text | Wrap in {{ }} |
| Unexpected node order | Check Settings โ Execution Order (use v1) |
| Code node returns nothing | Add return statement |
| API returns 401/403 | Use Credentials section, not parameters |
Connections Format
"connections": {
"Source Node": {
"main": [[{ "node": "Target Node", "type": "main", "index": 0 }]]
}
}
IF node outputs: index: 0 = True, index: 1 = False
Best Practices
โ Do:
- Use descriptive node names ("Fetch Users", not "HTTP Request 1")
- Set
onError: "continueRegularOutput"for resilience - Test incrementally, node by node
- Document complex workflows with notes
- Handle empty data cases
โ Don't:
- Build workflows in one shot (iterate!)
- Skip error handling
- Hardcode credentials in parameters
- Use Code node when built-in nodes suffice
- Deploy without testing
Reference Documentation
- nodes.md - Node configurations
- expressions.md - Expression syntax
- patterns.md - Workflow patterns
- json-structure.md - JSON schema