Skip to main content

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

ParameterDescription
chatFilter 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.