Streaming endpoints
Server-Sent Events (SSE) for desktop status updates and mission control activity streams.
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:
| Endpoint | Purpose |
|---|---|
GET /api/desktops/stream | Desktop status changes (started, stopped, metrics) |
GET /api/mission-control/activity/stream | Task 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:
| Type | Description |
|---|---|
desktop.status | Desktop status changed (booting, running, stopped, error) |
desktop.metrics | Updated CPU/RAM/disk numbers |
desktop.agentReady | Agent 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
EventSourceAPI reconnects automatically after a short delay - The server sends an
idfield with each event -- on reconnection, the browser sendsLast-Event-IDso 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.