REST API Reference
REST API Reference
Section titled “REST API Reference”Both server and client expose REST APIs for management and monitoring.
Authentication
Section titled “Authentication”If API token is configured:
curl -H "Authorization: Bearer your-token" http://localhost:7082/api/v1/statusOr via query parameter:
curl "http://localhost:7082/api/v1/status?token=your-token"Server API
Section titled “Server API”Default: http://localhost:7082
Health Check
Section titled “Health Check”GET /api/v1/healthResponse:
{ "status": "healthy", "time": "2024-01-01T00:00:00Z"}Version
Section titled “Version”GET /api/v1/versionResponse:
{ "version": "1.0.0", "git_commit": "abc123", "build_time": "2024-01-01T00:00:00Z", "go_version": "go1.22.0", "platform": "linux/amd64"}Status
Section titled “Status”GET /api/v1/statusResponse:
{ "status": "running", "time": "2024-01-01T00:00:00Z", "version": "1.0.0", "backends": 3}Server Statistics
Section titled “Server Statistics”GET /api/v1/statsResponse:
{ "total_connections": 5000, "active_connections": 25, "bytes_sent": 104857600, "bytes_received": 209715200, "backends": { "total": 3, "healthy": 3 }, "time": "2024-01-01T00:00:00Z"}List Backends
Section titled “List Backends”GET /api/v1/backendsResponse:
[ { "name": "direct", "type": "direct", "healthy": true, "stats": { "active_connections": 5, "total_connections": 100, "bytes_sent": 1024000, "bytes_received": 2048000 } }]Get Backend
Section titled “Get Backend”GET /api/v1/backends/{name}Backend Stats
Section titled “Backend Stats”GET /api/v1/backends/{name}/statsConfiguration
Section titled “Configuration”Get sanitized config (safe to display):
GET /api/v1/configGet full config for editing:
GET /api/v1/config/fullGet config section metadata (hot-reload info):
GET /api/v1/config/metaSave configuration:
PUT /api/v1/configContent-Type: application/json
{ "config": { ... }, "create_backup": true}Validate config without saving:
POST /api/v1/config/validateContent-Type: application/json
{ ... config object ... }Reload configuration:
POST /api/v1/config/reloadRequest Log
Section titled “Request Log”Get recent requests (requires enable_request_log: true in config):
GET /api/v1/requestsGET /api/v1/requests?limit=50GET /api/v1/requests?since=123 # Get requests since IDResponse:
{ "enabled": true, "requests": [ { "id": 1, "timestamp": "2024-01-01T00:00:00Z", "method": "GET", "host": "example.com", "path": "/api/data", "backend": "direct", "status_code": 200, "duration_ms": 150, "bytes_sent": 1024, "bytes_recv": 2048 } ]}Get request log stats:
GET /api/v1/requests/statsClear request log:
DELETE /api/v1/requestsActive Connections
Section titled “Active Connections”Get all active connections:
GET /api/v1/connectionsResponse:
{ "connections": [ { "id": "20240115100000-1", "client_ip": "192.168.1.100", "client_port": "54321", "host": "example.com:443", "backend": "direct", "protocol": "CONNECT", "start_time": "2024-01-15T10:00:00Z", "bytes_sent": 1024, "bytes_recv": 2048 } ], "count": 1, "time": "2024-01-15T10:00:05Z"}Connected Clients
Section titled “Connected Clients”Get unique connected clients with aggregated stats:
GET /api/v1/connections/clientsResponse:
{ "clients": [ { "client_ip": "192.168.1.100", "connections": 5, "bytes_sent": 10240, "bytes_recv": 20480, "first_seen": "2024-01-15T09:00:00Z" } ], "count": 1, "time": "2024-01-15T10:00:05Z"}Cache Management
Section titled “Cache Management”Get cache statistics:
GET /api/v1/cache/statsResponse:
{ "enabled": true, "hit_rate": 0.85, "total_requests": 12450, "cache_hits": 10582, "cache_misses": 1868, "storage_type": "tiered", "rules_count": 5, "memory": { "entries": 4521, "size_bytes": 1073741824, "max_size_bytes": 2147483648 }, "disk": { "entries": 892, "size_bytes": 107374182400, "max_size_bytes": 536870912000 }}List cached entries:
GET /api/v1/cache/entriesGET /api/v1/cache/entries?domain=*.steamcontent.comGET /api/v1/cache/entries?limit=10&offset=0Response:
{ "entries": [ { "key": "ab12cd34...", "url": "http://cdn.steamcontent.com/depot/123/chunk/abc", "host": "cdn.steamcontent.com", "size": 1048576, "content_type": "application/octet-stream", "created_at": "2024-01-15T10:30:00Z", "expires_at": "2025-01-15T10:30:00Z" } ], "total": 892, "offset": 0, "limit": 10}Get single entry metadata:
GET /api/v1/cache/entries/{key}Delete single entry:
DELETE /api/v1/cache/entries/{key}Clear all cache:
DELETE /api/v1/cache/entries?confirm=truePurge entries for a domain:
DELETE /api/v1/cache/domain/{domain}List caching rules:
GET /api/v1/cache/rulesResponse:
{ "rules": [ { "name": "steam", "domains": ["*.steamcontent.com", "content*.steampowered.com"], "enabled": true, "ttl": "8760h0m0s", "priority": 100, "preset": "steam" } ]}Add custom rule:
POST /api/v1/cache/rulesContent-Type: application/json
{ "name": "my-cdn", "domains": ["cdn.example.com"], "enabled": true, "ttl": "168h", "priority": 50}Update rule:
PUT /api/v1/cache/rules/{name}Delete rule:
DELETE /api/v1/cache/rules/{name}List available presets:
GET /api/v1/cache/presetsResponse:
{ "presets": [ { "name": "steam", "description": "Steam game downloads and updates", "domains": ["*.steamcontent.com", "content*.steampowered.com"], "ttl": "8760h0m0s", "priority": 100 } ]}Enable/disable preset:
POST /api/v1/cache/presets/{name}Content-Type: application/json
{"enabled": true}PAC File (Proxy Auto-Configuration)
Section titled “PAC File (Proxy Auto-Configuration)”Bifrost automatically generates a PAC file based on your routing rules:
GET /proxy.pacGET /wpad.datThe PAC file contains JavaScript that browsers use for automatic proxy configuration. Example output:
function FindProxyForURL(url, host) { if (shExpMatch(host, "*.internal.company.com")) { return "PROXY bifrost.example.com:7080; DIRECT"; } return "DIRECT";}Using the PAC file:
- macOS: System Preferences → Network → Advanced → Proxies → Automatic Proxy Configuration
- Windows: Settings → Network → Proxy → Use setup script
- Firefox: Settings → Network Settings → Automatic proxy configuration URL
- Chrome: Uses system settings, or use Proxy SwitchyOmega extension
Client API
Section titled “Client API”Default: http://localhost:7383
Status
Section titled “Status”GET /api/v1/statusResponse:
{ "status": "running", "server_status": "connected", "time": "2024-01-01T00:00:00Z", "version": "1.0.0", "debug_entries": 150}Debug Entries
Section titled “Debug Entries”Get all debug entries:
GET /api/v1/debug/entriesGet last N entries:
GET /api/v1/debug/entries/last/100Clear entries:
DELETE /api/v1/debug/entriesGet errors only:
GET /api/v1/debug/errorsRoutes
Section titled “Routes”List routes:
GET /api/v1/routesTest a domain:
GET /api/v1/routes/test?domain=example.comResponse:
{ "domain": "example.com", "action": "server"}VPN Status
Section titled “VPN Status”Get VPN connection status:
GET /api/v1/vpn/statusResponse:
{ "status": "connected", "enabled": true, "tunnel_type": "WireGuard", "interface_name": "bifrost0", "local_ip": "10.0.0.2", "gateway": "10.0.0.1", "dns_servers": ["1.1.1.1", "8.8.8.8"], "mtu": 1420, "port": 51820, "encryption": "ChaCha20-Poly1305", "bytes_sent": 1048576, "bytes_received": 2097152, "connected_since": "2024-01-15T10:00:00Z"}Enable/Disable VPN
Section titled “Enable/Disable VPN”POST /api/v1/vpn/enablePOST /api/v1/vpn/disableResponse:
{ "status": "ok"}VPN Connections
Section titled “VPN Connections”Get active VPN connections:
GET /api/v1/vpn/connectionsResponse:
[ { "id": "conn-123", "remote_addr": "example.com:443", "local_addr": "10.0.0.2:54321", "protocol": "tcp", "started_at": "2024-01-15T10:00:00Z", "bytes_sent": 1024, "bytes_received": 2048 }]Split Tunnel Rules
Section titled “Split Tunnel Rules”Get split tunnel configuration:
GET /api/v1/vpn/split/rulesResponse:
{ "mode": "exclude", "apps": [ {"name": "Slack", "path": "/Applications/Slack.app"} ], "domains": ["*.local", "localhost"], "ips": ["192.168.0.0/16", "10.0.0.0/8"]}Add Split Tunnel App
Section titled “Add Split Tunnel App”POST /api/v1/vpn/split/appsContent-Type: application/json
{ "name": "Discord", "path": "/Applications/Discord.app"}Remove Split Tunnel App
Section titled “Remove Split Tunnel App”DELETE /api/v1/vpn/split/apps/{name}Add Split Tunnel Domain
Section titled “Add Split Tunnel Domain”POST /api/v1/vpn/split/domainsContent-Type: application/json
{ "pattern": "*.internal.company.com"}Add Split Tunnel IP
Section titled “Add Split Tunnel IP”POST /api/v1/vpn/split/ipsContent-Type: application/json
{ "cidr": "172.16.0.0/12"}Servers
Section titled “Servers”List available servers:
GET /api/v1/serversResponse:
[ { "id": "us-west", "name": "US West", "address": "us-west.example.com:7080", "protocol": "HTTP", "is_default": true, "latency_ms": 45, "status": "online" }]Select Server
Section titled “Select Server”POST /api/v1/servers/{id}/selectResponse:
{ "status": "ok"}WebSocket API
Section titled “WebSocket API”Real-time updates are available via WebSocket:
const ws = new WebSocket('ws://localhost:7082/api/v1/ws');
ws.onmessage = function(event) { const data = JSON.parse(event.data); console.log(data);};Events:
connection.new- New connection establishedconnection.close- Connection closedbackend.health- Backend health changedconfig.reload- Configuration reloaded