Skip to main content

Overview

The WebSocket endpoint provides real-time notification delivery to connected clients. This connection-oriented approach minimizes latency and enables immediate user awareness of pending decisions.

Connection

Endpoint: WS /api/v1/client/stream
Authentication: Requires Bearer token using user credentials

Connection Query Parameters

ParameterTypeRequiredDescription
tokenstringYesUser authentication token (alternative to Authorization header)
client_idstringNoClient identifier for correlation (UUID recommended)
versionstringNoProtocol version for compatibility (defaults to latest)

Connection Example

const socket = new WebSocket('wss://atp.example.com/api/v1/client/stream?token=user_token_xyz789');

socket.onopen = () => {
  console.log('Connected to ATP notification stream');
};

socket.onmessage = (event) => {
  const message = JSON.parse(event.data);
  console.log('Received message:', message);
  
  // Process different message types
  switch (message.type) {
    case 'notification':
      handleNotification(message.data);
      break;
    case 'status_update':
      handleStatusUpdate(message.data);
      break;
    case 'heartbeat':
      // Respond to heartbeat to keep connection alive
      socket.send(JSON.stringify({ type: 'heartbeat_ack' }));
      break;
  }
};

socket.onerror = (error) => {
  console.error('WebSocket error:', error);
};

socket.onclose = (event) => {
  console.log('Connection closed:', event.code, event.reason);
  // Implement reconnection logic with exponential backoff
};

Message Types

Notification Event

When a new notification is available for the user, the server sends a notification event:
{
  "type": "notification",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "version": "1.0",
    "timestamp": "2025-05-25T10:30:00Z",
    "deadline": "2025-05-25T11:00:00Z",
    "service": {
      "id": "lovelace-ide",
      "name": "Lovelace IDE",
      "icon": "https://lovelace.dev/icon.png"
    },
    "context": {
      "title": "Deploy to Production?",
      "description": "New version 2.1.0 is ready for deployment to production servers.",
      "project": "backend-api",
      "metadata": {
        "version": "2.1.0",
        "changes": 47,
        "test_coverage": "98.3%"
      }
    },
    "actions": [
      {
        "id": "approve",
        "label": "Approve Deployment",
        "response_type": "simple",
        "flags": ["irreversible"]
      },
      {
        "id": "reject",
        "label": "Reject",
        "response_type": "text",
        "constraints": {
          "placeholder": "Reason for rejection"
        }
      }
    ]
  }
}

Status Update Event

When a notification’s status changes (e.g., it becomes invalidated), the server sends a status update event:
{
  "type": "status_update",
  "data": {
    "notification_id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "invalidated",
    "reason": "The deployment was canceled by the system",
    "timestamp": "2025-05-25T10:32:15Z"
  }
}

Heartbeat Event

The server sends periodic heartbeat events to keep the connection alive:
{
  "type": "heartbeat",
  "timestamp": "2025-05-25T10:31:00Z"
}
Clients should respond with a heartbeat acknowledgment:
{
  "type": "heartbeat_ack",
  "timestamp": "2025-05-25T10:31:00Z"
}

Error Event

When an error occurs that affects the WebSocket connection, the server may send an error event:
{
  "type": "error",
  "data": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Client has exceeded connection rate limit",
    "request_id": "req_abc123def456"
  }
}

Client Operations

Acknowledge Notification

Clients can acknowledge receipt of a notification to update its status to acknowledged:
{
  "type": "acknowledge",
  "notification_id": "550e8400-e29b-41d4-a716-446655440000",
  "timestamp": "2025-05-25T10:30:05Z"
}

Respond to Notification

While clients can respond to notifications via the WebSocket connection, it is recommended to use the Submit Response REST endpoint for better error handling and retry capabilities.

Reconnection Strategy

WebSocket connections may occasionally disconnect due to network issues, server maintenance, or other factors. Clients should implement a robust reconnection strategy with exponential backoff:
function connectWithRetry() {
  const MAX_RETRIES = 10;
  const BASE_DELAY_MS = 1000;
  let retryCount = 0;
  
  function connect() {
    const socket = new WebSocket('wss://atp.example.com/api/v1/client/stream?token=user_token_xyz789');
    
    socket.onopen = () => {
      console.log('Connected to ATP notification stream');
      retryCount = 0; // Reset retry counter on successful connection
    };
    
    socket.onclose = (event) => {
      if (retryCount < MAX_RETRIES) {
        // Calculate delay with exponential backoff and jitter
        const delay = Math.min(
          BASE_DELAY_MS * Math.pow(2, retryCount) + Math.random() * 1000, 
          60000 // Cap at 60 seconds
        );
        
        console.log(`Connection closed. Retrying in ${delay}ms...`);
        retryCount++;
        setTimeout(connect, delay);
      } else {
        console.error('Maximum retry attempts reached. Giving up.');
      }
    };
    
    // Add other event handlers as shown in previous examples
  }
  
  connect();
}

connectWithRetry();

Limitations

  • Maximum of 5 concurrent WebSocket connections per user
  • Heartbeat interval: 30 seconds
  • Connection timeout: 60 seconds of inactivity
  • Maximum message size: 1MB

Best Practices

  1. Implement Heartbeat: Always respond to heartbeat messages to keep the connection alive
  2. Handle Reconnection: Implement exponential backoff for reconnection attempts
  3. Manage Connection State: Keep track of connection state and avoid duplicate connections
  4. Fallback Strategy: Have a REST polling fallback for environments where WebSockets are not supported
  5. Efficient Rendering: Process and render notifications incrementally for large payloads
  6. Rate Limiting Awareness: Be mindful of connection attempt rate limits
I