Skip to content

n8n — Reference

  • 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-sson8n_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):

  1. Validates auth (Bearer token from Vault secret/n8nn8n_webhook_token)
  2. Detects Reddit URL
  3. Cleans URL (resolves /s/ share links, rewrites to old.reddit.com)
  4. Fetches .json?limit=500&sort=top for metadata (title, subreddit, type, media)
  5. POSTs to ArchiveBox API wrapper (tag = subreddit name)
  6. Archives extra media URLs (gallery images, videos, external links)
  7. Logs to media-archives ledger (Forgejo repo, monthly CSV)

What it does (non-Reddit path):

  1. Validates auth
  2. Cleans URL (strips tracking params, unwraps Google redirects)
  3. Creates Karakeep bookmark
  4. 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 htmlContent exists (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/n8nn8n_webhook_token iOS Shortcuts, Glance
Karakeep API key secret/karakeepapi_key archive-media, karakeep-crawled
ArchiveBox API key secret/archiveboxapi_key archive-media (Reddit), archive-website
Forgejo token secret/forgejoclaude_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:

  1. Create a new Shortcut named "Archive Media"
  2. Add "Receive input from Share Sheet" → accept URLs
  3. Add "Get Contents of URL":
  4. URL: https://n8n.eva-00.network/webhook/archive-media
  5. Method: POST
  6. Headers:
    • Content-Type: application/json
    • Authorization: Bearer <token from Vault secret/n8n → n8n_webhook_token>
  7. Request Body (JSON): {"url": "[Shortcut Input]"}
  8. 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:

  1. Create a new Shortcut named "Archive Website"
  2. Add "Receive input from Share Sheet" → accept URLs
  3. Add "Get Contents of URL":
  4. URL: https://n8n.eva-00.network/webhook/archive-website
  5. Method: POST
  6. Headers:
    • Content-Type: application/json
    • Authorization: Bearer <token from Vault secret/n8n → n8n_webhook_token>
  7. Request Body (JSON): {"url": "[Shortcut Input]"}
  8. 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