n8n-workflow-api-authoringlisted
Install: claude install-skill jackson2w/claude-code-skills
# n8n workflow authoring via REST API
Building an n8n workflow as a JSON file (agent-authored, or scripted) and importing it via
`POST /api/v1/workflows`, instead of hand-clicking every node in the editor. This is a reasonable
middle ground for config-as-code: workflow *logic* (nodes/connections) is versioned and
diffable; *credentials* are still created by hand in the editor so secret values never transit a
file or an agent's context (see the credentials section below). All of the gotchas here were
found the hard way building a real multi-node pipeline (Webhook → external API → GitHub Contents
API with retry logic) and getting it working end-to-end, not from documentation.
## The workflow JSON shape
```json
{
"name": "my-workflow",
"nodes": [ {"parameters": {...}, "name": "...", "type": "n8n-nodes-base.X", "typeVersion": N, "position": [x,y], "id": "...", "credentials": {...}} ],
"connections": { "Node A": { "main": [[ {"node": "Node B", "type": "main", "index": 0} ]] } },
"settings": { "executionOrder": "v1" }
}
```
Do **not** include `active` or `id` at the top level when creating — see "Import/update API
quirks" below.
## Expression fields (`={{ ... }}`) are not full JavaScript — build complex bodies in a Code node instead
An HTTP Request node's JSON Body (or any `={{ }}` field) looks like it accepts arbitrary JS, but
n8n's expression evaluator does **not** reliably support multi-statement code — an IIFE like:
```
={{ (() => { const x = ...; return JSON.str