n8n — Reference
Links
- Website: https://n8n.io
- API docs: https://docs.n8n.io/api/api-reference/
- Workflow nodes: https://docs.n8n.io/integrations/builtin/
- GitHub: https://github.com/n8n-io/n8n
Authentication
The n8n API requires an API key passed as a header. Generate one from the n8n UI: Settings → API → Create API Key.
curl -s -H "X-N8N-API-KEY: $N8N_API_KEY" \
https://n8n.eva-00.network/api/v1/...
Note: The API key is different from the webhook token. Webhooks use X-Webhook-Token (stored in Vault at secret/homelab-sso → n8n_webhook_token).
API — Workflows
List all workflows
curl -s -H "X-N8N-API-KEY: $N8N_API_KEY" \
https://n8n.eva-00.network/api/v1/workflows | python3 -c \
"import json,sys; [print(f'{w[\"id\"]} {w[\"name\"]} active={w[\"active\"]}') for w in json.load(sys.stdin)['data']]"
Get a specific workflow
curl -s -H "X-N8N-API-KEY: $N8N_API_KEY" \
https://n8n.eva-00.network/api/v1/workflows/<id>
Activate / deactivate a workflow
# Activate
curl -s -X PATCH -H "X-N8N-API-KEY: $N8N_API_KEY" \
-H "Content-Type: application/json" \
https://n8n.eva-00.network/api/v1/workflows/<id> \
-d '{"active": true}'
# Deactivate
curl -s -X PATCH -H "X-N8N-API-KEY: $N8N_API_KEY" \
-H "Content-Type: application/json" \
https://n8n.eva-00.network/api/v1/workflows/<id> \
-d '{"active": false}'
Create a workflow (import JSON)
curl -s -X POST -H "X-N8N-API-KEY: $N8N_API_KEY" \
-H "Content-Type: application/json" \
https://n8n.eva-00.network/api/v1/workflows \
-d @workflow.json
Delete a workflow
curl -s -X DELETE -H "X-N8N-API-KEY: $N8N_API_KEY" \
https://n8n.eva-00.network/api/v1/workflows/<id>
API — Executions
List recent executions
curl -s -H "X-N8N-API-KEY: $N8N_API_KEY" \
"https://n8n.eva-00.network/api/v1/executions?limit=10" | python3 -c \
"import json,sys; [print(f'{e[\"id\"]} {e[\"status\"]} {e[\"workflowId\"]}') for e in json.load(sys.stdin)['data']]"
Get execution details
curl -s -H "X-N8N-API-KEY: $N8N_API_KEY" \
https://n8n.eva-00.network/api/v1/executions/<id>
Retry a failed execution
curl -s -X POST -H "X-N8N-API-KEY: $N8N_API_KEY" \
https://n8n.eva-00.network/api/v1/executions/<id>/retry
Delete an execution
curl -s -X DELETE -H "X-N8N-API-KEY: $N8N_API_KEY" \
https://n8n.eva-00.network/api/v1/executions/<id>
API — Credentials
List credentials (metadata only — secrets not returned)
curl -s -H "X-N8N-API-KEY: $N8N_API_KEY" \
https://n8n.eva-00.network/api/v1/credentials | python3 -c \
"import json,sys; [print(f'{c[\"id\"]} {c[\"name\"]} type={c[\"type\"]}') for c in json.load(sys.stdin)['data']]"
Get credential schema (for a node type)
curl -s -H "X-N8N-API-KEY: $N8N_API_KEY" \
"https://n8n.eva-00.network/api/v1/credentials/schema/httpHeaderAuth"
Webhooks
Trigger a webhook workflow
curl -s -X POST https://n8n.eva-00.network/webhook/<path> \
-H "X-Webhook-Token: $WEBHOOK_TOKEN" \
-H "Content-Type: application/json" \
-d '{"key": "value"}'
Active webhook paths in this homelab
| Webhook | Purpose | Consumer | Auth |
|---|---|---|---|
/webhook/charlotte-weather |
Weather data for Glance | Glance dashboard | None (GET) |
/webhook/archive-media |
Smart routing: Reddit→ArchiveBox, everything else→Karakeep | iOS Shortcut "Archive Media" | Bearer token |
/webhook/archive-website |
Full website archive to ArchiveBox only | iOS Shortcut "Archive Website" | Bearer token |
/webhook/karakeep-crawled |
Fallback chain after Karakeep crawl | Karakeep webhook | None (internal) |
Bookmark & Archival Workflows
Two primary n8n workflows power the archival pipeline. Karakeep is the daily driver for bookmarks; ArchiveBox is the deep vault for Reddit posts and full websites.
flowchart LR
subgraph Input
S1[iOS Shortcut<br/>'Archive Media']
S2[iOS Shortcut<br/>'Archive Website']
S3[Safari Bookmarklet]
end
subgraph "archive-media workflow"
AM[/webhook/archive-media/]
R{Reddit?}
AM --> R
R -->|Yes| AB1[ArchiveBox<br/>tag=subreddit]
R -->|No| KK[Karakeep<br/>bookmark]
AB1 --> LED[Ledger<br/>monthly CSV]
KK --> LED
end
subgraph "archive-website workflow"
AW[/webhook/archive-website/]
AW --> AB2[ArchiveBox<br/>full archive]
end
S1 --> AM
S3 --> AM
S2 --> AW
style AB1 fill:#f96,stroke:#333
style AB2 fill:#f96,stroke:#333
style KK fill:#69f,stroke:#333
archive-media (smart routing)
curl -s -X POST https://n8n.eva-00.network/webhook/archive-media \
-H "Authorization: Bearer $N8N_WEBHOOK_TOKEN" \
-H "Content-Type: application/json" \
-d '{"url": "https://reddit.com/r/pics/comments/abc123/cool_photo/"}'
Response: {"status": "archived", "url": "...", "title": "...", "subreddit": "..."}
Routing logic:
| URL type | Destination | Notes |
|---|---|---|
| Reddit post | ArchiveBox only | Tags with subreddit, fetches .json metadata, archives extra media |
PDF (.pdf) |
Karakeep only | Stored as document bookmark |
| GitHub / Google (docs, search) | Karakeep only | Better reading experience |
| Everything else | Karakeep only | Generic bookmarks |
What it does (Reddit path):
- Validates auth (Bearer token from Vault
secret/n8n→n8n_webhook_token) - Detects Reddit URL
- Cleans URL (resolves
/s/share links, rewrites toold.reddit.com) - Fetches
.json?limit=500&sort=topfor metadata (title, subreddit, type, media) - POSTs to ArchiveBox API wrapper (tag = subreddit name)
- Archives extra media URLs (gallery images, videos, external links)
- Logs to media-archives ledger (Forgejo repo, monthly CSV)
What it does (non-Reddit path):
- Validates auth
- Cleans URL (strips tracking params, unwraps Google redirects)
- Creates Karakeep bookmark
- Logs to media-archives ledger
archive-website (ArchiveBox only)
curl -s -X POST https://n8n.eva-00.network/webhook/archive-website \
-H "Authorization: Bearer $N8N_WEBHOOK_TOKEN" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "depth": 1}'
Response: {"status": "queued", "url": "..."}
No Karakeep, no tagging, no ledger logging. Optional depth: 1 follows all links on the page. Use this for full website archives of non-Reddit pages.
karakeep-crawled (fallback chain)
Triggered by Karakeep webhook after monolith crawl completes. Not called directly.
- Tier 1: Checks if
htmlContentexists (monolith succeeded) - Tier 2: If no content → checks
archive.today/newest/{url}for existing snapshot - Tier 3: If archive.is also fails → tags
needs-manual-archive+ sends ntfy alert - Paywall detection: Short content + paywall keywords → tags
paywalled+ ntfy alert
Secrets
| Secret | Vault path | Used by |
|---|---|---|
| Webhook auth token | secret/n8n → n8n_webhook_token |
iOS Shortcuts, Glance |
| Karakeep API key | secret/karakeep → api_key |
archive-media, karakeep-crawled |
| ArchiveBox API key | secret/archivebox → api_key |
archive-media (Reddit), archive-website |
| Forgejo token | secret/forgejo → claude_mcp_access_token |
archive-media (ledger logging) |
iOS Shortcuts
Two iOS Shortcuts (+ macOS via Share Sheet or Safari bookmarklet) use the archival webhooks.
Archive Media
Smart routing: Reddit posts → ArchiveBox, everything else (PDFs, GitHub, Google, articles) → Karakeep.
Setup in Shortcuts app:
- Create a new Shortcut named "Archive Media"
- Add "Receive input from Share Sheet" → accept URLs
- Add "Get Contents of URL":
- URL:
https://n8n.eva-00.network/webhook/archive-media - Method: POST
- Headers:
Content-Type:application/jsonAuthorization:Bearer <token from Vault secret/n8n → n8n_webhook_token>
- Request Body (JSON):
{"url": "[Shortcut Input]"} - Add "Show Notification" → title: "Archived!"
Archive Website
Full website archive — sends to ArchiveBox only (DOM, WARC, screenshot, wget, media). No Karakeep.
Setup in Shortcuts app:
- Create a new Shortcut named "Archive Website"
- Add "Receive input from Share Sheet" → accept URLs
- Add "Get Contents of URL":
- URL:
https://n8n.eva-00.network/webhook/archive-website - Method: POST
- Headers:
Content-Type:application/jsonAuthorization:Bearer <token from Vault secret/n8n → n8n_webhook_token>
- Request Body (JSON):
{"url": "[Shortcut Input]"} - Add "Show Notification" → title: "Sent to ArchiveBox!"
Safari Bookmarklet (macOS)
For quick archiving from Safari without the Share Sheet:
javascript:void(fetch('https://n8n.eva-00.network/webhook/archive-media',{method:'POST',headers:{'Authorization':'Bearer TOKEN','Content-Type':'application/json'},body:JSON.stringify({url:location.href})}).then(r=>r.json()).then(d=>alert('Archived!')).catch(e=>alert('Error: '+e)))
Getting the webhook token for Shortcuts
vault kv get -field=n8n_webhook_token secret/n8n
Or via Vault UI at https://vault.eva-00.network/ui/vault/secrets/secret/show/n8n.
SQLite Direct Access
n8n uses SQLite for its database. Direct access is needed for operations the API doesn't support.
# Access the database
ssh [email protected] "pct exec 120 -- docker exec n8n sqlite3 /home/node/.n8n/database.sqlite"
# List all credentials with their types
ssh [email protected] "pct exec 120 -- docker exec n8n sqlite3 /home/node/.n8n/database.sqlite \
\"SELECT id, name, type FROM credentials_entity;\""
What the API/CLI Cannot Do
| Gap | Workaround |
|---|---|
| Cannot read credential secrets via API (security restriction) | Access SQLite directly: credentials_entity table (encrypted) |
| Cannot create credentials with secret values via API | Use the web UI or SQLite + n8n encryption format |
| Cannot execute a workflow on-demand via API (only webhooks) | Trigger via webhook endpoint or activate/deactivate |
| No CLI for n8n | API-only; use curl for automation |
| Cannot manage environment variables via API | Set in docker-compose .env file |
| Cannot manage community nodes via API | Install via web UI: Settings → Community Nodes |
| Execution history has a retention limit | Configure EXECUTIONS_DATA_MAX_AGE env var |
| Cannot view node-level execution data in list endpoint | Must fetch individual execution by ID |