WebSocket Events
Connecting
Section titled “Connecting”wss://panel.example.com/ws/v1/eventsAuthenticate with a session cookie (browser) or pass a token as a query param:
wss://panel.example.com/ws/v1/events?token=tnd_prod_<token>Subscribing to channels
Section titled “Subscribing to channels”Send a JSON subscribe message after connecting:
{ "type": "subscribe", "channels": [ "deployment:01j4k...", "site:01j4k...:logs", "server:01j4k...:metrics" ]}Response:
{ "type": "subscribed", "channels": ["deployment:01j4k..."] }Event types
Section titled “Event types”Deployment events
Section titled “Deployment events”Channel: deployment:{id}
{ "channel": "deployment:01j4k...", "event": "deployment.stage_changed", "data": { "deployment_id": "01j4k...", "stage": "symlink-swap", "status": "running" }}{ "event": "deployment.completed", "data": { "deployment_id": "...", "duration_ms": 4200 }}Site log streaming
Section titled “Site log streaming”Channel: site:{id}:logs
{ "channel": "site:01j4k...:logs", "event": "log.line", "data": { "stream": "access", "line": "192.168.1.1 - - [09/May/2026] \"GET / HTTP/2\" 200 1234" }}Server metrics
Section titled “Server metrics”Channel: server:{id}:metrics
{ "channel": "server:01j4k...:metrics", "event": "metrics.snapshot", "data": { "cpu_pct": 12.4, "ram_used_mb": 1024, "disk_used_gb": 45.2, "ts": "2026-05-09T12:00:00Z" }}Unsubscribing
Section titled “Unsubscribing”{ "type": "unsubscribe", "channels": ["deployment:01j4k..."] }Heartbeat
Section titled “Heartbeat”The server sends a ping every 30 seconds. The client must respond with a pong (most WebSocket libraries do this automatically). Connections idle for 90 seconds are closed.