WebSocket event playground¶
The VeriOps WebSocket API provides real-time, bidirectional communication for project updates and task notifications over a persistent connection. This playground allows you to connect, subscribe to channels, send messages, and observe server-pushed events.
Connection details¶
| Setting | Value |
|---|---|
| Endpoint | wss://api.veriops.example/realtime |
| Authentication | Bearer token as token query parameter |
| Protocol | WebSocket (RFC 6455) over TLS 1.3 |
| Heartbeat interval | 30 seconds (server sends ping, client responds pong) |
| Reconnect strategy | Exponential backoff: 1 second, 2 seconds, 4 seconds, 8 seconds, 16 seconds, max 30 seconds |
| Max message size | 64 KB |
| Idle timeout | 300 seconds (5 minutes) without messages |
| Max subscriptions per connection | 50 channels |
| Compression | permessage-deflate supported |
Message envelope¶
Every client-to-server and server-to-client message uses this JSON envelope:
{
"type": "subscribe",
"request_id": "req_001",
"sent_at": "2026-03-19T14:30:00Z",
"payload": {
"channel": "project.updated",
"filters": {"project_id": "prj_abc123"}
}
}
Envelope fields¶
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | Yes | Message type: subscribe, unsubscribe, publish, ping, ack, event |
request_id |
string | Yes | Client-generated ID for request/response correlation |
sent_at |
string (ISO 8601) | No | Timestamp when the message was sent |
payload |
object | Varies | Message-specific data |
Message types¶
| Type | Direction | Description |
|---|---|---|
subscribe |
Client to server | Subscribe to a channel with optional filters |
unsubscribe |
Client to server | Unsubscribe from a channel |
publish |
Client to server | Send a message to a channel |
ping |
Bidirectional | Heartbeat ping (server sends every 30 seconds) |
pong |
Client to server | Response to server ping |
ack |
Server to client | Acknowledgment of a client request |
event |
Server to client | Channel event pushed by the server |
Channel catalog¶
| Channel | Direction | Filters | Description |
|---|---|---|---|
project.updated |
Server to client | project_id (optional) |
Project status change events |
project.created |
Server to client | -- | New project creation events |
task.completed |
Server to client | project_id (optional) |
Task completion notifications |
presence |
Bidirectional | -- | User online/offline status |
Quick start: connect and subscribe¶
Step 1: establish connection¶
// Connect to the VeriOps WebSocket API
// Pass your API key as a query parameter for authentication
const ws = new WebSocket('wss://api.veriops.example/realtime?token=YOUR_API_KEY');
ws.addEventListener('open', () => {
console.log('Connected to VeriOps WebSocket API');
});
ws.addEventListener('close', (event) => {
console.log('Disconnected:', event.code, event.reason);
});
Step 2: subscribe to a channel¶
// Subscribe to project update events for a specific project
ws.send(JSON.stringify({
type: 'subscribe',
request_id: 'req_001',
sent_at: new Date().toISOString(),
payload: {
channel: 'project.updated',
filters: { project_id: 'prj_abc123' }
}
}));
Step 3: handle incoming events¶
ws.addEventListener('message', (event) => {
const msg = JSON.parse(event.data);
switch (msg.type) {
case 'ack':
console.log('Subscription confirmed:', msg.request_id);
break;
case 'event':
console.log('Event received:', msg.payload.event_type);
console.log('Project:', msg.payload.data.project_id);
console.log('Status:', msg.payload.data.status);
break;
case 'ping':
ws.send(JSON.stringify({ type: 'pong', request_id: msg.request_id }));
break;
}
});
Complete client example with reconnection¶
// Production-ready WebSocket client with automatic reconnection
// Handles heartbeats, subscription restoration, and exponential backoff
class VeriOpsWebSocket {
constructor(apiKey) {
this.apiKey = apiKey;
this.endpoint = 'wss://api.veriops.example/realtime';
this.subscriptions = new Set();
this.reconnectDelay = 1000;
this.maxReconnectDelay = 30000;
this.connect();
}
connect() {
this.ws = new WebSocket(`${this.endpoint}?token=${this.apiKey}`);
this.ws.onopen = () => {
console.log('Connected');
this.reconnectDelay = 1000;
// Restore subscriptions after reconnect
for (const channel of this.subscriptions) {
this.subscribe(channel);
}
};
this.ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === 'ping') {
this.ws.send(JSON.stringify({ type: 'pong', request_id: msg.request_id }));
} else if (msg.type === 'event') {
this.handleEvent(msg.payload);
}
};
this.ws.onclose = () => {
console.log(`Reconnecting in ${this.reconnectDelay}ms...`);
setTimeout(() => this.connect(), this.reconnectDelay);
this.reconnectDelay = Math.min(this.reconnectDelay * 2, this.maxReconnectDelay);
};
}
subscribe(channel) {
this.subscriptions.add(channel);
if (this.ws.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify({
type: 'subscribe',
request_id: `req_${Date.now()}`,
payload: { channel }
}));
}
}
handleEvent(payload) {
console.log(`[${payload.event_type}] ${JSON.stringify(payload.data)}`);
}
}
// Usage:
const client = new VeriOpsWebSocket('YOUR_API_KEY');
client.subscribe('project.updated');
client.subscribe('task.completed');
Interactive WebSocket tester¶
Connect to the sandbox WebSocket endpoint, subscribe to channels, and send messages from the browser.
Sandbox mode
The endpoint field below auto-fills with a public WebSocket echo sandbox URL. No API key is required for sandbox requests.
Not connected
Error handling¶
WebSocket close codes¶
| Close code | Meaning | Client action |
|---|---|---|
| 1000 | Normal closure | No action required |
| 1001 | Server going away | Reconnect with exponential backoff |
| 1006 | Abnormal close (no close frame) | Reconnect with exponential backoff |
| 1008 | Policy violation | Check message format and size |
| 4001 | Authentication failed | Verify your API key is valid and not expired |
| 4002 | Subscription limit reached | Unsubscribe from unused channels (max 50) |
| 4008 | Rate limited | Wait 60 seconds before reconnecting |
| 4009 | Message too large | Reduce message size to under 64 KB |
Common issues¶
| Symptom | Cause | Resolution |
|---|---|---|
| Connection drops every 30 seconds | Client not responding to ping |
Implement pong response handler |
| Connection drops after 5 minutes | No messages sent or received | Send periodic messages or respond to pings |
Connection error in browser |
Mixed content (ws:// on HTTPS page) |
Use wss:// endpoint |
| Missed events after reconnect | Subscriptions not restored | Re-subscribe to all channels on open event |
Next steps¶
- AsyncAPI event docs for message broker patterns with AMQP
- REST API reference for synchronous CRUD operations
- Quality evidence for pipeline gate results