NeuroWealth provides two real-time event streaming transports backed by a shared event hub, topic authorization model, and durable per-user sequence stream (UserEvent):
- WebSocket (
/api/v1/ws): Full-duplex transport suitable for interactive applications. - Server-Sent Events (
/api/v1/stream/sse): Plain HTTP GET fallback transport ideal for environments where WebSockets are blocked (corporate proxies, edge runtimes, curl/script consumers).
| Feature | WebSocket (/api/v1/ws) |
Server-Sent Events (/api/v1/stream/sse) |
|---|---|---|
| Protocol | ws:// / wss:// |
Standard HTTP GET (text/event-stream) |
| Authentication | Authorization: Bearer <token> or Sec-WebSocket-Protocol |
Authorization: Bearer <token> or ?ticket=<token> |
| Resume & Replay | Control message resume with afterSeq |
Last-Event-ID header or ?afterSeq= query param |
| Heartbeat | WS Ping/Pong frames | : keep-alive\n\n comments every 15s |
| Backpressure | Connection drop on overflow | Connection drop on overflow (event: overflow) |
Browsers using standard EventSource cannot set custom HTTP headers. To prevent putting live session tokens in URLs, clients obtain a single-use stream ticket:
- Issue Ticket:
POST /api/v1/stream/ticket(authenticated via Bearer JWT)- Returns:
{ "ticket": "eyJ...", "ttlSeconds": 60 }
- Returns:
- Connect SSE:
new EventSource('/api/v1/stream/sse?topics=portfolio,agent&ticket=eyJ...') - Ticket is single-use, expires in 60 seconds, and grants read-only topic access.
SSE events follow standard EventSource framing:
id: 1042
event: deposit.received
data: {"amount": 100, "asset": "USDC", "status": "CONFIRMED"}
: keep-aliveid:: Monotonic durable sequence number (seq).Last-Event-ID: When reconnecting, browsers automatically sendLast-Event-ID: 1042. The server replays missed events fromseq > 1042.event: replay_truncated: Emitted ifLast-Event-IDis older than the server's data retention window.
# 1. Get stream ticket
TICKET=$(curl -s -X POST http://localhost:3000/api/v1/stream/ticket \
-H "Authorization: Bearer $SESSION_TOKEN" | jq -r .ticket)
# 2. Connect to SSE stream
curl -N "http://localhost:3000/api/v1/stream/sse?topics=portfolio,transactions&ticket=$TICKET"