docs(phase-6): research n8n API access
Phase 6: n8n API Access - n8n REST API capabilities identified - Authentication patterns documented (X-N8N-API-KEY header) - Workflow CRUD operations researched - Execution history access patterns found - Common pitfalls catalogued (activation timeout, public vs private endpoints) - No official SDK exists - raw HTTP client required Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,413 @@
|
|||||||
|
# Phase 6: n8n API Access - Research
|
||||||
|
|
||||||
|
**Researched:** 2026-02-03
|
||||||
|
**Domain:** n8n REST API integration, workflow automation API
|
||||||
|
**Confidence:** MEDIUM
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
n8n provides a public REST API that allows programmatic access to workflows, executions, and credentials. The API is available on self-hosted instances (including Docker deployments) and requires API key authentication via the X-N8N-API-KEY header.
|
||||||
|
|
||||||
|
**Primary recommendation:** Use n8n's native REST API with a simple HTTP client (axios or node-fetch) to read workflow JSON, update workflows, and query execution history. No SDK exists, but the API is straightforward RESTful JSON. Create API key through UI (Settings > n8n API), store securely, and use for all Claude Code operations.
|
||||||
|
|
||||||
|
**Key finding:** There is NO official n8n API client library/SDK. All API interactions will be raw HTTP requests (curl, axios, fetch). The API documentation exists but is not comprehensive - expect to discover endpoints through community examples and experimentation.
|
||||||
|
|
||||||
|
## Standard Stack
|
||||||
|
|
||||||
|
The established libraries/tools for n8n API integration:
|
||||||
|
|
||||||
|
### Core
|
||||||
|
| Library | Version | Purpose | Why Standard |
|
||||||
|
|---------|---------|---------|--------------|
|
||||||
|
| n8n REST API | Native | Workflow CRUD, execution history | Built-in to all n8n instances |
|
||||||
|
| axios | ^1.6.0 | HTTP client for API calls | Most common in Node.js ecosystem, better error handling than fetch |
|
||||||
|
| node-fetch | ^3.3.0 | Alternative HTTP client | Native fetch API, simpler than axios |
|
||||||
|
|
||||||
|
### Supporting
|
||||||
|
| Library | Version | Purpose | When to Use |
|
||||||
|
|---------|---------|---------|-------------|
|
||||||
|
| dotenv | ^16.0.0 | Environment variable management | Store API key and n8n host URL |
|
||||||
|
| @types/node | ^20.0.0 | TypeScript types for Node.js | If writing TypeScript helper scripts |
|
||||||
|
|
||||||
|
### Alternatives Considered
|
||||||
|
| Instead of | Could Use | Tradeoff |
|
||||||
|
|------------|-----------|----------|
|
||||||
|
| REST API | n8n MCP server | MCP is overkill for v1.1 (marked out of scope in REQUIREMENTS.md) |
|
||||||
|
| axios | curl via bash | Less maintainable, harder error handling, but requires no dependencies |
|
||||||
|
| API key auth | OAuth | n8n doesn't support OAuth for its own API, only for external integrations |
|
||||||
|
|
||||||
|
**Installation:**
|
||||||
|
```bash
|
||||||
|
# For helper scripts (if needed)
|
||||||
|
npm install axios dotenv
|
||||||
|
|
||||||
|
# Or for native fetch approach (Node.js 18+)
|
||||||
|
npm install node-fetch
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** For Claude Code workflow iterations, curl is sufficient and requires no installation.
|
||||||
|
|
||||||
|
## Architecture Patterns
|
||||||
|
|
||||||
|
### Recommended Project Structure
|
||||||
|
```
|
||||||
|
scripts/
|
||||||
|
├── n8n-api/
|
||||||
|
│ ├── config.js # API key, host URL configuration
|
||||||
|
│ ├── client.js # Reusable HTTP client wrapper
|
||||||
|
│ ├── workflows.js # Workflow CRUD operations
|
||||||
|
│ └── executions.js # Execution history queries
|
||||||
|
.env # API credentials (gitignored)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pattern 1: API Key Authentication
|
||||||
|
**What:** Pass API key in X-N8N-API-KEY header for all requests
|
||||||
|
**When to use:** Every n8n API call
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
# Source: Community examples + official docs
|
||||||
|
curl -X GET 'http://localhost:5678/api/v1/workflows' \
|
||||||
|
-H 'accept: application/json' \
|
||||||
|
-H 'X-N8N-API-KEY: your-api-key-here'
|
||||||
|
```
|
||||||
|
|
||||||
|
**TypeScript/JavaScript:**
|
||||||
|
```javascript
|
||||||
|
// Source: Community patterns
|
||||||
|
const axios = require('axios');
|
||||||
|
|
||||||
|
const n8nClient = axios.create({
|
||||||
|
baseURL: process.env.N8N_HOST || 'http://localhost:5678',
|
||||||
|
headers: {
|
||||||
|
'X-N8N-API-KEY': process.env.N8N_API_KEY,
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get all workflows
|
||||||
|
const workflows = await n8nClient.get('/api/v1/workflows');
|
||||||
|
|
||||||
|
// Get specific workflow
|
||||||
|
const workflow = await n8nClient.get(`/api/v1/workflows/${workflowId}`);
|
||||||
|
|
||||||
|
// Update workflow
|
||||||
|
const updated = await n8nClient.patch(`/api/v1/workflows/${workflowId}`, {
|
||||||
|
nodes: [...],
|
||||||
|
connections: {...}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pattern 2: Workflow Read-Modify-Write
|
||||||
|
**What:** Fetch current workflow JSON, modify locally, push back via API
|
||||||
|
**When to use:** Making incremental changes to existing workflows
|
||||||
|
**Example:**
|
||||||
|
```javascript
|
||||||
|
// Source: Community workflow manager patterns
|
||||||
|
async function updateWorkflowNode(workflowId, nodeName, newParams) {
|
||||||
|
// 1. Fetch current workflow
|
||||||
|
const { data: workflow } = await n8nClient.get(`/api/v1/workflows/${workflowId}`);
|
||||||
|
|
||||||
|
// 2. Find and modify node
|
||||||
|
const node = workflow.nodes.find(n => n.name === nodeName);
|
||||||
|
if (node) {
|
||||||
|
node.parameters = { ...node.parameters, ...newParams };
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Push updated workflow
|
||||||
|
const { data: updated } = await n8nClient.patch(`/api/v1/workflows/${workflowId}`, {
|
||||||
|
nodes: workflow.nodes,
|
||||||
|
connections: workflow.connections,
|
||||||
|
settings: workflow.settings
|
||||||
|
});
|
||||||
|
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pattern 3: Execution History Query
|
||||||
|
**What:** Query recent executions to verify workflow behavior
|
||||||
|
**When to use:** Testing after workflow updates, debugging failures
|
||||||
|
**Example:**
|
||||||
|
```javascript
|
||||||
|
// Source: Community patterns for execution monitoring
|
||||||
|
async function getRecentExecutions(workflowId, limit = 10) {
|
||||||
|
const { data } = await n8nClient.get('/api/v1/executions', {
|
||||||
|
params: {
|
||||||
|
workflowId: workflowId,
|
||||||
|
limit: limit,
|
||||||
|
// Filter by status if needed: status=success, status=error
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data.data.map(exec => ({
|
||||||
|
id: exec.id,
|
||||||
|
status: exec.finished ? 'success' : exec.stoppedAt ? 'error' : 'running',
|
||||||
|
startedAt: exec.startedAt,
|
||||||
|
stoppedAt: exec.stoppedAt,
|
||||||
|
error: exec.data?.resultData?.error
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Anti-Patterns to Avoid
|
||||||
|
- **Direct workflow.json file editing:** Changes won't take effect until n8n restarts; use API instead
|
||||||
|
- **Storing API key in workflow:** Use environment variables or secure credential store
|
||||||
|
- **Polling for execution completion:** n8n executions can be long-running; better to check status on-demand
|
||||||
|
- **Activating workflows via API during updates:** Known timeout issues; update workflow while inactive, activate manually via UI
|
||||||
|
|
||||||
|
## Don't Hand-Roll
|
||||||
|
|
||||||
|
Problems that look simple but have existing solutions:
|
||||||
|
|
||||||
|
| Problem | Don't Build | Use Instead | Why |
|
||||||
|
|---------|-------------|-------------|-----|
|
||||||
|
| API key management | Hardcoded keys in scripts | Environment variables (.env + dotenv) | Security, portability, secrets rotation |
|
||||||
|
| HTTP retry logic | Manual retry loops | axios-retry or built-in retry config | Handles exponential backoff, max retries, error detection |
|
||||||
|
| Workflow JSON validation | Custom schema validator | n8n API validation on PATCH | n8n will reject invalid workflow structure |
|
||||||
|
| Execution log parsing | Custom log processors | n8n API returns structured execution data | Execution data already includes node outputs, errors, timestamps |
|
||||||
|
|
||||||
|
**Key insight:** n8n API has limited documentation, but attempting operations and reading error responses is often more reliable than trying to find docs. The API is forgiving - invalid requests return clear JSON error messages.
|
||||||
|
|
||||||
|
## Common Pitfalls
|
||||||
|
|
||||||
|
### Pitfall 1: API Not Enabled on Self-Hosted
|
||||||
|
**What goes wrong:** API calls return 404 or unauthorized even with valid key
|
||||||
|
**Why it happens:** User assumes API is enabled by default on self-hosted instances
|
||||||
|
**How to avoid:**
|
||||||
|
- API is enabled by default on modern n8n versions (v1.0+)
|
||||||
|
- Create API key via UI: Settings > n8n API > Create an API key
|
||||||
|
- No environment variable needed to "enable" API - it's always available
|
||||||
|
- If Settings > n8n API is missing, n8n version may be too old (upgrade to v1.0+)
|
||||||
|
|
||||||
|
**Warning signs:** 404 on `/api/v1/workflows`, "API access blocked" messages
|
||||||
|
|
||||||
|
### Pitfall 2: Using Private vs Public Endpoints
|
||||||
|
**What goes wrong:** Found endpoint pattern in n8n source code that returns 401/403
|
||||||
|
**Why it happens:** n8n has both public API endpoints (/api/v1/*) and private internal endpoints (/rest/*)
|
||||||
|
**How to avoid:**
|
||||||
|
- Use `/api/v1/*` endpoints for public API access
|
||||||
|
- Avoid `/rest/*` endpoints (internal, may require different auth or be restricted)
|
||||||
|
- Community examples sometimes reference `/rest/workflows` - this is NOT the public API
|
||||||
|
- Official public API base: `http(s)://your-n8n-host/api/v1/`
|
||||||
|
|
||||||
|
**Warning signs:** Authorization errors despite valid API key, endpoints working in browser but not via API
|
||||||
|
|
||||||
|
### Pitfall 3: Workflow Activation via API Timeout
|
||||||
|
**What goes wrong:** PATCH request to activate workflow times out, workflow stays inactive
|
||||||
|
**Why it happens:** Known n8n issue (GitHub #7258) - activation via API can timeout on some instances
|
||||||
|
**How to avoid:**
|
||||||
|
- Update workflow while inactive
|
||||||
|
- Activate manually via n8n UI after making changes
|
||||||
|
- If automation is critical, use n8n's built-in n8n node to activate workflows from another workflow
|
||||||
|
- Monitor for timeout (>30s response time), fallback to manual activation
|
||||||
|
|
||||||
|
**Warning signs:** API request hangs, workflow.active: true in response but UI shows inactive
|
||||||
|
|
||||||
|
### Pitfall 4: Missing Execution Logs
|
||||||
|
**What goes wrong:** `/api/v1/executions` returns empty or stale data
|
||||||
|
**Why it happens:** n8n execution pruning deletes old executions (default: 14 days)
|
||||||
|
**How to avoid:**
|
||||||
|
- Check execution retention settings: Environment variable `EXECUTIONS_DATA_PRUNE_MAX_AGE` (default: 336 hours = 14 days)
|
||||||
|
- For recent executions (<14 days), verify workflow has actually run
|
||||||
|
- Execution data is only saved if workflow execution completes (running workflows won't appear)
|
||||||
|
- Use `?limit=N` parameter to control result count (default: 20, max: 250)
|
||||||
|
|
||||||
|
**Warning signs:** Executions list is empty but workflow has run recently, old executions missing
|
||||||
|
|
||||||
|
### Pitfall 5: Credentials in Workflow JSON
|
||||||
|
**What goes wrong:** API returns workflow with credential IDs but not actual credential values
|
||||||
|
**Why it happens:** n8n API protects credential values from exposure
|
||||||
|
**How to avoid:**
|
||||||
|
- Workflow JSON contains credential IDs, not actual keys/tokens
|
||||||
|
- To update credentials, use separate credentials API endpoints
|
||||||
|
- Don't try to extract credential values from workflow JSON (they're not there)
|
||||||
|
- If cloning workflows between instances, credentials must be recreated manually
|
||||||
|
|
||||||
|
**Warning signs:** Workflow nodes reference credentials but values are missing/null
|
||||||
|
|
||||||
|
## Code Examples
|
||||||
|
|
||||||
|
Verified patterns from official sources and community:
|
||||||
|
|
||||||
|
### Creating API Key (UI)
|
||||||
|
**Source:** [n8n Authentication Docs](https://docs.n8n.io/api/authentication/)
|
||||||
|
```
|
||||||
|
1. Log in to n8n
|
||||||
|
2. Go to Settings > n8n API
|
||||||
|
3. Select "Create an API key"
|
||||||
|
4. Choose a Label (e.g., "Claude Code")
|
||||||
|
5. Set Expiration time (or "Never" for development)
|
||||||
|
6. Copy "My API Key" - this is shown ONCE
|
||||||
|
7. Store in secure location (.env file, password manager)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Get All Workflows
|
||||||
|
```bash
|
||||||
|
# Source: Community examples, Hostinger tutorial
|
||||||
|
curl -X GET 'http://localhost:5678/api/v1/workflows' \
|
||||||
|
-H 'accept: application/json' \
|
||||||
|
-H 'X-N8N-API-KEY: n8n_api_1234567890abcdef...'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"id": "1",
|
||||||
|
"name": "Telegram Docker Bot",
|
||||||
|
"active": true,
|
||||||
|
"createdAt": "2026-01-15T10:30:00.000Z",
|
||||||
|
"updatedAt": "2026-02-01T14:20:00.000Z",
|
||||||
|
"nodes": [...],
|
||||||
|
"connections": {...}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Get Specific Workflow
|
||||||
|
```bash
|
||||||
|
# Source: Community patterns
|
||||||
|
curl -X GET 'http://localhost:5678/api/v1/workflows/1' \
|
||||||
|
-H 'accept: application/json' \
|
||||||
|
-H 'X-N8N-API-KEY: n8n_api_...'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Update Workflow (Partial)
|
||||||
|
```bash
|
||||||
|
# Source: Community workflow manager patterns
|
||||||
|
curl -X PATCH 'http://localhost:5678/api/v1/workflows/1' \
|
||||||
|
-H 'accept: application/json' \
|
||||||
|
-H 'X-N8N-API-KEY: n8n_api_...' \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d '{
|
||||||
|
"nodes": [...updated nodes array...],
|
||||||
|
"connections": {...updated connections...}
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Get Execution History
|
||||||
|
```bash
|
||||||
|
# Source: Community monitoring patterns
|
||||||
|
curl -X GET 'http://localhost:5678/api/v1/executions?workflowId=1&limit=10' \
|
||||||
|
-H 'accept: application/json' \
|
||||||
|
-H 'X-N8N-API-KEY: n8n_api_...'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"id": "123",
|
||||||
|
"finished": true,
|
||||||
|
"mode": "webhook",
|
||||||
|
"startedAt": "2026-02-03T08:15:00.000Z",
|
||||||
|
"stoppedAt": "2026-02-03T08:15:02.000Z",
|
||||||
|
"workflowId": "1",
|
||||||
|
"status": "success"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nextCursor": "eyJsYXN0SWQiOiIxMjMifQ=="
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pagination Pattern
|
||||||
|
**Source:** [n8n API Pagination Docs](https://docs.n8n.io/api/pagination/)
|
||||||
|
```javascript
|
||||||
|
// n8n uses cursor-based pagination
|
||||||
|
async function getAllExecutions(workflowId) {
|
||||||
|
let allExecutions = [];
|
||||||
|
let cursor = null;
|
||||||
|
|
||||||
|
do {
|
||||||
|
const params = { workflowId, limit: 100 };
|
||||||
|
if (cursor) params.cursor = cursor;
|
||||||
|
|
||||||
|
const { data } = await n8nClient.get('/api/v1/executions', { params });
|
||||||
|
allExecutions.push(...data.data);
|
||||||
|
cursor = data.nextCursor;
|
||||||
|
} while (cursor);
|
||||||
|
|
||||||
|
return allExecutions;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** Default page size is 100, maximum is 250.
|
||||||
|
|
||||||
|
## State of the Art
|
||||||
|
|
||||||
|
| Old Approach | Current Approach | When Changed | Impact |
|
||||||
|
|--------------|------------------|--------------|--------|
|
||||||
|
| Manual workflow JSON editing | REST API for workflow updates | n8n v1.0 (2023) | API-first workflow management is now standard |
|
||||||
|
| No public API | Public REST API with API keys | n8n v1.0 (2023) | Programmatic access without database manipulation |
|
||||||
|
| Polling for executions | Cursor-based pagination | Recent (2025+) | Efficient execution history retrieval |
|
||||||
|
| Webhook-only workflow triggers | API playground for testing | Recent (2025+) | Interactive API testing built-in |
|
||||||
|
|
||||||
|
**Deprecated/outdated:**
|
||||||
|
- `/rest/*` endpoint patterns (internal API, not public) - Use `/api/v1/*` instead
|
||||||
|
- Trial user API access (no longer available) - Self-hosted or paid plans only
|
||||||
|
- API key via environment variable - Create via UI Settings instead
|
||||||
|
|
||||||
|
## Open Questions
|
||||||
|
|
||||||
|
Things that couldn't be fully resolved:
|
||||||
|
|
||||||
|
1. **API Endpoint Versioning**
|
||||||
|
- What we know: Current endpoints are `/api/v1/*`
|
||||||
|
- What's unclear: Will n8n introduce `/api/v2/*`? How to handle version transitions?
|
||||||
|
- Recommendation: Stick with v1 endpoints, monitor n8n release notes for API changes
|
||||||
|
|
||||||
|
2. **Rate Limiting on Self-Hosted**
|
||||||
|
- What we know: n8n Cloud has rate limits, self-hosted documentation mentions limits exist
|
||||||
|
- What's unclear: Exact limits for self-hosted API, whether configurable
|
||||||
|
- Recommendation: Assume conservative limit (~100 req/min), add retry logic, monitor for 429 responses
|
||||||
|
|
||||||
|
3. **Workflow Activation Reliability**
|
||||||
|
- What we know: GitHub issue #7258 shows activation via API can timeout
|
||||||
|
- What's unclear: Is this fixed in recent versions? Workarounds?
|
||||||
|
- Recommendation: Test on target n8n version, fallback to manual activation if needed
|
||||||
|
|
||||||
|
4. **Execution Log Detail Level**
|
||||||
|
- What we know: Executions API returns status, timestamps, basic error info
|
||||||
|
- What's unclear: Full node-by-node execution data available? Structured logs?
|
||||||
|
- Recommendation: Test execution response structure, may need to fetch individual execution details
|
||||||
|
|
||||||
|
## Sources
|
||||||
|
|
||||||
|
### Primary (HIGH confidence)
|
||||||
|
- [n8n API Documentation](https://docs.n8n.io/api/) - Official API overview
|
||||||
|
- [n8n API Authentication](https://docs.n8n.io/api/authentication/) - API key creation and usage
|
||||||
|
- [n8n API Pagination](https://docs.n8n.io/api/pagination/) - Cursor-based pagination
|
||||||
|
- [n8n API Playground](https://docs.n8n.io/api/using-api-playground/) - Interactive API testing
|
||||||
|
- [n8n API Reference](https://docs.n8n.io/api/api-reference/) - Endpoint documentation
|
||||||
|
|
||||||
|
### Secondary (MEDIUM confidence)
|
||||||
|
- [n8n API Integration Guide (Hostinger)](https://www.hostinger.com/tutorials/n8n-api) - Self-hosted setup examples
|
||||||
|
- [n8n Workflow Manager Template](https://n8n.io/workflows/4166-n8n-workflow-manager-api/) - Community workflow management patterns
|
||||||
|
- [Create Dynamic Workflows via API](https://n8n.io/workflows/4544-create-dynamic-workflows-programmatically-via-webhooks-and-n8n-api/) - Programmatic workflow creation examples
|
||||||
|
- [n8n API Rate Limits Guide (Refactix)](https://refactix.com/ai-automation-productivity/n8n-api-pagination-rate-limits-retries) - Rate limiting best practices
|
||||||
|
- [7 Common n8n Workflow Mistakes (Medium, 2026)](https://medium.com/@juanm.acebal/7-common-n8n-workflow-mistakes-that-can-break-your-automations-9638903fb076) - Error handling patterns
|
||||||
|
|
||||||
|
### Tertiary (LOW confidence)
|
||||||
|
- [n8n GitHub Issue #7258](https://github.com/n8n-io/n8n/issues/7258) - Workflow activation timeout issue
|
||||||
|
- [n8n GitHub Issue #14748](https://github.com/n8n-io/n8n/issues/14748) - GET /executions status filtering issue
|
||||||
|
- Community forum discussions on `/rest/workflows` API access issues
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
|
||||||
|
**Confidence breakdown:**
|
||||||
|
- Standard stack: MEDIUM - No official SDK exists, patterns derived from community usage
|
||||||
|
- Architecture: MEDIUM - Verified endpoint patterns from docs, response structures from community examples
|
||||||
|
- Pitfalls: MEDIUM - Mix of documented issues (GitHub) and community-reported problems
|
||||||
|
|
||||||
|
**Research date:** 2026-02-03
|
||||||
|
**Valid until:** ~30 days (n8n API is relatively stable, check release notes for breaking changes)
|
||||||
|
|
||||||
|
**Notes:**
|
||||||
|
- n8n API documentation is sparse - expect to discover endpoint behavior through experimentation
|
||||||
|
- Community forum and GitHub issues are valuable sources for undocumented behavior
|
||||||
|
- Official OpenAPI spec does not exist; API playground is interactive but not exportable
|
||||||
|
- This research assumes n8n v1.0+ (self-hosted via Docker on Unraid)
|
||||||
Reference in New Issue
Block a user