Events
ServerService.Subscribe streams events to a client. One stream carries everything for one member. Clients act with unary calls; the stream only receives.
Sequence numbers
Every saved event has a server-wide seq that only goes up. The client keeps the last seq it applied.
- Call
GetState. Itsseqis the snapshot point. - Call
SubscribewithafterSeqset to it. - The server first replays every event after that seq that you may see, then streams live ones.
- After a disconnect, subscribe again with the last seq you applied. Nothing is missed.
Typing, presence and heartbeat events are not saved. Their seq is 0.
Heartbeats
The server sends a heartbeat at once, so the response starts without delay, and then every 25 seconds. It keeps proxies from closing the stream.
Resync
The server keeps the newest 10,000 events, and anything newer than 7 days. If you ask for a seq it no longer has, or a seq from the future, the first event that is not a heartbeat is resync. Call GetState and continue from its seq. The stream stays open.
Falling behind
A subscriber more than 512 events behind is dropped with resource_exhausted. Reconnect with the last seq.
Who gets what
Each event is stored with who may see it, and replay uses the same rule as live delivery:
- Public: every member. For example,
member_joined. - One channel's members: message events, and channel events for that channel. A member never receives traffic for a channel they cannot see.
- One member:
read_state, andchannel_createdwhen they are added to a channel.
Event kinds
Each Event has seq, at_ms and exactly one of these:
| Kind | Carries | When |
|---|---|---|
message_created |
Message | A new message or thread reply. |
message_updated |
Message | An edit, a reaction, or a new reply count on a thread root. |
message_deleted |
Message | A message was deleted. |
channel_created |
Channel | A channel you can now see. Add it. |
channel_updated |
Channel | A channel changed. Treat it as an upsert. |
channel_deleted |
channel id | A channel is gone for you. Drop it. |
member_joined |
Member | Someone joined. |
member_updated |
Member | Profile, permission or roles changed. |
member_left |
member id | Someone left, was kicked or was banned. |
read_state |
ReadState | Your read state changed, for example on another device. |
typing |
TypingEvent | Someone is typing. Not saved. |
presence |
PresenceEvent | Someone came online, went away or went offline. Not saved. |
heartbeat |
true | Every 25 seconds. Not saved. |
resync |
true | Call GetState again. |
role_updated |
Role | A role was made or changed. |
role_deleted |
role id | Drop it from members and channels. |
channel_mode_changed |
ChannelMode | The community switched between roles and opt-in mode. |
server_updated |
true | Description, banner or icon changed. Call GetServerInfo. |
emoji_changed |
true | Custom emoji were added or deleted. Fetch GET /emoji again. |
When a change hides a channel from a member, they get channel_deleted. When a change lets them in, they get channel_created. Members who still see it get channel_updated.
Unread counts
- Unread counts start when a member joined, so old history is not unread.
unread_countcounts top-level messages by others, not thread replies.mention_countcounts<@member_id>mentions in any message, thread replies too, and every message in a DM.- To tell if a message is new, compare its
created_seqwithlast_read_seq. Do not useseq, which edits, reactions and replies bump. MarkReadwithseq0 marks everything read. It sendsread_stateto all of that member's streams.
Tools and agents can read every call and type from schema.json.
View this page as Markdown · Glossary · API schema.json · openapi.json