Skip to main content

Connection Details

WebSocket Endpoint

URL: wss://your-server-url/voice-stream

Audio Format Requirements

Sending (Mic → Server)

Raw PCM, 16,000 Hz, 16-bit Signed Little-Endian, Mono

Receiving (Server → Client)

Same format - PCM audio from the AI

Connection Flow

1

Open WebSocket

Connect to the WebSocket endpoint URL
2

Send Token

Immediately send your JWT token as a text message
3

Wait for Confirmation

Server sends savant_voice_connected when ready
4

Start Streaming

Begin bidirectional audio streaming

Message Types

Server → Client

Connection Confirmed:
{
  "type": "savant_voice_connected",
  "message": "Connection established"
}
Error Message:
{
  "type": "error",
  "error": {
    "message": "Error description",
    "code": "ERROR_CODE"
  }
}
Audio Data: Binary data containing PCM audio from AI

Client → Server

  • Token: String containing JWT
  • Audio: Binary PCM data from microphone

Implementation Example

websocket_connection.dart
class WebSocketManager {
  WebSocketChannel? _channel;
  StreamSubscription<dynamic>? _subscription;

  Future<void> connect(String token) async {
    // 1. Connect to WebSocket
    final wsUrl = '${dotenv.env['API_BASE_URL']}'
        .replaceFirst(RegExp(r'^http'), 'ws') + '/voice-stream';
    _channel = WebSocketChannel.connect(Uri.parse(wsUrl));

    // 2. Listen for messages
    _subscription = _channel!.stream.listen(
      _handleMessage,
      onError: _handleError,
      onDone: _handleDisconnection,
    );

    // 3. Send authentication token
    _channel!.sink.add(token);
  }

  void _handleMessage(dynamic message) {
    if (message is String) {
      final data = jsonDecode(message);
      if (data['type'] == 'vapi_connected') {
        // Start audio streaming
        _startAudioStreaming();
      }
    } else if (message is List<int>) {
      // Handle incoming audio
      _playAudioChunk(Uint8List.fromList(message));
    }
  }
}

Error Handling

Always implement proper error handling for connection issues, authentication failures, and unexpected disconnections.

Next Steps