WebSocket API
Plain WebSocket, UTF-8 JSON frames on ws://<host>:1616. No SDK needed.
Connection
| Scenario | URL |
|---|---|
| No auth | ws://raspberrypi.local:1616 |
| With auth | ws://raspberrypi.local:1616?token=<ws-token> |
Authenticated Connection
With --auth enabled: POST /auth with the 6-digit code → GET /auth/ws-token → connect with ?token=....
const dashboardBase = "http://raspberrypi.local:1617";
const wsBase = "ws://raspberrypi.local:1616";
async function connectAuthenticated(code: string): Promise<WebSocket> {
await fetch(`${dashboardBase}/auth`, {
method: "POST",
headers: { "Content-Type": "application/json" },
credentials: "include",
body: JSON.stringify({ code }),
});
const { token } = await fetch(`${dashboardBase}/auth/ws-token`, {
credentials: "include",
}).then((r) => r.json());
return new WebSocket(`${wsBase}?token=${encodeURIComponent(token)}`);
}Commands (Client → Server)
Filter
{"cmd": "set_filter", "enabled": true, "lowcut": 1.0, "highcut": 40.0}
{"cmd": "set_filter", "enabled": false}Recording
{"cmd": "start_record"}
{"cmd": "stop_record"}Webhooks
{"cmd": "webhook_list"}
{"cmd": "webhook_create", "rule": {
"name": "Alpha alert",
"trigger_type": "band_power_above",
"params": {"band": "alpha", "threshold": 20},
"url": "https://example.com/hook",
"method": "POST",
"headers": {"Authorization": "Bearer ..."},
"cooldown": 30
}}
{"cmd": "webhook_update", "rule": {"id": "abc123", "enabled": false}}
{"cmd": "webhook_delete", "id": "abc123"}
{"cmd": "webhook_test", "id": "abc123"}VRChat OSC
{"cmd": "osc_start"}
{"cmd": "osc_stop"}
{"cmd": "osc_configure", "host": "127.0.0.1", "port": 9000, "mode": "both", "interval": 0.25}
{"cmd": "osc_status"}Lab Streaming Layer
{"cmd": "lsl_start"}
{"cmd": "lsl_stop"}
{"cmd": "lsl_status"}ADS1299 Registers
Real-time register configuration for PiEEG boards. See Register Configuration for full details.
{"cmd": "reg_read"}
{"cmd": "reg_write", "regs": {"0x05": "0x00", "0x06": "0x01"}}
{"cmd": "reg_preset", "preset": "internal_short"}
{"cmd": "noise_test", "duration": 3}Presets: normal, internal_short, test_signal, temp_sensor.
Messages (Server → Client)
EEG Frame
Sent at 250 Hz:
{"t": 1711234567.123, "n": 42, "channels": [12.34, -5.67, 8.90, ...]}Welcome Message
Sent on connect:
{
"status": "connected",
"sample_rate": 250,
"channels": 16,
"filter": false,
"recording": false
}The channels field reflects the selected device: 16 for pieeg16 (default), 8 for pieeg8 or ironbci8.
Record Status
{
"record_status": {
"recording": true,
"stopped": {
"filename": "pieeg_20260401_143136.csv",
"frames": 1000,
"duration": 4.0,
"path": "/path/to/file"
}
}
}Webhook Event
{
"webhook_event": {
"rule_id": "abc",
"value": 12.5,
"ts": 1711234567.123456
}
}