Server-Sent Events (SSE)

Serveka provides a real-time event stream for each bot using Server-Sent Events (SSE). This allows you to receive transcript segments, status changes, participant updates, and more as they happen during a meeting.

How SSE works

  1. Get the stream URL and token
    Call POST /api/v1/bots/{bot_id}/subscribe to obtain a stream URL and a short-lived JWT token.

  2. Connect to the stream
    Open an EventSource connection to the URL with the token in the Authorization header.

  3. Receive events
    The stream sends named events (e.g., transcript_segment, bot_status) as JSON payloads.

Step-by-step example

1. Get the stream URL and token

bash
curl -X POST https://api.serveka.com/api/v1/bots/550e8400-e29b-41d4-a716-446655440000/subscribe \
  -H "X-API-Key: srvk_your_key_here"

Response 200:

json
{
  "url": "https://stream.serveka.com/sse/550e8400-e29b-41d4-a716-446655440000",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

2. Connect to the SSE stream

javascript
const eventSource = new EventSource(url, {
  headers: { Authorization: `Bearer ${token}` }
});
 
// Handle incoming events
eventSource.addEventListener('transcript_segment', (e) => {
  const segment = JSON.parse(e.data);
  console.log(`[${segment.speaker}]: ${segment.text}`);
});
 
eventSource.addEventListener('bot_status', (e) => {
  const event = JSON.parse(e.data);
  console.log(`Bot status changed to: ${event.status}`);
});
 
eventSource.addEventListener('participant_update', (e) => {
  const event = JSON.parse(e.data);
  console.log('Current participants:', event.participants);
});
 
// Handle errors
eventSource.onerror = (err) => {
  console.error('SSE error:', err);
  eventSource.close();
};

3. Event types

EventPayloadDescription
transcript_segment{ speaker, text, timestamp, is_final }A transcription chunk. is_final indicates the segment is complete.
bot_status{ status, timestamp }The bot's status has changed (e.g., active, completed).
participant_update{ participants: string[] }The list of participants in the meeting has changed.
action_detected{ action_type, data }An LLM action was triggered (if enabled).
recording_ready{ recording_url }The recording has finished uploading and is ready for download.

4. Keeping the connection alive

  • The SSE connection should remain open for the duration of the meeting.
  • The stream automatically closes when the bot leaves the meeting.
  • If the connection drops, you can reconnect by calling POST /subscribe again to get a fresh URL and token.
  • Events are buffered for 30 seconds to allow for brief reconnects.

Best practices

  • Always verify the token on the server side if you're proxying the connection.
  • Handle errors gracefully by checking the onerror event and attempting to reconnect.
  • Process events asynchronously to avoid blocking the event loop.
  • Close the connection when the bot reaches a terminal state (completed or failed) if you no longer need updates.

Alternative: Webhooks

If you prefer to receive events via HTTP POST instead of maintaining a persistent connection, consider using Webhooks. Webhooks are better suited for infrequent, reliable delivery of events (e.g., meeting completion), while SSE is ideal for real-time, high-volume data like transcript segments.

Updated May 2026Edit on GitHub