CallMeTechie
EN Anmelden
Home Produkte Blog Über mich Kontakt

API-Referenz

v1.0 · Updated vor 1 Monat

Vollständige Endpoint-Referenz für Server v1.50+. Praktische Integrations-Rezepte stehen im separaten API_GUIDE.md; nur Desktop-Client-spezifische Flows haben ein eigenes Kapitel in CLIENT-API.md.

Konventionen:

  • Alle Admin-Endpoints sind unter /api/v1/* erreichbar. Der Pfad /api/* existiert als backward-compatibler Alias und wird clientseitig (in public/js/app.js) auf /api/v1/* umgeschrieben.
  • Antworten folgen dem Muster { ok: true, … } bzw. { ok: false, error: "…" }. Abweichungen sind beim Endpoint vermerkt.
  • Alle Beispiele benutzen gate.example.com als Platzhalter für deine GateControl-Domain.

Inhaltsverzeichnis


Authentifizierung

GateControl kennt drei Authentifizierungs-Pfade. Je nach Pfad gelten unterschiedliche Regeln für CSRF, Rate-Limits und den Input-Scope.

Session-Authentifizierung (Browser)

Verwendet vom Admin-UI. Login per POST /login setzt ein Session-Cookie.

curl -c cookies.txt -X POST https://gate.example.com/login \
  -d "username=admin&password=…"
curl -b cookies.txt https://gate.example.com/api/v1/peers

Zustandsändernde Methoden (POST/PUT/DELETE/PATCH) brauchen zusätzlich einen CSRF-Token im Header X-CSRF-Token. Der Token steckt in window.GC.csrfToken (vom Server per res.locals.csrfToken in jedes Template injiziert) oder im _csrf-Body-Feld.

API-Token (Automation)

Für Skripte und Integrationen. Token werden unter Settings → API-Tokens angelegt. Bearer-Header:

curl -H "Authorization: Bearer gc_…" https://gate.example.com/api/v1/peers

Alternativ X-API-Token oder X-API-Key. Token-authentifizierte Requests umgehen CSRF.

Token-Scopes

Scope Zugriff
full-access Alle Endpoints (Lesen + Schreiben)
read-only Nur GET-Requests
peers /api/v1/peers/* komplett
routes /api/v1/routes/* komplett
settings /api/v1/settings/* + /api/v1/smtp/*
webhooks /api/v1/webhooks/*
logs /api/v1/logs/*
system /api/v1/system/*, /api/v1/wg/*, /api/v1/caddy/*

Gateway-Token (Companion-Container)

Jeder Home-Gateway-Peer hat ein eigenes Bearer-Token, geliefert in der gateway.env-Datei. Gilt ausschließlich für Endpoints unter /api/v1/gateway/*. Auth erfolgt über Authorization: Bearer <apiToken>. Das Token ist an einen bestimmten Peer gebunden (siehe requireGateway-Middleware), CSRF entfällt.


Rate-Limiting

Eingebaute Limiter pro IP:

Scope Fenster Limit
/login 15 min 10
/api/v1/* (admin) 15 min 1000
/api/v1/client/* (Peer-Agent) 15 min 100
/api/v1/client/peer/hostname 1 min 3
/api/v1/gateway/heartbeat kein expliziter Limit (Token-Auth)

Response-Header Ratelimit-Limit, Ratelimit-Remaining, Ratelimit-Reset sind immer gesetzt.


Fehler-Antworten

{ "ok": false, "error": "Menschenlesbare Meldung", "fields": { "domain": "Pflichtfeld" } }

fields ist optional — nur bei Schema-Validierungsfehlern (HTTP 400). Statuscodes:

Code Bedeutung
200 OK
201 Created
304 Not Modified (z.B. /gateway/config/check)
400 Validierungsfehler — Details meist in fields
401 Nicht authentifiziert
403 CSRF fehlt/ungültig oder Scope unzureichend
404 Ressource nicht vorhanden
409 Konflikt (z.B. Peer-Gruppe mit Name existiert schon)
429 Rate-Limit
500 Serverfehler

Admin API

Alle folgenden Endpoints sind hinter requireAuth + apiLimiter (/api/v1/*). Schreibende Operationen brauchen CSRF bei Session-Auth.

Dashboard

GET /api/v1/dashboard/stats

Liefert die Zahlen für die 5 Dashboard-Stat-Karten.

{
  "ok": true,
  "peers":   { "total": 6, "online": 4 },
  "routes":  { "active": 7 },
  "monitoring": { "total": 3, "up": 2, "down": 1 },
  "traffic": { "today": 3200000000, "todayUpload": 1200000000, "todayDownload": 2000000000,
               "uploadRate": 41200, "downloadRate": 128000 },
  "wireguard": { "running": true },
  "latency": 23
}

GET /api/v1/dashboard/traffic?period=1h|24h|7d

Chart-Daten-Punkte für den Traffic-Graph.


System

GET /api/v1/system/resources

CPU, RAM, Uptime, Disk. Wird u.a. vom Dashboard aufgerufen.

{ "ok": true,
  "cpu":    { "cores": 4, "percent": 8, "model": "…" },
  "memory": { "total": 8e9, "used": 2e9, "percent": 25 },
  "uptime": { "seconds": 1234, "days": 0, "hours": 0, "minutes": 20, "formatted": "20m", "bootTime": "2026-04-22" },
  "disk":   { "total": …, "free": …, "used": … }
}

GET /api/v1/system/dns/status · Feature internal_dns

Interner DNS-Service-Zustand: Hosts-Datei-Metadaten, Peer-Anzahl nach Hostname-Source (admin/agent/stale).

GET /api/v1/system/dns/records · Feature internal_dns

Snapshot der gesamten internen DNS-Zone: statische Records (gateway.<domain>, server.<domain>), alle Peer-Records mit Quelle.


Logs

GET /api/v1/logs/activity?limit=100&offset=0&severity=info

Full Activity-Log. Filter: severity, source, event_type, since, until (ISO-Datum oder epoch-ms).

GET /api/v1/logs/recent?limit=10

Aktivitäts-Feed für Dashboard.

GET /api/v1/logs/access?limit=100&offset=0

Caddy-Access-Log (gefiltert aus /data/caddy/access.log).

GET /api/v1/logs/activity/export?format=csv|json

GET /api/v1/logs/access/export?format=csv|json

Als File-Download.


Peers

GET /api/v1/peers?limit=250&offset=0

Liste aller Peers.

{ "ok": true, "peers": [
  { "id": 73, "name": "NAS2", "peer_type": "regular", "enabled": 1, "allowed_ips": "10.8.0.3/32",
    "tags": "NAS, Heimnetz", "group_id": 2, "hostname": "nas2", "hostname_source": "admin",
    "expires_at": null, "total_rx": …, "total_tx": …, "latestHandshake": 1776…,
    "isOnline": true }
] }

peer_type ist entweder "regular" oder "gateway".

GET /api/v1/peers/:id

Einzel-Peer.

POST /api/v1/peers

Legt einen Peer an. Body:

{ "name": "Laptop", "description": "Reisegerät", "tags": "Desktop",
  "group_id": 1, "expires_at": "2026-12-31", "dns": "1.1.1.1",
  "is_gateway": false, "api_port": 9876 }

is_gateway: true legt einen Gateway-Peer an und antwortet mit { peer, gateway: { apiToken, pushToken, envContent } } (Plaintext-Tokens nur einmal; im envContent ist eine fertige gateway.env).

PUT /api/v1/peers/:id

Partial-Update. Alle Felder optional.

DELETE /api/v1/peers/:id

Entfernt den Peer. Bricht bestehende WG-Handshakes.

PUT /api/v1/peers/:id/toggle

Enable/Disable ohne Löschen.

POST /api/v1/peers/batch

Body { action: "enable"|"disable"|"delete", ids: [1,2,3] }.

GET /api/v1/peers/:id/config

WireGuard-Config als Plaintext-Body (Content-Type text/plain). Query ?download=1 löst Attachment-Download aus.

GET /api/v1/peers/:id/qr

QR-Code als Data-URL + raw Config.

{ "ok": true, "name": "…", "qr": "data:image/png;base64,…", "config": "[Interface]\n…" }

PATCH /api/v1/peers/:id/hostname · Feature internal_dns

Admin setzt Hostname für internen DNS. Body { hostname: "nas2" }. Leer-String oder null entfernt. Sticky-Admin: überschreibt Agent-gemeldete Namen, Agent-Writes können einen Admin-Wert nicht ersetzen.

GET /api/v1/peers/:id/gateway-info

Nur für peer_type === "gateway". Parsed last_health-Payload + State-Machine-Status + API-Port.

{ "ok": true, "gateway": {
  "peer_id": 79, "status": "online", "api_port": 9876, "last_seen_at": 1776…,
  "health": { "uptime_s": 4200, "wg_handshake_age_s": 45,
    "route_reachability": [ { "route_id": 43, "reachable": true, "latency_ms": 2 } ],
    "telemetry": { "gateway_version": "1.4.0", "cpu_cores": 4, "mem_used": 234000000, … } }
} }

GET /api/v1/peers/:id/traffic?period=24h|7d|30d

Chart-Daten für den Per-Peer-Traffic.

POST /api/v1/peers/:id/gateway-env/rotate

Rotiert Gateway-API-Token + Push-Token für einen Gateway-Peer. Invalidiert den laufenden Companion sofort. Response enthält frische Tokens + neu gebautes envContent.


Peer-Gruppen

GET /api/v1/peer-groups

Alle Gruppen mit Peer-Anzahl.

{ "ok": true, "groups": [{ "id": 2, "name": "Heimnetz", "color": "#64748b", "description": "", "peer_count": 3 }] }

POST /api/v1/peer-groups — Body { name, color?, description? }

PUT /api/v1/peer-groups/:id

DELETE /api/v1/peer-groups/:id

Löschen setzt group_id aller Mitglieder auf NULL.


Tags

Peer-Tags sind eine CSV auf peers.tags. Seit v1.48 gibt es zusätzlich eine Registry-Tabelle (tags), die Tag-Namen unabhängig von Peer-Zuweisungen verwaltet.

GET /api/v1/tags

Merged-View: Registry + distinkte Tokens aus allen Peer-CSVs.

{ "ok": true, "tags": [
  { "id": 3, "name": "server", "peer_count": 2, "registered": true },
  { "id": null, "name": "Pixel-only", "peer_count": 1, "registered": false }
] }

POST /api/v1/tags — Body { name }

Idempotent (INSERT OR IGNORE). Rejected bei ,<>"\n\r\t oder > 64 Zeichen.

DELETE /api/v1/tags/:name

Löscht Registry-Eintrag und strippt Token aus allen peers.tags-CSVs (case-insensitive, whole-word — prod wipe'd nicht prod-backup).


Routes

Reverse-Proxy-Konfiguration. Route-Typen: http, l4. Ziele: peer (direkter WG-Peer) oder gateway (über Home-Gateway-Container).

GET /api/v1/routes?limit=250&offset=0&type=http|l4

GET /api/v1/routes/:id

POST /api/v1/routes

Body-Felder (Auszug):

{ "domain": "app.example.com",
  "route_type": "http",
  "target_kind": "peer",
  "peer_id": 73,
  "target_port": "5000",

  "https_enabled": true,
  "backend_https": false,
  "compress_enabled": false,

  "bot_blocker_enabled": false,
  "bot_blocker_mode": "block",
  "bot_blocker_config": {},

  "monitoring_enabled": false,
  "ip_filter_enabled": false,
  "ip_filter_mode": "whitelist",
  "ip_filter_rules": [],

  "acl_enabled": false,
  "acl_peer_ids": [],

  "rate_limit_enabled": false,
  "rate_limit_requests": 100,
  "rate_limit_window": "1m",

  "retry_enabled": false,
  "retry_count": 3,
  "retry_status_codes": "502,503,504",

  "circuit_breaker_enabled": false,
  "circuit_breaker_threshold": 5,
  "circuit_breaker_timeout": 30,

  "mirror_enabled": false,
  "mirror_targets": [],

  "debug_enabled": false,

  "basic_auth_user": "",
  "basic_auth_password": "",

  "user_ids": [1, 2] }

Gateway-Routen: target_kind: "gateway", target_peer_id: <gateway-peer-id>, target_lan_host, target_lan_port (+ optional wol_enabled, wol_mac).

L4-Routen: zusätzlich l4_protocol (tcp|udp), l4_listen_port, l4_tls_mode (none|passthrough|terminate).

PUT /api/v1/routes/:id — Partial-Update

DELETE /api/v1/routes/:id

PUT /api/v1/routes/:id/toggle

POST /api/v1/routes/batch — Body { action, ids }

POST /api/v1/routes/check-dns — Body { domain }

DNS-Prüfung: Load A-Records, Vergleich gegen die öffentliche IP des Servers.

{ "ok": true, "matches": true, "resolvedIps": ["1.2.3.4"], "expectedIp": "1.2.3.4" }

GET /api/v1/routes/peers

Liste verfügbarer Peers für den Route-Wizard (online-Status, Gateway-Flag, Gruppe). Query ?peer_type=gateway filtert auf Gateway-Peers.

POST /api/v1/routes/:id/check

Sofortige Uptime-Monitoring-Prüfung auslösen.

POST /api/v1/routes/:id/circuit-breaker/reset · Feature circuit_breaker

Setzt einen hängenden Circuit-Breaker manuell auf closed zurück (nullt cb_failure_count, räumt cb_opened_at, re-rendert Caddy). Nötig weil der Breaker-Zustand in SQLite persistiert wird und Neustarts überlebt — ohne Reset wartet ein offener Breaker auf den Timeout- und Half-Open-Zyklus des Monitorings. Antwortet 400 wenn Circuit-Breaker an der Route nicht aktiviert ist.

POST /api/v1/routes/:id/branding/logo (Multipart file)

DELETE /api/v1/routes/:id/branding/logo

POST /api/v1/routes/:id/branding/bg-image (Multipart file)

DELETE /api/v1/routes/:id/branding/bg-image

Benutzerdefiniertes Branding für die Route-Auth-Login-Seite.

GET /api/v1/routes/:id/trace

Request-Tracing: liefert die N letzten Requests für die Route. Details siehe features/request-tracing.md.


Route-Auth

Sub-Resource zu Routes. Gateway ist /:id/auth.

GET /api/v1/routes/:id/auth

POST /api/v1/routes/:id/auth

Body konfiguriert die Auth-Methode: email_password, email_code, totp; optional two_factor_enabled + two_factor_method. Felder: email, password, session_max_age (ms).

DELETE /api/v1/routes/:id/auth

POST /api/v1/routes/:id/auth/totp-setup

POST /api/v1/routes/:id/auth/totp-verify — Body { token }


RDP-Routen

RDP ist ein eigener Route-Typ mit eigener API unter /api/v1/rdp/*. Licensegated (remote_desktop).

GET /api/v1/rdp

Liste aller RDP-Routen.

POST /api/v1/rdp — Body (Auszug)

{ "name": "Büro-PC",
  "access_mode": "internal" | "external" | "both" | "gateway",
  "target_host": "192.168.2.10", "target_port": 3389,
  "listen_port": 13389,
  "gateway_peer_id": 79, "gateway_listen_port": 3389,
  "gateway_host": "rdg.example.com", "gateway_port": 443,
  "credentials": { "username": "mka", "password": "…", "domain": "" },
  "wol_enabled": true, "wol_mac": "AA:BB:CC:DD:EE:FF",
  "network_level_auth": true, "audio_mode": "local", "clipboard_enabled": true,
  "resolution": "1920x1080", "color_depth": 32,
  "maintenance_windows": [] }

access_mode (aus VALID_ACCESS_MODES in src/services/rdp.js):

  • internal — Ziel ist ein direkter WG-Peer im Tunnel (LAN-IP des Clients + RDP-Port)
  • external — Ziel ist per öffentlicher IP/Domain erreichbar (z.B. eigener RDP-Server mit Port-Forwarding)
  • both — beide Pfade möglich, Desktop-Client wählt nach Erreichbarkeit
  • gateway — Verbindung läuft durch einen Home-Gateway-Container; Server legt automatisch eine gelinkte L4-TCP-Route an (gateway_l4_route_id FK auf routes.id). Siehe features/rdp-via-gateway.md.

Microsoft RD-Gateway (TSGateway) ist kein eigener Mode, sondern ein zusätzliches Feld-Paar: gateway_host + gateway_port werden an den Desktop-Client als .rdp-Config mit gatewayhostname/gatewayport durchgereicht und können zu jedem Access-Mode ergänzend konfiguriert werden.

GET /api/v1/rdp/:id

PATCH /api/v1/rdp/:id

DELETE /api/v1/rdp/:id

PUT /api/v1/rdp/:id/toggle

POST /api/v1/rdp/batch

GET /api/v1/rdp/status

Aggregierter Status aller RDP-Routen.

GET /api/v1/rdp/pubkey

Server-Public-Key für Credential-Verschlüsselung (client-seitig).

GET /api/v1/rdp/:id/credentials

PUT /api/v1/rdp/:id/credentials — Body { credentials: { …E2EE-verschlüsselt… } }

DELETE /api/v1/rdp/:id/credentials

Ciphertext-In/Out — Passwort wird nie im Klartext gespeichert. Siehe src/utils/crypto.js.

POST /api/v1/rdp/:id/wol

Sendet Wake-on-LAN Magic-Packet via Gateway (wenn gateway-typed) oder direkt (peer-typed). Body optional { timeout_ms }.

GET /api/v1/rdp/:id/wol/status

GET /api/v1/rdp/:id/status

POST /api/v1/rdp/:id/sessions/disconnect-all

Trennt alle aktiven Sessions (serverseitiger Kill via RDP-Admin-Protokoll, falls verfügbar — sonst Marker).

GET /api/v1/rdp/:id/history?limit=100

GET /api/v1/rdp/history/export?format=csv|json

Pro-Route Session-History.

GET /api/v1/rdp/:id/maintenance

PUT /api/v1/rdp/:id/maintenance — Body { windows: [{ from, to, note }] }

GET /api/v1/rdp/rotation/pending

POST /api/v1/rdp/:id/rotation/ack

Credential-Rotation-Workflow — welche Routes warten auf ein neues Passwort (weil der Master-Key rotiert wurde), Admin bestätigt nach erneutem Eintrag.


Gateways (Admin-Sicht)

GET /api/v1/gateways

Konsolidierte Liste aller Gateway-Peers. Ein Call füttert die komplette "Home Gateways"-Sektion auf /peers.

{ "ok": true, "gateways": [{
  "peer_id": 79, "name": "Home Gateway", "hostname": "nas1", "ip": "10.8.0.8",
  "api_port": 9876, "status": "online", "last_seen_at": 1776…,
  "health": { …komplettes last_health JSON inkl. telemetry… },
  "routes": [ { "id": 43, "domain": "nas.domaincaster.com", "route_type": "http",
                "target_lan_host": "192.168.2.228", "target_lan_port": 5000 } ]
}] }

status kommt aus dem Gateway-State-Machine (siehe src/services/gateways.js): "online", "offline", "unknown". Grundwahrheit ist route_reachability — Details in der Anleitung zu _isHeartbeatHealthy (tests/gateway_health_definition.test.js).


Settings

Alle unter /api/v1/settings/*.

GET /api/v1/settings/profile

PUT /api/v1/settings/profile — Body { username?, email?, language? }

PUT /api/v1/settings/password — Body { current, next }

POST /api/v1/settings/language — Body { language: "de"|"en" }

GET /api/v1/settings/app

PUT /api/v1/settings/default-theme — Body { theme: "pro"|"default" }

Serverweite Default-Theme, greift für Nutzer ohne eigene Auswahl.

POST /api/v1/settings/clear-logs

Löscht Activity- und Access-Logs (Bestätigung per CSRF).


SMTP

GET /api/v1/smtp

PUT /api/v1/smtp — Body { host, port, secure, user, password, from }

POST /api/v1/smtp/test — Body { to }

Verschickt Test-Mail an die angegebene Adresse.


Backup & Restore

GET /api/v1/settings/backup

Vollständiges JSON-Backup (Peers, Routes, Settings, Webhooks, Route-Auth, Peer-Groups). Query ?format=download als Attachment.

POST /api/v1/settings/backup/restore (Multipart)

Lädt ein Backup-JSON. Optional ?mode=merge|replace.

Auto-Backup-Jobs

  • GET /api/v1/settings/autobackup
  • POST /api/v1/settings/autobackup — Body { schedule: "daily"|"weekly"|..., keep: 7, target: "local"|"s3", … }
  • PUT /api/v1/settings/autobackup/:id
  • DELETE /api/v1/settings/autobackup/:id
  • POST /api/v1/settings/autobackup/:id/run — manuell auslösen

WireGuard

GET /api/v1/wg/status

Aktueller Interface-Status, Peer-Handshakes.

POST /api/v1/wg/restart

wg-quick down wg0 && wg-quick up wg0.


Caddy

GET /api/v1/caddy/status

{ ok, running: bool, pid, uptime_s, admin_api: "127.0.0.1:2019" }.

POST /api/v1/caddy/reload

Forciert Re-Rendering der Caddy-Config und Admin-API-Load.


Webhooks

  • GET /api/v1/webhooks
  • POST /api/v1/webhooks — Body { name, url, events: ["peer_online", …], enabled, secret, retry_count? }
  • PUT /api/v1/webhooks/:id
  • DELETE /api/v1/webhooks/:id
  • PUT /api/v1/webhooks/:id/toggle
  • POST /api/v1/webhooks/:id/test — feuert einen Test-POST

API-Tokens

  • GET /api/v1/tokens — Liste (Token-Hash nur beim Create)
  • POST /api/v1/tokens — Body { name, scopes: ["full-access"], expires_at? } → Plain-Token einmalig zurück
  • DELETE /api/v1/tokens/:id — widerrufen

Lizenz

  • GET /api/v1/license — aktueller Lizenz-Stand + Features
  • POST /api/v1/license/activate — Body { key }
  • POST /api/v1/license/refresh — Force-Re-Validation gegen die Lizenz-API
  • DELETE /api/v1/license — lokal entfernen, zurück in Community-Fallback

Users

Nur für Rollen admin. Multi-User-Tabelle für UI-Logins (im Gegensatz zu API-Tokens).

  • GET /api/v1/users
  • POST /api/v1/users — Body { username, email, password, role }
  • PUT /api/v1/users/:id
  • DELETE /api/v1/users/:id
  • POST /api/v1/users/:id/reset-password

Gateway-Companion API

Endpoints unter /api/v1/gateway/*. Der Zweck dieser Gruppe ist der Daten-Austausch zwischen einem Home-Gateway-Container (gatecontrol-gateway) und dem Server. Auth: Bearer-Token aus der gateway.env — Middleware requireGateway bindet das Token an eine Peer-ID.

GET /api/v1/gateway/config

Holt die aktuelle Gateway-Konfiguration (Routes, TCP-Listener-Ports, Caddy-Proxy-Port). Response enthält config_hash für Efficient-Polling.

GET /api/v1/gateway/config/check?hash=sha256:…

Long-poll-freundlicher Hash-Check. Antwortet 304 wenn unverändert, sonst 200 mit neuem Hash.

POST /api/v1/gateway/status — Body { rx_bytes, tx_bytes, active_connections }

Traffic-Counter-Snapshot. Wird nicht als Heartbeat gewertet.

POST /api/v1/gateway/probe — Body beliebig

Echo-Endpoint für End-to-End-Verbindungstests (Round-Trip-Zeit, Payload-Integrität).

POST /api/v1/gateway/heartbeat — Body (Auszug)

{ "uptime_s": 4200,
  "http_proxy_healthy": true,
  "api_healthy": true,
  "tcp_listeners": [{ "port": 13389, "status": "listening" }],
  "wg_handshake_age_s": 45,
  "dns_resolve_ok": true,
  "route_reachability": [{ "route_id": 43, "reachable": true, "latency_ms": 2 }],
  "overall_healthy": true,
  "hostname": "nas1",
  "config_hash": "sha256:…",
  "telemetry": { "gateway_version": "1.4.0", "node_version": "20.20.2",
    "wg_tools_version": "wireguard-tools v1.0.20210914",
    "cpu_cores": 4, "cpu_load_avg": [0.15, 0.22, 0.18],
    "mem_total": …, "mem_free": …, "mem_used": …,
    "disk": { "total": …, "free": …, "used": … },
    "os_platform": "linux", "os_release": "6.1.78", "arch": "arm64",
    "dns_resolvers": ["192.168.1.1"], "default_gateway_ip": "192.168.1.1" }
}

Seiten-Effekte:

  • gateway_meta.last_health wird als JSON komplett gespeichert
  • State-Machine liest route_reachability als Ground-Truth (Fallback: self-check)
  • hostname + telemetry aktualisieren zusätzlich peers.hostname (agent-source, sticky-admin)

Desktop-Client API

Pfad /api/v1/client/*. Auth: Bearer-Token + Machine-Fingerprint-Binding. Details: CLIENT-API.md.

Kompakt-Liste:

Endpoint Zweck
GET /ping Lebenszeichen + Server-Version
GET /permissions Was darf dieses Token?
POST /register Neuer Client registriert Peer-Slot
GET /config WG-Config aktuell
GET /config/check?hash=… Hash-basierter Idle-Poll
POST /heartbeat Handshake-Status, rx/tx, optional hostname
POST /status Detailliertes Gerät-Status-Update
POST /peer/hostname Opportunistischer Hostname-Report (Internal-DNS, rate-limited 3/min)
GET /peer-info?peerId=… Lookup eines anderen Peers (z.B. für DNS-Fallback)
GET /traffic?period=… Per-Peer-Traffic-Historie
GET /services Zugewiesene Services (Routes) für den Client
GET /dns-check?domain=… DNS-Lookup-Proxy fürs UI-Diagnosetool
GET /rdp RDP-Routen, für die dieser Client freigegeben ist
GET /rdp/:id/status Ist das Ziel erreichbar?
GET /rdp/:id/connect .rdp-Connect-Profil generieren
POST /rdp/:id/session Session-Start aufzeichnen
PATCH /rdp/:id/session Session-Heartbeat
DELETE /rdp/:id/session Session-End
GET /split-tunnel Liste der zu tunnelnden IP-Bereiche (Override möglich pro Token)

Öffentliche Endpoints

Kein Auth nötig.

GET /health

Health-Check (DB + WG-Interface). Localhost-Requests bekommen Detail-Struktur, remote nur { ok }. 503 bei Fehler.

GET /api/v1/client/update

Public-Release-Info (Version, Download-URL). Damit können Desktop-Clients Updates entdecken, auch wenn ihr Token invalid ist.

GET /metrics · Feature prometheus_metrics

Prometheus-Format. Auth per Session oder Token (system/full-access/read-only). Zusätzlich ?token=… als Query-Param erlaubt.

POST /login · POST /logout

Admin-Auth-Endpoints (Body siehe AUTHENTICATION.md).


Quick-Start-Beispiele

Peer anlegen mit API-Token

TOKEN="gc_…"
curl -X POST https://gate.example.com/api/v1/peers \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"name":"Laptop","description":"Reisegerät","tags":"Desktop"}' \
  | jq .peer.id

Gateway-Peer anlegen (Gateway-Env herunterladen)

curl -X POST https://gate.example.com/api/v1/peers \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"name":"NAS1","is_gateway":true,"api_port":9876}' \
  | jq -r .gateway.envContent > gateway.env

Traffic heute abfragen (für Monitoring-Dashboard)

curl -H "Authorization: Bearer $TOKEN" \
  https://gate.example.com/api/v1/dashboard/stats | jq .traffic.today

Route disablen (Home-Automation-Szenario)

curl -X PUT -H "Authorization: Bearer $TOKEN" \
  https://gate.example.com/api/v1/routes/7/toggle

Full-Backup als Datei speichern

curl -H "Authorization: Bearer $TOKEN" \
  "https://gate.example.com/api/v1/settings/backup?format=download" \
  -o backup-$(date -u +%F).json

Weitere Integrations-Rezepte (Home Assistant, Python, Tasker, GitHub Actions …): API_GUIDE.md.

Cookie Settings

Wir verwenden Cookies, um Ihre Erfahrung zu verbessern. Essentielle Cookies sind immer aktiv.

Datenschutzerklärung
ESC
↑↓ navigate open esc close