Skip to main content

Overview

Learn how to establish secure WebSocket connections to the Live API. The API uses JWT authentication for secure access and provides immediate session management for real-time audio transcription.
Secure Authentication: All connections require valid JWT tokens for authentication and authorization.

Connection Endpoint

Base URL: ws://localhost:8000/ws/transcribe Protocol: WebSocket Authentication: JWT token required

Authentication Methods

const jwtToken = 'your-jwt-token-here';

const ws = new WebSocket('ws://localhost:8000/ws/transcribe', [], {
  headers: {
    'Authorization': `Bearer ${jwtToken}`
  }
});

ws.onopen = () => {
  console.log('Connected with JWT authentication');
};

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);
  console.log('Received:', message);
};

ws.onerror = (error) => {
  console.error('Connection error:', error);
};

Method 2: Query Parameter

const jwtToken = 'your-jwt-token-here';
const ws = new WebSocket(`ws://localhost:8000/ws/transcribe?token=${jwtToken}`);

ws.onopen = () => {
  console.log('Connected via query parameter');
};

JWT Token Requirements

Token Structure

Your JWT token must include the following claims:
{
  "sub": "user-id-123",
  "iat": 1703123456,
  "exp": 1703209856,
  "scope": "transcription:read transcription:write",
  "user_type": "doctor"
}

Token Validation

Server Validation

  • Signature: Verifies token signature
  • Expiration: Checks token is not expired
  • Claims: Validates required claims exist
  • Scope: Ensures transcription permissions

Security Features

  • Algorithm: HS256 or RS256 supported
  • Issuer Validation: Verifies token issuer
  • Audience Check: Validates intended audience
  • Revocation: Supports token blacklisting

Connection Flow

1

Prepare JWT Token

Obtain a valid JWT token with transcription permissions
const token = await getJWTToken(); // Your auth service
2

Initiate Connection

Connect to WebSocket endpoint with authentication
const ws = new WebSocket('ws://localhost:8000/ws/transcribe', [], {
  headers: { 'Authorization': `Bearer ${token}` }
});
3

Handle Authentication

Server validates token and establishes connection
ws.onopen = () => {
  console.log('Authentication successful');
};
4

Receive Session ID

Get unique session identifier for your transcription session
{
  "type": "session_init",
  "session_id": "550e8400-e29b-41d4-a716-446655440000"
}
5

Start Audio Streaming

Begin sending binary audio data
ws.send(audioBuffer); // Binary audio data

Connection Management

Basic Connection Handler

class LiveAPIConnection {
  constructor(jwtToken) {
    this.token = jwtToken;
    this.ws = null;
    this.sessionId = null;
    this.reconnectAttempts = 0;
    this.maxReconnectAttempts = 5;
  }
  
  connect() {
    try {
      this.ws = new WebSocket('ws://localhost:8000/ws/transcribe', [], {
        headers: {
          'Authorization': `Bearer ${this.token}`
        }
      });
      
      this.ws.onopen = this.handleOpen.bind(this);
      this.ws.onmessage = this.handleMessage.bind(this);
      this.ws.onclose = this.handleClose.bind(this);
      this.ws.onerror = this.handleError.bind(this);
      
    } catch (error) {
      console.error('Connection failed:', error);
    }
  }
  
  handleOpen() {
    console.log('Connected to Live API');
    this.reconnectAttempts = 0;
  }
  
  handleMessage(event) {
    const message = JSON.parse(event.data);
    
    switch (message.type) {
      case 'session_init':
        this.sessionId = message.session_id;
        console.log('Session ID:', this.sessionId);
        this.onSessionInit(message);
        break;
        
      case 'transcription':
        this.onTranscription(message);
        break;
        
      case 'warning':
        this.onWarning(message);
        break;
    }
  }
  
  handleClose(event) {
    console.log('Connection closed:', event.code, event.reason);
    
    if (event.code === 1006 && this.reconnectAttempts < this.maxReconnectAttempts) {
      this.reconnect();
    }
  }
  
  handleError(error) {
    console.error('WebSocket error:', error);
  }
  
  reconnect() {
    this.reconnectAttempts++;
    const delay = Math.pow(2, this.reconnectAttempts) * 1000; // Exponential backoff
    
    console.log(`Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts})`);
    
    setTimeout(() => {
      this.connect();
    }, delay);
  }
  
  sendAudio(audioBuffer) {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(audioBuffer);
    }
  }
  
  disconnect() {
    if (this.ws) {
      this.ws.close();
    }
  }
  
  // Override these methods in your implementation
  onSessionInit(message) {
    // Handle session initialization
  }
  
  onTranscription(message) {
    // Handle transcription results
  }
  
  onWarning(message) {
    // Handle warnings
  }
}

// Usage
const connection = new LiveAPIConnection('your-jwt-token');
connection.connect();

Authentication Error Handling

Common Authentication Errors

Cause: JWT token is malformed, invalid signature, or missing required claimsSolution:
ws.onclose = (event) => {
  if (event.code === 1002) { // Protocol error (auth failed)
    console.error('Authentication failed - check your JWT token');
    // Refresh token and reconnect
    refreshTokenAndReconnect();
  }
};
Cause: JWT token has expiredSolution:
// Implement token refresh logic
async function refreshTokenAndReconnect() {
  try {
    const newToken = await refreshJWTToken();
    const newConnection = new LiveAPIConnection(newToken);
    newConnection.connect();
  } catch (error) {
    console.error('Token refresh failed:', error);
  }
}
Cause: JWT token doesn’t have required transcription permissionsSolution:
// Ensure token has required scopes
const requiredScopes = ['transcription:read', 'transcription:write'];
// Contact your auth service to update token permissions
Cause: Too many concurrent connections or requestsSolution:
ws.onclose = (event) => {
  if (event.code === 1013) { // Try again later
    setTimeout(() => {
      reconnect();
    }, 30000); // Wait 30 seconds before reconnecting
  }
};

Best Practices

Security Best Practices

1

Token Storage

Store JWT tokens securely and never expose them in client-side code
2

Token Refresh

Implement automatic token refresh before expiration
3

Error Handling

Handle authentication errors gracefully with proper user feedback
4

Connection Limits

Respect rate limits and avoid unnecessary reconnections
5

Secure Transport

Use WSS (WebSocket Secure) in production environments

Performance Optimization

Connection Pooling

  • Reuse Connections: Avoid frequent connect/disconnect
  • Session Management: Maintain session state
  • Resource Cleanup: Properly close connections
  • Load Balancing: Distribute connections across servers

Error Recovery

  • Exponential Backoff: Gradual reconnection delays
  • Circuit Breaker: Stop reconnecting after repeated failures
  • Health Checks: Monitor connection status
  • Fallback Strategy: Alternative connection methods

Testing Connections

Connection Testing

async function testConnection() {
  const token = 'your-test-jwt-token';
  
  try {
    const ws = new WebSocket('ws://localhost:8000/ws/transcribe', [], {
      headers: {
        'Authorization': `Bearer ${token}`
      }
    });
    
    ws.onopen = () => {
      console.log('✅ Connection successful');
      ws.close();
    };
    
    ws.onerror = (error) => {
      console.error('❌ Connection failed:', error);
    };
    
    ws.onclose = (event) => {
      if (event.code === 1000) {
        console.log('✅ Clean disconnection');
      } else {
        console.error(`❌ Connection closed with code: ${event.code}`);
      }
    };
    
  } catch (error) {
    console.error('❌ Connection error:', error);
  }
}

// Run test
testConnection();

Next Steps