Real-time Updates (SSE)
Enterprise exposes Server-Sent Events (SSE) endpoints for receiving live record changes and AI response streams without polling. SSE uses a persistent HTTP connection where the server pushes data: lines to the client as events occur.
Data streaming — record changes
The Data module's StreamService pushes a change event every time a record is created, updated, or deleted, across any registered model.
Connect
GET /api/data/stream?models=contacts,accounts,opportunities
Accept: text/event-stream
Authorization: Bearer <access_token>
The models query parameter accepts a comma-separated list of model keys. Omit it to receive events for all models.
Event format
Each SSE event is a JSON object:
data: {"operation":"insert","model":"contacts","record":{"_id":"...","firstName":"Jane","lastName":"Smith",...}}
data: {"operation":"update","model":"opportunities","record":{"_id":"...","stage":"proposal",...}}
data: {"operation":"delete","model":"accounts","recordId":"..."}
| Field | Values | Description |
|---|---|---|
operation |
insert | update | delete |
Type of change |
model |
e.g. contacts |
Model key of the affected record |
record |
object | Full record (insert/update) or just recordId (delete) |
Browser example
const token = '<your_access_token>';
const url = '/api/data/stream?models=contacts,opportunities';
const source = new EventSource(url, {
// EventSource doesn't support custom headers natively — use a cookie session
// or a library like `eventsource` (Node) that supports Authorization headers.
});
source.onmessage = (event) => {
const { operation, model, record } = JSON.parse(event.data);
console.log(`${operation} on ${model}:`, record);
};
source.onerror = () => {
console.warn('SSE connection lost — will auto-reconnect');
};
Node.js / server-side example
import { EventSource } from 'eventsource'; // npm install eventsource
const source = new EventSource('https://your-instance.com/api/data/stream?models=contacts', {
headers: { Authorization: `Bearer ${token}` },
});
source.onmessage = ({ data }) => {
const event = JSON.parse(data);
// handle the change event
};
Reconnection
The browser's EventSource API reconnects automatically after a dropped connection using the retry: field sent by the server. The server sends this every 30 seconds to keep the connection alive.
AI chat streaming
The AI module's ChatStreamService streams language model responses token by token so your UI can render text progressively as it arrives.
Connect
POST /api/ai/chat/stream
Content-Type: application/json
Accept: text/event-stream
Authorization: Bearer <access_token>
{
"model": "claude-sonnet-4",
"message": "Summarise the top 5 open opportunities this quarter",
"accountKey": "your-account-key"
}
Note: This endpoint uses
POSTwith an SSE response. Usefetchwith aReadableStreamreader rather thanEventSource(which only supportsGET).
Event format
data: {"type":"text","text":"Here are "}
data: {"type":"text","text":"the top 5 "}
data: {"type":"text","text":"open opportunities..."}
data: [DONE]
Browser example
const response = await fetch('/api/ai/chat/stream', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`,
'Accept': 'text/event-stream',
},
body: JSON.stringify({ model: 'gpt-4o', message: 'Hello!', accountKey: 'acme' }),
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const lines = decoder.decode(value).split('\n');
for (const line of lines) {
if (!line.startsWith('data: ')) continue;
const payload = line.slice(6);
if (payload === '[DONE]') return;
const { text } = JSON.parse(payload);
process.stdout.write(text ?? '');
}
}
Tips
- Authentication: Data stream uses cookie-based sessions by default. If you need
Authorizationheader support, use a server-side proxy or theeventsourcenpm package. - Filtering: Always pass a
models=list to the data stream endpoint to avoid receiving events for every model in the system. - Abort: Pass an
AbortControllersignal tofetch()to cancel a stream cleanly when the user navigates away.