Skip to main content
The chat module provides real-time messaging through channels (group chats, direct conversations, broadcasts). Users join channels as channel users, exchange messages within message feeds (threads), and can attach media, reactions, and mentions. Channels are the top-level container. Each channel has one or more message feeds (threads), and each feed contains messages ordered by a monotonically increasing segment. Messages support threading via a self-referential parentId.
Who is this for? This reference describes the core chat server data model. It’s essential for data import, analytics integration, and understanding API response structures. For social entities (User, Community, Post, Comment, etc.), see the Social Data Model Reference.

Entity Reference

6 core entities with full field definitions, types, and relationship mappings

Patterns & Relationships

Message threading, channel–community linking, and feed structure

Enums & Import Tips

Enum values and 8 practical data import guidelines

Conventions

Entity-Relationship Diagram

The following diagram shows the core entities and their relationships in the chat module.

Entity Reference

A chat room, conversation, or group. Channels are the top-level container for messaging. Every community has a 1:1 backing channel. Channels can be standard (open), private, direct conversations, broadcast, community-backed, or live (attached to a room).Relationships:
  • 1:1 → Community (community-type channels back a community; see Channel ↔ Community Relationship)
  • 1:N → ChannelUser (members)
  • 1:N → MessageFeed (message threads within the channel)
  • 0:1 → Room (live-type channels are attached to a room via attachedTo.roomId)
  • 0:1 → File (avatar via avatarFileId)
The join entity between User and Channel. Represents a user’s membership, roles, and read state within a channel.Relationships:
  • N:1 → User
  • N:1 → Channel
  • Composite key: (userId, channelId)
A message within a channel. Messages belong to a MessageFeed and support threading (replies). Each message is stored as its own document.
Threading model: See Message Threading Model below for details on how replies work.
Relationships:
  • N:1 → User (creator via creatorId)
  • N:1 → Channel (via channelId)
  • N:1 → MessageFeed (via messageFeedId)
  • 1:N → Message (replies via parentId, self-referential)
  • 1:N → Reaction (via reaction.referenceId where referenceType = "message")
  • 0:1 → File (attachment via data.fileId)
A message thread/feed within a channel. Each channel has one or more message feeds. The feed tracks the latest message and provides a message preview for UI display.Relationships:
  • N:1 → Channel (via channelId)
  • N:1 → User (creator via creatorId)
  • 1:N → Message (messages reference feed via messageFeedId)
Tracks reactions (likes, love, etc.) on messages. Each reaction is stored as its own document — one document per user-reaction-reference combination. Reactions use a polymorphic reference that supports multiple content types across both chat and social modules.
Reaction names are freeform strings, not a fixed enum. The reactions field on Message aggregates these as {reactionName: count}. The same Reaction entity is shared across both social and chat modules — only the referenceType differs.
Relationships:
  • N:1 → Message (when referenceType = "message")
  • N:1 → User (via userId)
An uploaded media file (image, video, audio, or generic file). Files are referenced by messages and channels via fileId. The File entity is shared across both social and chat modules.Relationships: Referenced by: Message (data.fileId, data.thumbnailFileId), Channel (avatarFileId).

Message Threading Model

Messages support single-level threading within a message feed:
1

Top-level messages

Top-level messages have parentId = null. They belong directly to the feed.
2

Replies

Replies have parentId set to the parent message’s ID.
3

Child tracking

childCount on each message tracks its direct reply count.
4

Segment ordering

Messages are ordered by segment within their feed (monotonically increasing). All messages (top-level and replies) live in the same feed and share the same segment counter.

Reconstructing Threads

  1. Query messages by messageFeedId.
  2. Top-level messages: parentId = null.
  3. Group replies by parentId.
  4. Order all messages by segment.

Channel ↔ Community Relationship

Every community in the social module has a 1:1 backing channel with type = "community". This relationship connects the social and chat modules:
Cross-module linking: The Community entity stores a channelId foreign key pointing to its backing channel. Community-type channels inherit the community’s membership — a user who is a community member is also a channel member. When importing data that spans both modules, ensure the Community’s channelId FK is correctly linked.

Key Enums Reference

Data Import Tips

Most entities expose three IDs (channelId, channelPublicId, channelInternalId). For joining data across entities, use the public ID — these are the values used in foreign key references. Internal IDs are database-level identifiers and may not appear in all API responses.
Every community has a 1:1 backing channel (with type = "community"). When importing both communities and channels, ensure corresponding records are linked. The community stores a channelId foreign key.
Messages within a feed are ordered by segment (a monotonically increasing integer). Preserve segment ordering during import to maintain correct message sequence. Each feed maintains its own independent segment counter.
The ChannelUser entity uses a composite key of (userId, channelId). When importing, deduplicate on both fields to avoid creating duplicate membership records.
Several fields are derived at read time and should not be imported as stored values:
  • Channel.isMuted — derived from muteTimeout > now.
  • Channel.isRateLimited — derived from rateLimitTimeout > now.
  • Channel.memberCount / messageCount — aggregated from related records.
  • ChannelUser.isBanned — derived from membership = "banned".
  • ChannelUser.isMuted — derived from muteTimeout > now.
  • Message.myReactions — derived per-request for the current user.
  • MessageFeed.messagePreviewId — derived from latest message.
Soft-deleted records have isDeleted: true. Exclude these by default for analytics unless you need deletion history.
Message reactions follow the same model as social reactions (see Social Data Model Reference). Each reaction is stored as a separate document with referenceType = "message" and referenceId pointing to the message. The reactions object on Message provides pre-aggregated {name: count} maps.
To get only top-level messages (not replies), filter by parentId = null. To reconstruct threads, group replies by parentId and order by segment. See Message Threading Model for the full pattern.

Social Data Model

Core social entities — User, Community, Post, Comment, Reaction, and more

API Overview

Server-to-server API capabilities, authentication methods, and getting started guide

SDK Chat Overview

Client-side SDK implementation for channels, messaging, and real-time chat features