Build N8N Workflows with Claude Code 2026
The Workflow
Generate complete N8N workflow JSON files using Claude Code, eliminating manual node-by-node assembly in the N8N editor. This approach suits developers who want version-controlled, reproducible automation pipelines that can be imported directly into N8N instances.
Expected time: 15-30 minutes per workflow Prerequisites: N8N instance (self-hosted or cloud), Claude Code installed, basic understanding of N8N node types
Setup
1. Create a Project Directory for N8N Workflows
mkdir -p ~/n8n-workflows && cd ~/n8n-workflows
This gives Claude Code a dedicated workspace for generating and managing workflow JSON files.
2. Add a CLAUDE.md with N8N Context
# CLAUDE.md
## Project Context
This directory contains N8N workflow JSON files for export/import.
## Rules
- All workflows must use N8N v1.x JSON schema
- Every node must have a unique name and valid position coordinates
- Credentials must use reference IDs, never inline secrets
- Webhook nodes must specify httpMethod and path
- Error handling: every workflow needs an Error Trigger node
- Position nodes on a grid: x increments of 250, y increments of 150
This ensures Claude generates valid, importable workflow files every time.
3. Verify N8N CLI Access
n8n --version
# Expected output:
# 1.64.0 (or your installed version)
If using N8N cloud, verify API access instead:
curl -s -H "X-N8N-API-KEY: $N8N_API_KEY" \
https://your-instance.app.n8n.cloud/api/v1/workflows | jq '.data | length'
# Expected output: number of existing workflows
Usage Example
Ask Claude Code to generate a webhook-triggered workflow that receives form data, validates it, stores it in a database, and sends a Slack notification:
{
"name": "Form Submission Handler",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "form-submit",
"responseMode": "responseNode",
"options": {}
},
"id": "webhook-1",
"name": "Webhook Receiver",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [250, 300]
},
{
"parameters": {
"conditions": {
"string": [
{
"value1": "={{ $json.body.email }}",
"operation": "isNotEmpty"
},
{
"value1": "={{ $json.body.name }}",
"operation": "isNotEmpty"
}
]
}
},
"id": "if-1",
"name": "Validate Fields",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [500, 300]
},
{
"parameters": {
"operation": "insert",
"table": "submissions",
"columns": "name,email,message,created_at",
"fieldsUi": {
"fieldValues": [
{ "column": "name", "value": "={{ $json.body.name }}" },
{ "column": "email", "value": "={{ $json.body.email }}" },
{ "column": "message", "value": "={{ $json.body.message }}" },
{ "column": "created_at", "value": "={{ $now.toISO() }}" }
]
}
},
"id": "postgres-1",
"name": "Store in Database",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.4,
"position": [750, 200],
"credentials": {
"postgres": { "id": "1", "name": "Production DB" }
}
},
{
"parameters": {
"channel": "#form-submissions",
"text": "New submission from {{ $json.body.name }} ({{ $json.body.email }})",
"otherOptions": {}
},
"id": "slack-1",
"name": "Notify Slack",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.2,
"position": [1000, 200],
"credentials": {
"slackApi": { "id": "2", "name": "Workspace Bot" }
}
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify({ success: false, error: 'Missing required fields' }) }}"
},
"id": "respond-error",
"name": "Error Response",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [750, 450]
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify({ success: true }) }}"
},
"id": "respond-ok",
"name": "Success Response",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [1250, 200]
}
],
"connections": {
"Webhook Receiver": {
"main": [[{ "node": "Validate Fields", "type": "main", "index": 0 }]]
},
"Validate Fields": {
"main": [
[{ "node": "Store in Database", "type": "main", "index": 0 }],
[{ "node": "Error Response", "type": "main", "index": 0 }]
]
},
"Store in Database": {
"main": [[{ "node": "Notify Slack", "type": "main", "index": 0 }]]
},
"Notify Slack": {
"main": [[{ "node": "Success Response", "type": "main", "index": 0 }]]
}
},
"settings": {
"executionOrder": "v1"
}
}
Import the generated workflow:
# Import via CLI
n8n import:workflow --input=form-submission-handler.json
# Or via API
curl -X POST "https://your-instance.app.n8n.cloud/api/v1/workflows" \
-H "X-N8N-API-KEY: $N8N_API_KEY" \
-H "Content-Type: application/json" \
-d @form-submission-handler.json
Common Issues
- Import fails with “Invalid node type”: Check that the node
typefield matches exactly what your N8N version supports. Runn8n nodes:listto see available node types. - Webhook not triggering: Ensure
httpMethodis uppercase (POST, not post) and the workflow is activated after import. Test withcurl -X POST http://localhost:5678/webhook/form-submit -d '{"name":"test","email":"[email protected]"}'. - Credential reference errors: N8N requires credentials to exist before workflow activation. Create credentials first, note their IDs, and update the JSON accordingly.
Why This Matters
Version-controlled N8N workflows enable reproducible automation across environments. Generating workflow JSON with Claude Code reduces a 30-minute drag-and-drop session to a 2-minute prompt.