04
API Design
Two surfaces: a REST API for stateful operations (create channel, fetch history) and a WebSocket gateway for real-time events. All real-time flows use the WebSocket; REST is for things you'd do from any tab.
WSwss://gateway.example.com/?v=9&token=JWT
Establish persistent connection. Server sends Hello + heartbeat_interval; client heartbeats every N seconds. Receives push events (MESSAGE_CREATE, TYPING_START, PRESENCE_UPDATE, etc.)
POST/api/channels/{channel_id}/messages
Send a message. Body: { content, attachments[], reply_to?, nonce }. Nonce enables client-side dedup. Returns { message_id, ts }.
GET/api/channels/{channel_id}/messages?before=ID&limit=50
Paginated message history. Cursor-based (not offset); cursor = message_id. Lets you scroll back indefinitely.
POST/api/channels/{channel_id}/messages/{id}/reactions/{emoji}/@me
Add reaction. Separate endpoint so rate limits can target reactions specifically (common spam vector).
POST/api/channels/{channel_id}/typing
Broadcast typing-indicator. Fire-and-forget; no persistence. Gateway broadcasts to channel subscribers; auto-expires after 10 s.
GET/api/search?q=term&channel_id=X
Full-text search across message history. Backed by Elasticsearch; results scoped by user's channel membership.
POST/api/attachments/upload
Returns pre-signed S3 URL + attachment_id. Client uploads directly; then includes attachment_id in POST /messages.
POST/api/guilds/{guild_id}/members/{user_id}
Join / leave server. Triggers membership update event to all guild members (GUILD_MEMBER_ADD).