Entity Reference
Relationship Patterns
Enums & Import Tips
Conventions
Entity-Relationship Diagram
The following diagram shows the core entities and their relationships in the social module.Entity Reference
User
User
1:N→ Post (aspostedUserId)1:N→ Comment (asuserId)1:N→ Story (ascreatorId)1:N→ Poll (asuserId)M:N→ Community (via CommunityUser join)1:N→ Follow (asfromorto)
Community
Community
displayName, tags, metadata, avatarFileId, categoryIds, hasFlaggedComment, hasFlaggedPost, notificationMode) are actually stored on the backing Channel document, not on the Community document itself. The API serializer merges both into a single response.1:1→ Channel (every community has a backing channel)M:N→ CommunityCategory (viacategoryIds[])1:N→ CommunityUser (members)1:N→ Post (via polymorphictargetIdwheretargetType = "community")1:N→ Story (via polymorphictargetIdwheretargetType = "community")1:N→ Feed (via polymorphictargetIdwheretargetType = "community")
CommunityCategory
CommunityCategory
categoryIds[] (many-to-many).M:N→ Community (referenced bycommunity.categoryIds[])
CommunityUser (Member)
CommunityUser (Member)
N:1→ UserN:1→ Community- Composite key: (
userId,communityId)
Post
Post
N:1→ User (creator viapostedUserId)N:1→ Community or User (viatargetId+targetType)1:N→ Post (children viaparentPostId, self-referential)1:N→ Comment (viacomment.referenceIdwherereferenceType = "post")1:N→ Reaction (viareaction.referenceIdwherereferenceType = "post")N:1→ Feed (viafeedId)0:1→ Poll (viadata.pollIdwhen created as poll post)0:N→ File (attachments via child posts ordata.fileId)
Comment
Comment
Reaction
Reaction
reactions field on Post/Comment/Story aggregates these as {reactionName: count}.Aggregated view: When querying reactions for a reference, the API returns an aggregated reactors[] array grouped by reference. Each entry contains reactionId, reactionName, userId, and createdAt.N:1→ Post (whenreferenceType = "post")N:1→ Comment (whenreferenceType = "comment")N:1→ Story (whenreferenceType = "story")N:1→ Message (whenreferenceType = "message")N:1→ User (viauserId)
Follow
Follow
N:1→ User (from — the follower)N:1→ User (to — the followed)
Feed
Feed
N:1→ Community (whentargetType = "community")N:1→ User (whentargetType = "user")1:N→ Post (posts reference feed viapost.feedId)
Poll
Poll
N:1→ User (creator)1:1→ Post (poll is embedded viapost.data.pollId)
Room
Room
dataType = "room" and data.roomId. They have a lifecycle (idle → live → ended/recorded) and can optionally attach a live chat channel.N:1→ User (creator viacreatedBy)N:1→ Community (viatargetIdwheretargetType = "community")1:1→ Post (room is embedded viapost.data.roomId; room references back viareferenceId)1:N→ Room (children viaparentRoomId, self-referential)0:1→ File (thumbnail viathumbnailFileId)0:1→ Channel (live chat vialiveChannelId)
Story
Story
N:1→ User (creator viacreatorId)N:1→ Community (whentargetType = "community")N:1→ User (whentargetType = "user")1:N→ Comment (viacomment.referenceIdwherereferenceType = "story")1:N→ Reaction (viareaction.referenceIdwherereferenceType = "story")0:N→ File (viadata.fileId,data.thumbnailFileId)
File
File
fileId.data.fileId, child post attachments), Comment (attachments[].fileId), Story (data.fileId), User (avatarFileId), Community (avatarFileId), CommunityCategory (avatarFileId), Poll answers (answers[].fileId).Polymorphic Reference Patterns
Two polymorphic foreign key patterns are used throughout the data model. Understanding these is critical for correct data joins.- targetId + targetType
- referenceId + referenceType
Post Composition Model (Parent–Child Posts)
Posts use a parent–child composition pattern to represent multi-attachment content (e.g., image galleries, mixed-media posts).Top-level posts
parentPostId = null.Child posts
parentPostId pointing to the parent’s postId.Parent tracks children
children[] (array of child post IDs) and childrenNumber.One attachment per child
fileId or videoFileId per child).Structure type derivation
structureType field on the parent indicates the derived type: image, video, file, text, etc. if all children are the same type, or mixed if children have different data types.Querying top-level posts
parentPostId = null to get only top-level posts. Then load children[] to get attachments.Comment Threading Model
Comments support two-level threading usingparentId and rootId.
Top-level comments
referenceId → Post/Story, parentId = null, rootId = null.Replies
parentId to the direct parent comment and rootId to the thread root.Shared root
rootId, regardless of nesting depth.Children tracking
children[] (array of child comment IDs) and childrenNumber.Content reference
referenceId + referenceType.Feed System
Feeds organize posts for a specific target. Each community or user can have up to three feed types representing the post approval workflow:Feed Endpoints
Community Feed
targetType = "community".User Feed
targetType = "user".Global Feed
Following Feed
Post → Feed Mapping
- Every post has a
feedIdpointing to the Feed it belongs to. - The Feed’s
targetId+targetTypetells you which community or user owns it. - To find all published posts in a community: find the Feed where
targetId = communityId,targetType = "community",feedType = "published", then query posts by thatfeedId.
Key Enums Reference
Full Enums Table
Full Enums Table
Data Import Tips
1. ID Resolution
1. ID Resolution
userId, userPublicId, userInternalId). For joining data across entities, use userId or the corresponding 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.2. Routing Posts to Communities vs. User Profiles
2. Routing Posts to Communities vs. User Profiles
targetType + targetId on posts:targetType = "community"→ the post belongs to a community; join ontargetId = community.communityId.targetType = "user"→ the post is on a user’s profile feed; join ontargetId = user.userId.
3. Reactions are Freeform
3. Reactions are Freeform
"like", "love", "wow") are freeform strings, not a fixed enum. When aggregating, group by reactionName. The reactions object on Post/Comment/Story already provides {name: count} aggregations.4. Polls are Embedded in Posts
4. Polls are Embedded in Posts
data object will contain a pollId during creation. To join: Post.data.pollId → Poll.pollId. Not all posts have polls — only those with structureType = "poll" or where data.pollId exists.5. Stories Expire
5. Stories Expire
expiresAt timestamp. To query only active stories, filter where expiresAt > NOW(). Expiry duration is configurable per network (1–1440 minutes). Expired stories remain in the database but are no longer shown in story rings.6. Filtering Deleted Records
6. Filtering Deleted Records
isDeleted: true. Exclude these by default for analytics unless you need deletion history. Posts also support permanent (hard) deletes — these records are removed entirely.7. Feed Type Awareness
7. Feed Type Awareness
feedType:published→ live, visible posts (this is what you want for most analytics).reviewing→ posts awaiting approval.declined→ rejected posts.
8. Post Children vs. Top-Level Posts
8. Post Children vs. Top-Level Posts
parentPostId = null when counting top-level posts. Child posts are attachments/media within a parent post, not standalone content.9. Comment Depth
9. Comment Depth
parentId = null. To reconstruct full threads, group by rootId.10. Community Membership
10. Community Membership
communityMembership:member→ active member.banned→ banned from the community.none→ not a member.
commentIduserIduserPublicIduserInternalIdparentIdnullfor top-level.rootIdnullfor top-level.referenceIdreferenceTypepost|content|story. WhatreferenceIdpoints to.targetIdpathat serialization time.targetTypecommunity|user|content. Derived frompathat serialization time.dataType"text"in newer SDKs.dataTypestext|image|video. A comment can contain multiple types.datametadataattachments[{type: "image"|"video", fileId: "..."}].childrenchildrenNumberreactionsreactionName → count.reactionsCountmyReactionsmentionees[{type: "user", userIds: [...]}].segmentNumberflagCounthashFlagpublisherPublicIdlinkseditedAtisDeletedcreatedAtupdatedAtN:1→ User (creator viauserId)N:1→ Post or Story (viareferenceId+referenceType)1:N→ Comment (replies viaparentId, self-referential)N:1→ Comment (root thread viarootId)1:N→ Reaction (viareaction.referenceIdwherereferenceType = "comment")0:N→ File (viaattachments[].fileId)