通过 n8n REST API 设计、创建、修改和管理工作流。无需 MCP,纯 REST API 调用即可完全操控 n8n。
以下规则经过真实 n8n 2.x 实例验证,违反任一条都会导致 API 报错。
active 是只读字段 — 创建/更新时不传 activetags / staticData 是只读字段 — 创建时不传shared / activeVersion / pinData 是只读字段 — PUT 更新时不传POST /api/v1/workflows/{id}/activate(body: {})name/ nodes/ connections/ settings,否则 must NOT have additional propertiesPATCH method not allowedresponseMode: "lastNode" 时,最后一个节点返回值自动作为 HTTP 响应, 不要加 respondToWebhook 节点当用户请求以下操作时,自动激活此 Skill:
text
N8N_BASE_URL=http://localhost:5678
N8N_API_KEY=<your-api-key>
获取 API Key:n8n 界面 → Settings → API → Create an API Key
所有 API 请求必须携带:
text
X-N8N-API-KEY: <N8N_API_KEY>
Content-Type: application/json
bash
curl -s -o /dev/null -w "%{http_code}" -H "X-N8N-API-KEY: $N8N_API_KEY" "$N8N_BASE_URL/api/v1/workflows"
200 → 正常 | 401 → Key 无效 | 000 → 网络不通Agent 必须严格遵循以下 4 阶段:
text
Step 1: 创建空骨架 → 获取 workflow_id
Step 2: 逐个添加节点(每次 1-3 个)
Step 3: 建立节点连接
Step 4: GET 验证完整工作流
Step 5: 激活(用户确认后)
text
{N8N_BASE_URL}/api/v1
操作方法端点列表GET``/workflows?active=true&limit=50详情GET``/workflows/{id}创建POST``/workflows更新PUT``/workflows/{id}(全量替换)删除DELETE``/workflows/{id}激活POST``/workflows/{id}/activate停用POST``/workflows/{id}/deactivate执行POST``/workflows/{id}/execute
操作方法端点列表GET``/credentials创建POST``/credentials
操作方法端点列表GET``/executions?workflowId={id}&status=error&limit=20详情GET``/executions/{id}重试POST``/executions/{id}/retry
bash
# 列出所有工作流
curl -s -H "X-N8N-API-KEY: $N8N_API_KEY" "$N8N_BASE_URL/api/v1/workflows?limit=50"
# 获取单个工作流
curl -s -H "X-N8N-API-KEY: $N8N_API_KEY" "$N8N_BASE_URL/api/v1/workflows/123"
# 激活
curl.exe -s -X POST -H "X-N8N-API-KEY: $N8N_API_KEY" -H "Content-Type: application/json" -d "{}" "$N8N_BASE_URL/api/v1/workflows/123/activate"
# 停用
curl.exe -s -X POST -H "X-N8N-API-KEY: $N8N_API_KEY" "$N8N_BASE_URL/api/v1/workflows/123/deactivate"
# 删除
curl -s -X DELETE -H "X-N8N-API-KEY: $N8N_API_KEY" "$N8N_BASE_URL/api/v1/workflows/123"
# 手动执行
curl -s -X POST -H "X-N8N-API-KEY: $N8N_API_KEY" -H "Content-Type: application/json" -d '{"data": {"key": "value"}}' "$N8N_BASE_URL/api/v1/workflows/123/execute"
Windows 注意: PowerShell 的
curl是Invoke-WebRequest别名,用curl.exe调用真正的 curl。
json
{
"parameters": {},
"id": "unique-uuid",
"name": "Node Display Name",
"type": "n8n-nodes-base.xxx",
"typeVersion": 1,
"position": [250, 300],
"credentials": {},
"disabled": false
}
关键规则:
type 始终用完整格式 n8n-nodes-base.xxxid 用 UUID v4name 既是显示名称,也是 connections 中引用的 keyjson
{
"SourceNodeName": {
"main": [
[
{ "node": "TargetNodeName", "type": "main", "index": 0 }
]
]
}
}
三层嵌套:
text
{源节点} → {输出类型} → [[{目标列表}]]
常见模式:
线性(A→B→C):
json
{"A":{"main":[[{"node":"B","type":"main","index":0}]]}},
{"B":{"main":[[{"node":"C","type":"main","index":0}]]}}
分支(IF→true/false):
json
{"IF":{"main":[[{"node":"True","type":"main","index":0}],[{"node":"False","type":"main","index":0}]]}}
并行(A→B+C→D):
json
{"A":{"main":[[{"node":"B","type":"main","index":0},{"node":"C","type":"main","index":0}]]}}
在 parameters 中使用 ={{ }} 嵌入动态值。
变量用途示例$json当前节点输入{{ $json.email }}``$json.bodyWebhook 请求体{{ $json.body.data }}``$json.queryURL 查询参数{{ $json.query.page }}``$node["Name"].json引用指定节点输出{{ $node["HTTP"].json.data }}``$now当前时间{{ $now.toISO() }}``$env环境变量{{ $env.MY_VAR }}``$input.first()第一个输入项{{ $input.first().json.name }}
Webhook 陷阱: POST 请求体在 $json.body 下,不是直接在 $json 下。
发送 JSON body 的正确配置:
json
{
"parameters": {
"sendBody": true,
"specifyBody": "json",
"jsonParameters": false,
"jsonBody": "={{ JSON.stringify({key: 'value'}) }}"
}
}
关键: jsonParameters: false 是必须的!设为 true 直接崩溃。
参数值说明sendBody``true启用请求体specifyBody``"json"JSON 格式jsonParameters**false**必须为 falsejsonBody``"={{ ... }}"用表达式传递
当需要 OpenClaw 定时自动触发 n8n 工作流时:
方法:直接编辑 jobs.json 文件
text
路径:C:\Users\lujun\.openclaw\cron\jobs.json
在 jobs.json 中添加 cron 任务,通过 curl.exe POST 触发 n8n webhook URL。
关键经验:
通过 n8n 调用微信公众号草稿 API 时的限制:
限制项字节数中文数说明title≤ 20字节≤ 10个超过报 45003digest≤ 54字节≤ 25个超过报 45004thumb_media_id不能为空—先上传封面获取
access_token 有效期 7200 秒,每次发草稿前重新获取,不缓存复用。
json
{
"settings": {
"executionOrder": "v1",
"errorWorkflow": "error-handler-workflow-id"
}
}
json
{
"name": "HTTP Request",
"continueOnFail": true
}
json
{
"type": "n8n-nodes-base.errorTrigger",
"typeVersion": 1
}
n8n-nodes-base.function(v1,已弃用),用 n8n-nodes-base.code(v2)json
{
"name": "Webhook Echo",
"nodes": [
{
"id": "a1",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [0, 0],
"parameters": {
"httpMethod": "POST",
"path": "echo",
"responseMode": "lastNode",
"responseData": "lastNode",
"options": {}
}
},
{
"id": "a2",
"name": "Process & Respond",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [250, 0],
"parameters": {
"jsCode": "return [{ json: { received: $json.body, processed: true, time: new Date().toISOString() } }];"
}
}
],
"connections": {
"Webhook": { "main": [[{ "node": "Process & Respond", "type": "main", "index": 0 }]] }
},
"settings": { "saveManualExecutions": true, "executionOrder": "v1" }
}
激活 + 测试:
bash
# 创建(自动获取 id)
# 激活(等 1-2 秒)
curl.exe -s -X POST -H "X-N8N-API-KEY: %N8N_API_KEY%" -H "Content-Type: application/json" -d "{}" "%N8N_BASE_URL%/api/v1/workflows/{id}/activate"
# 触发
curl.exe -s -X POST -H "Content-Type: application/json" -d "{\"hello\":\"world\"}" "%N8N_BASE_URL%/webhook/echo"
问题原因解决401API Key 无效重新生成400 active is read-only传了 active不传,用 POST /activate400 tags is read-only传了 tags不传400 must NOT have additional propertiesPUT 传了额外字段只传 name/nodes/connections/settings405 PATCH method not allowedn8n 2.x 不支持用 PUT 全量替换500 Unused Respond to Webhook nodelastNode 模式下用了 respondToWebhook删掉,用 Code 节点返回Webhook 404激活后立即触发等 1-2 秒Wait 节点导致激活失败Wait for Callback 配置问题用 Code + setTimeout 替代HTTP Request 崩溃jsonParameters: true改为 false微信 45003title 超字节title[:10]微信 45004digest 超字节digest[:25]微信草稿无封面thumb_media_id 为空先上传获取 media_idWebhook 路径 404用了 path 参数而非 webhookId用 webhookId 触发
fs 模块被屏蔽导致文件写入失败#解决: 用 ReadWriteFile 节点 + Binary 数据,详见 desktop-write.md
解决: 用 Code 节点 + await new Promise(r => setTimeout(r, 5000)) 替代
解决: 必须设为 false, true 直接崩溃
解决: title[:10] / digest[:25],每次发草稿前重新获取 token
解决: PUT 全量替换,必须包含全部节点
解决: n8n 2.x 用 {webhookId} 触发,不是 path 参数
解决: 停下来搜索文档/社区,分析根因,针对性解决
同一问题试错超过 3 次 → 必须停止:
bash
ACTIVE=$(curl -s -H "X-N8N-API-KEY: $N8N_API_KEY" "$N8N_BASE_URL/api/v1/workflows?active=true" | jq ".data | length")
FAILED=$(curl -s -H "X-N8N-API-KEY: $N8N_API_KEY" "$N8N_BASE_URL/api/v1/executions?status=error&limit=100" | jq "[.data[] | select(.startedAt > (now - 86400 | todate))] | length")
echo "Active: $ACTIVE | Failed(24h): $FAILED"
bash
python3 scripts/n8n_api.py list-workflows --active true --pretty
python3 scripts/n8n_api.py list-executions --limit 10 --pretty
python3 scripts/n8n_optimizer.py analyze --id <id> --pretty
python3 scripts/n8n_tester.py validate --id <id> --pretty