Skip to main content

WebSocket API

Receive real-time updates for bans, server status, and other events via WebSocket.

Connection

Endpoint

wss://bloqd.example.com/ws

Authentication

Include the API key or JWT token in the connection:

Via Query Parameter:

wss://bloqd.example.com/ws?token=f2b_your_api_key

Via Header (when client supports):

const ws = new WebSocket('wss://bloqd.example.com/ws', [], {
headers: {
'Authorization': 'Bearer f2b_your_api_key'
}
});

Message Format

All messages are JSON-encoded:

{
"type": "event_type",
"data": { ... },
"timestamp": "2024-01-15T10:30:00Z"
}

Event Types

ban

Triggered when an IP is banned.

{
"type": "ban",
"data": {
"id": 12345,
"ip": "192.168.1.100",
"jail": "sshd",
"server": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"hostname": "web-server-01"
},
"country": "CN",
"log_lines": "Failed password for root..."
},
"timestamp": "2024-01-15T10:30:00Z"
}

unban

Triggered when an IP is unbanned.

{
"type": "unban",
"data": {
"ip": "192.168.1.100",
"jail": "sshd",
"server": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"hostname": "web-server-01"
},
"reason": "ban_expired"
},
"timestamp": "2024-01-15T11:30:00Z"
}

server_status

Triggered when server status changes.

{
"type": "server_status",
"data": {
"server": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"hostname": "web-server-01"
},
"status": "offline",
"previous_status": "online",
"last_heartbeat": "2024-01-15T10:25:00Z"
},
"timestamp": "2024-01-15T10:30:00Z"
}

server_metrics

Periodic server metrics update.

{
"type": "server_metrics",
"data": {
"server": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"hostname": "web-server-01"
},
"metrics": {
"cpu_percent": 25.5,
"memory_percent": 60.2,
"disk_percent": 45.0
}
},
"timestamp": "2024-01-15T10:30:00Z"
}

command_result

Triggered when a remote command completes.

{
"type": "command_result",
"data": {
"command_id": "cmd-abc123",
"type": "ban-ip",
"status": "completed",
"result": {
"success": true,
"output": "IP banned successfully"
},
"server": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"hostname": "web-server-01"
}
},
"timestamp": "2024-01-15T10:30:05Z"
}

whitelist_update

Triggered when whitelist is modified.

{
"type": "whitelist_update",
"data": {
"action": "add",
"entry": {
"id": 16,
"ip": "203.0.113.100",
"description": "New entry"
},
"user": "admin"
},
"timestamp": "2024-01-15T10:30:00Z"
}

sync_complete

Triggered when whitelist sync completes.

{
"type": "sync_complete",
"data": {
"server": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"hostname": "web-server-01"
},
"status": "success",
"entries_synced": 15
},
"timestamp": "2024-01-15T10:30:00Z"
}

Subscribing to Events

Subscribe

Send a subscribe message to filter events:

{
"action": "subscribe",
"events": ["ban", "unban", "server_status"]
}

Response:

{
"type": "subscribed",
"events": ["ban", "unban", "server_status"]
}

Subscribe to Specific Server

{
"action": "subscribe",
"events": ["ban", "server_metrics"],
"server_id": "550e8400-e29b-41d4-a716-446655440000"
}

Unsubscribe

{
"action": "unsubscribe",
"events": ["server_metrics"]
}

Heartbeat

The server sends periodic pings:

{
"type": "ping",
"timestamp": "2024-01-15T10:30:00Z"
}

Respond with:

{
"action": "pong"
}

Connections that don't respond to pings within 30 seconds are closed.

Connection States

StateDescription
connectingWebSocket handshake in progress
openConnection established
closingConnection is being closed
closedConnection closed

Error Messages

{
"type": "error",
"data": {
"code": "AUTH_FAILED",
"message": "Invalid or expired token"
}
}

Error Codes

CodeDescription
AUTH_FAILEDAuthentication failed
INVALID_MESSAGEMalformed message
SUBSCRIPTION_ERRORInvalid subscription request
RATE_LIMITEDToo many messages

Code Examples

JavaScript

const ws = new WebSocket('wss://bloqd.example.com/ws?token=f2b_your_api_key');

ws.onopen = () => {
console.log('Connected');

// Subscribe to events
ws.send(JSON.stringify({
action: 'subscribe',
events: ['ban', 'server_status']
}));
};

ws.onmessage = (event) => {
const message = JSON.parse(event.data);

switch (message.type) {
case 'ban':
console.log('New ban:', message.data);
break;
case 'server_status':
console.log('Server status:', message.data);
break;
case 'ping':
ws.send(JSON.stringify({ action: 'pong' }));
break;
}
};

ws.onclose = () => {
console.log('Disconnected');
};

Python

import asyncio
import websockets
import json

async def connect():
uri = "wss://bloqd.example.com/ws?token=f2b_your_api_key"

async with websockets.connect(uri) as ws:
# Subscribe
await ws.send(json.dumps({
"action": "subscribe",
"events": ["ban", "server_status"]
}))

async for message in ws:
data = json.loads(message)

if data["type"] == "ping":
await ws.send(json.dumps({"action": "pong"}))
elif data["type"] == "ban":
print(f"New ban: {data['data']}")
elif data["type"] == "server_status":
print(f"Server status: {data['data']}")

asyncio.run(connect())

Rate Limits

LimitValue
Max connections per API key5
Max subscriptions per connection20
Max messages per minute60

Best Practices

  1. Handle reconnection - Implement exponential backoff
  2. Respond to pings - Keep connection alive
  3. Subscribe selectively - Only subscribe to needed events
  4. Handle errors gracefully - Log and recover from errors
  5. Use secure connections - Always use wss://