WebSocket Connection
Connect to the Nexgent WebSocket API to receive real-time position and price updates.
Overview
The WebSocket API provides real-time updates for:
- Position changes - When positions are created, updated, or closed
- Price updates - Live token price feeds for open positions
- Connection status - Heartbeat/ping-pong for connection health
The WebSocket server runs on the same port as the HTTP API, using the /ws path.
Connection URL
ws://your-instance.com/ws?token=<jwt_token>&agentId=<agent_id>Or with TLS:
wss://your-instance.com/ws?token=<jwt_token>&agentId=<agent_id>Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
token | string | Yes | Valid JWT access token |
agentId | UUID | Yes | Agent ID to receive updates for |
URL Construction
function getWebSocketUrl(apiUrl, token, agentId) {
// Convert http:// to ws:// or https:// to wss://
const wsUrl = apiUrl.replace(/^http/, 'ws');
return `${wsUrl}/ws?token=${encodeURIComponent(token)}&agentId=${encodeURIComponent(agentId)}`;
}
// Example
const url = getWebSocketUrl(
'https://your-instance.com',
'eyJhbGciOiJIUzI1NiIs...',
'550e8400-e29b-41d4-a716-446655440000'
);
// wss://your-instance.com/ws?token=eyJhbGc...&agentId=550e8400...Authentication
WebSocket connections authenticate via JWT token passed in the URL query string.
Authentication Flow
1. Client obtains JWT access token (via /api/v1/auth/login)
2. Client connects to WebSocket with token in URL
ws://host/ws?token=<jwt>&agentId=<id>
3. Server validates:
- Token signature and expiration
- Token type is 'access' (not refresh)
- Agent belongs to the authenticated user
4. On success: Server sends 'connected' message
On failure: Server closes connection with error codeConnection Errors
| Code | Reason | Description |
|---|---|---|
| 1008 | Missing authentication | No token or agentId provided |
| 1008 | Authentication failed | Invalid or expired token |
| 1008 | Agent not found | Agent doesn't exist or belongs to different user |
| 1011 | Internal server error | Server-side error during connection |
Connection Lifecycle
Opening Connection
const ws = new WebSocket(url);
ws.onopen = () => {
console.log('WebSocket connection opened');
// Wait for 'connected' message to confirm authentication
};Connection Confirmed
After successful authentication, the server sends a connected message:
{
"type": "connected",
"data": {
"agentId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2025-01-20T10:30:00.000Z"
}
}Initial Data
Immediately after connection, the server sends an initial_data message with all current positions:
{
"type": "initial_data",
"data": {
"positions": [...],
"timestamp": "2025-01-20T10:30:00.000Z"
}
}Closing Connection
// Clean close
ws.close(1000, 'User disconnect');
// The server will also close connections if:
// - Token expires
// - No pong response to ping within 60 seconds
// - Server shutdownKeep-Alive (Ping/Pong)
The server sends periodic ping messages every 30 seconds. Clients must respond with pong to maintain the connection.
Server Ping
{
"type": "ping",
"timestamp": "2025-01-20T10:30:00.000Z"
}Client Pong Response
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
if (message.type === 'ping') {
ws.send(JSON.stringify({
type: 'pong',
timestamp: new Date().toISOString()
}));
}
};Connection Timeout
| Condition | Timeout |
|---|---|
| No pong response | 60 seconds (2 ping cycles) |
| Connection considered stale | Connection closed |
If your client doesn't respond to ping messages, the connection will be closed after ~60 seconds.
One Connection Per Agent
Each agent can have only one active WebSocket connection at a time.
If a new connection is established for an agent that already has a connection:
- The existing connection is closed with code
1000and reason "New connection established" - The new connection becomes active
// If user opens app in a new tab with same agent:
// - Old tab's connection: closed
// - New tab's connection: activeReconnection Strategy
Implement automatic reconnection for production apps:
class WebSocketManager {
constructor(url) {
this.url = url;
this.reconnectAttempts = 0;
this.maxReconnectAttempts = 5;
this.reconnectInterval = 5000; // 5 seconds
}
connect() {
this.ws = new WebSocket(this.url);
this.ws.onclose = (event) => {
// Don't reconnect on clean close
if (event.code === 1000) return;
// Exponential backoff
if (this.reconnectAttempts < this.maxReconnectAttempts) {
const delay = this.reconnectInterval * Math.pow(1.5, this.reconnectAttempts);
console.log(`Reconnecting in ${delay}ms...`);
setTimeout(() => {
this.reconnectAttempts++;
this.connect();
}, delay);
} else {
console.error('Max reconnection attempts reached');
}
};
this.ws.onopen = () => {
this.reconnectAttempts = 0; // Reset on successful connection
};
}
disconnect() {
if (this.ws) {
this.ws.close(1000, 'Manual disconnect');
}
}
}