Skip to content

Streaming endpoints

Server-Sent Events (SSE) for desktop status updates and mission control activity streams.

3 min read

SSE overview

Le Bureau uses Server-Sent Events (SSE) to push real-time updates to your application. Unlike WebSockets, SSE is a one-way protocol -- the server pushes events to your client over a long-lived HTTP connection. The connection auto-reconnects if it drops.

There are two SSE endpoints:

EndpointPurpose
GET /api/desktops/streamDesktop status changes (started, stopped, metrics)
GET /api/mission-control/activity/streamTask and approval events across all desktops

Desktop status stream

GET /api/desktops/stream

Pushes status updates for all desktops belonging to the authenticated user.

Event format:

{
  "type": "desktop.status",
  "payload": {
    "id": "clx...",
    "name": "my-agent",
    "status": "running",
    "ipAddress": "10.0.3.42",
    "cpu": 23.5,
    "memory": 45.2
  }
}

Event types:

TypeDescription
desktop.statusDesktop status changed (booting, running, stopped, error)
desktop.metricsUpdated CPU/RAM/disk numbers
desktop.agentReadyAgent finished initializing and is ready for tasks

Activity stream

GET /api/mission-control/activity/stream

Pushes events for tasks, approvals, and desktop activity across your account.

Event format:

{
  "type": "task.completed",
  "payload": {
    "taskId": "task_abc123",
    "desktopId": "clx...",
    "status": "done",
    "completedAt": "2026-03-15T10:05:00Z"
  }
}

See Activity monitoring for the full list of event types.

Consuming SSE in JavaScript

Browser (EventSource API)

// With session cookie (logged in user)
const stream = new EventSource('/api/desktops/stream');

stream.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('Event:', data.type, data.payload);
};

stream.onerror = (err) => {
  console.log('SSE error, will auto-reconnect:', err);
};

// Clean up when done
stream.close();

The native EventSource API does not support custom headers. If you need to use an API key instead of a session cookie, pass it as a query parameter:

const stream = new EventSource(
  '/api/mission-control/activity/stream?apiKey=lb_k_abc123...'
);

Node.js (fetch-based)

For server-side consumption, use the Fetch API with streaming:

const response = await fetch('https://lebureau.talentai.fr/api/desktops/stream', {
  headers: { 'x-api-key': 'lb_k_abc123...' }
});

const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  const text = decoder.decode(value);
  // SSE format: "data: {...}\n\n"
  const lines = text.split('\n');
  for (const line of lines) {
    if (line.startsWith('data: ')) {
      const data = JSON.parse(line.slice(6));
      console.log('Event:', data.type, data.payload);
    }
  }
}

Python

import requests
import json

response = requests.get(
    'https://lebureau.talentai.fr/api/desktops/stream',
    headers={'x-api-key': 'lb_k_abc123...'},
    stream=True
)

for line in response.iter_lines():
    if line:
        decoded = line.decode('utf-8')
        if decoded.startswith('data: '):
            data = json.loads(decoded[6:])
            print(f"Event: {data['type']}", data['payload'])

Reconnection

SSE has built-in reconnection. If the connection drops:

  • The browser EventSource API reconnects automatically after a short delay
  • The server sends an id field with each event -- on reconnection, the browser sends Last-Event-ID so the server can replay missed events

For custom clients (Node.js, Python), implement reconnection logic in your error handler:

function connect() {
  const stream = new EventSource('/api/desktops/stream');
  stream.onerror = () => {
    stream.close();
    setTimeout(connect, 5000); // Reconnect after 5 seconds
  };
  stream.onmessage = (event) => {
    // Handle event
  };
}
connect();

Notes

  • SSE connections are lightweight. Keep them open for the duration of your monitoring session.
  • The desktop stream is useful for live dashboards showing fleet status.
  • The activity stream works well for automated workflows, like sending a Slack notification when a task fails.
  • SSE connections count toward the rate limit only at connection time, not per event.