API-Referenz
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 (inpublic/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.comals Platzhalter für deine GateControl-Domain.
Inhaltsverzeichnis
- Authentifizierung
- Rate-Limiting
- Fehler-Antworten
- Admin API
- Gateway-Companion API
- Desktop-Client API
- Öffentliche Endpoints
- Quick-Start-Beispiele
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 Erreichbarkeitgateway— Verbindung läuft durch einen Home-Gateway-Container; Server legt automatisch eine gelinkte L4-TCP-Route an (gateway_l4_route_idFK aufroutes.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/autobackupPOST /api/v1/settings/autobackup— Body{ schedule: "daily"|"weekly"|..., keep: 7, target: "local"|"s3", … }PUT /api/v1/settings/autobackup/:idDELETE /api/v1/settings/autobackup/:idPOST /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/webhooksPOST /api/v1/webhooks— Body{ name, url, events: ["peer_online", …], enabled, secret, retry_count? }PUT /api/v1/webhooks/:idDELETE /api/v1/webhooks/:idPUT /api/v1/webhooks/:id/togglePOST /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ückDELETE /api/v1/tokens/:id— widerrufen
Lizenz
GET /api/v1/license— aktueller Lizenz-Stand + FeaturesPOST /api/v1/license/activate— Body{ key }POST /api/v1/license/refresh— Force-Re-Validation gegen die Lizenz-APIDELETE /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/usersPOST /api/v1/users— Body{ username, email, password, role }PUT /api/v1/users/:idDELETE /api/v1/users/:idPOST /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_healthwird als JSON komplett gespeichert- State-Machine liest
route_reachabilityals Ground-Truth (Fallback: self-check) hostname+telemetryaktualisieren zusätzlichpeers.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.