Real-time (SSE)
RSMG Engage streams live discussion activity over Server-Sent Events (SSE). To subscribe, mint a
short-lived, single-use ticket from your backend, then open an EventSource to the stream with
that ticket.
1. Mint a ticket (backend)
POST /api/v1/stream/ticket-by-external
X-API-Key: ek_…
Content-Type: application/json
{ "externalId": "article-123" }
{ "data": { "ticket": "…", "discussionId": "…", "expiresAt": "…", "discussionStatus": "open" } }
Tickets are short-lived (~60 s) and single-use, so mint one per connection. You can also mint by
UUID via POST /api/v1/stream/ticket with { "discussionId": "…" }.
2. Connect (client)
const es = new EventSource(
`https://{slug}.rsmg-engage.com/api/v1/stream/${discussionId}?ticket=${ticket}`,
);
es.addEventListener('comment_created', (e) => render(JSON.parse(e.data)));
The ticket is the only credential the browser needs — no API key reaches the client.
Event types
| Event | When |
|---|---|
comment_created | A comment is posted |
comment_edited | A comment body changes |
comment_deleted | A comment is removed (carries deletedBy) |
comment_approved / comment_rejected | Moderation decision on a pending comment |
comment_pinned / comment_unpinned | Admin pins/unpins |
reaction_toggled | A reaction is added/removed |
discussion_locked / discussion_unlocked / discussion_archived | Discussion lifecycle change |
poll_vote / poll_status_changed | Poll activity |
Two framing events bracket the stream: connected on subscribe, and connection-timeout when a
long-lived connection is cycled.
Suppressing your own echoes
Every event includes originatedBy: { userId: string | null } — the acting reader's internal
user id, which is null for admin and visitor actions. If your client knows the internal id, match
on it to skip echoing an action you just performed locally.
For clients that don't hold internal ids, two sibling fields cover the gap:
externalUserIdonreaction_toggled— the reacting reader's external (your-side) id.ballotKeyonpoll_vote— for anonymous poll voters.
Match either against your local viewer to self-suppress without ever seeing internal ids.
See Stream in the API Reference for payload shapes, and Webhooks for server-to-server delivery of the same events.