SSE Streaming
urelay provides a Server-Sent Events (SSE) endpoint for real-time message delivery without polling.
How it works
The SSE endpoint maintains a persistent HTTP connection. When a new message arrives or a typing indicator changes, the server pushes the event to all connected clients instantly via Redis pub/sub.
This is different from webhooks -- SSE is designed for browser-based clients and real-time UIs, while webhooks are for server-to-server integrations.
Connecting
const eventSource = new EventSource(
'https://app.urelay.ai/api/client/messages/stream?chat=%2B12025551234'
);
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'connected') {
console.log('SSE connected');
}
if (data.type === 'messages') {
// New message(s) arrived
for (const msg of data.messages) {
console.log(`${msg.handle}: ${msg.text}`);
}
}
if (data.type === 'typing') {
// Typing indicator changed
console.log(`${data.chatIdentifier} typing: ${data.active}`);
}
};
eventSource.onerror = () => {
console.log('SSE disconnected, will reconnect automatically');
};
Query parameters
| Parameter | Description |
|---|---|
chat | Filter events to a specific chat identifier (phone number). If omitted, receives events for all conversations. |
Event types
connected
Sent immediately when the SSE connection is established.
{"type": "connected"}
messages
Sent when one or more new messages arrive.
{
"type": "messages",
"messages": [
{
"id": "cmlt12345000abc",
"guid": "6EEC3F64-A2B1-4C8F...",
"text": "Hello!",
"handle": "+12025551234",
"chatIdentifier": "+12025551234",
"isFromMe": false,
"service": "iMessage",
"isSent": true,
"isDelivered": true,
"isRead": false,
"error": 0,
"createdAt": "2026-02-19T12:00:00.000Z"
}
]
}
typing
Sent when a contact starts or stops typing.
{
"type": "typing",
"chatIdentifier": "+12025551234",
"active": true
}
Authentication
The SSE endpoint uses session-based authentication (browser cookies), not API keys. It is designed for use within the urelay dashboard or applications that authenticate through the web portal.
Keep-alive
The server sends a keepalive comment (: keepalive) every 30 seconds to prevent proxy timeouts. The EventSource API handles reconnection automatically if the connection drops.