chat module is the server-side client for Sublay’s messaging: direct and group conversations, messages (with GIFs, mentions, threads, quotes, and file attachments), membership, reactions, read state, and reporting.
Acting on behalf of a user
Your service key has no implicit session user, so every chat call takes the user it acts as. Most functions take that user asuserId; the few where userId already names a target take the actor as actingUserId instead (createDirectConversation, addMember, removeMember, changeMemberRole).
Naming a user other than the caller’s own is gated to service/master keys. With
a service key, omitting the acting user returns
400 chat/missing-user-id.Conversations
listConversations
Lists the acting user’s conversations, newest activity first. Uses cursor (keyset) pagination — pass the last item’slastMessageAt as cursor and its createdAt as cursorCreatedAt to get the next page.
The user whose conversations are listed.
Comma-separated filter: any of
direct, group, space.Keyset cursor — the
lastMessageAt of the last item from the previous page.Tie-breaker cursor — the
createdAt of the last item from the previous page.Page size, 1–50. Defaults to
20.Promise<{ conversations: ConversationPreview[]; hasMore: boolean }>
Each ConversationPreview includes otherMembers — up to 5 active members other than the acting user (id, name, username, avatar) for direct/group conversations, so a DM/group can render the counterparty without a separate members fetch. Capped at 5 (use memberCount for the group total); empty for space conversations.
createDirectConversation
Creates (or returns the existing) one-to-one conversation between the acting user and a target user.The other participant (the target).
The user initiating the DM.
Promise<Conversation>
createGroupConversation
Creates a group conversation; the acting user becomes its admin.The acting user (becomes the group admin).
Group name.
Group description.
Initial members to add.
Custom key-value data.
Promise<Conversation>
getConversation
Fetches a single conversation the acting user is a member of.The acting user (must be a member).
Promise<Conversation>
updateConversation
Updates a group conversation. Requires the acting user to be a group admin.The acting user (must be a group admin).
File id for the avatar, or
null to clear it.Space conversations only.
Promise<Conversation>
deleteConversation
Deletes a group conversation. Requires the acting user to be a group admin.The acting user (must be a group admin).
Promise<void>
getUnreadCount
Returns the acting user’s unread totals across all conversations.Promise<{ totalUnread: number; unreadConversationCount: number }>
Members
listMembers
The acting user (must be a member).
Defaults to
1.1–100, defaults to
50.Filter by role.
Promise<PaginatedResponse<ConversationMember>>
addMember
Adds a member to a group. Requires the acting caller to be a group admin.The member to add (the target).
The caller (must be a group admin).
Promise<ConversationMember>
removeMember
Removes a member from a group. Requires the acting caller to be a group admin.The member to remove (the target).
The caller (must be a group admin).
Promise<void>
changeMemberRole
Promotes or demotes a member. Requires the acting caller to be a group admin.The member whose role changes (the target).
The caller (must be a group admin).
Promise<ConversationMember>
leaveConversation
The user leaving.
Promise<void>
Messages
listMessages
Lists messages in a conversation. Uses cursor pagination — passbefore (an ISO timestamp) to page backwards, or after to page forwards (before/after are mutually exclusive).
The acting user (must be a member).
Restrict to replies of this message (thread view).
ISO timestamp — messages created before this. Mutually exclusive with
after.ISO timestamp — messages created after this. Mutually exclusive with
before.1–100, defaults to
50.Comma-separated associations to populate, e.g.
"files".Optional filters.
filters.hasReplies (boolean): when true, returns only messages that have thread replies (threadReplyCount > 0); when false, only messages with none. Filters by thread replies, not quotings. Threads are one level deep, so hasReplies: true together with parentId always returns an empty list — the response’s notice field explains why.Promise<{ messages: ChatMessage[]; hasMore: boolean; oldestCreatedAt: string | null; newestCreatedAt: string | null }>
sendMessage
Sends a message as the acting user. A message must have content, a GIF, or at least one file. Whenfiles are attached the request is sent as multipart/form-data; otherwise it’s a JSON body.
The message author (must be a member).
Up to 4000 characters.
An attached GIF object.
User/space mentions.
Reply within a thread.
Quote another message.
Custom key-value data.
Client-generated id echoed back on the created message (not stored).
Attachments:
{ file: Uint8Array | Blob; filename?: string; mimeType?: string }[], up to 10.Promise<ChatMessage>
getMessage
The acting user (must be a member).
Promise<ChatMessage>
editMessage
Edits a message. Requires the acting user to be the message author.The acting user (must be the message author).
A GIF URL, or
null to clear it.Promise<ChatMessage>
deleteMessage
Soft-deletes a message. Requires the acting user to be the author or a group admin.The acting user (author or group admin).
Promise<void>
reportMessage
Reports a message for moderation.The reporting user (must be a member).
Up to 200 characters.
Up to 1000 characters.
Promise<{ message: string; code: string }>
Reactions
toggleReaction
Adds or removes the acting user’s emoji reaction on a message.The reacting user (must be a member).
Promise<{ reactionCounts: Record<string, number>; userReactions: string[]; delta: 1 | -1 }> (delta is 1 if the reaction was added, -1 if removed).
listReactions
Lists the users who reacted with a given emoji.The emoji to list reactors for.
The acting user (must be a member).
Defaults to
1.1–100, defaults to
50.Promise<{ data: MessageReaction[]; pagination: { page; limit; total; hasMore } }>
Read state
markAsRead
Marks the conversation read up to a given message.The message up to which the conversation is marked read.
The acting user (must be a member).
Promise<void>
Space conversations
Each space has a single built-in conversation. These three live onclient.spaces (they’re /spaces/... routes), not on client.chat.
spaces.getSpaceConversation
Fetches-or-creates a space’s conversation and joins the acting user to it. The acting user must be a non-banned member of the space.The acting user (must be a space member).
Promise<Conversation>
spaces.moderateSpaceChatMessage
Removes a message in a space conversation.Unlike the conversation-scoped chat calls, the two space-chat moderation routes
are service-key god-mode — your service key passes the space-moderator check
automatically.
actingUserId here is attribution only (who moderated); omit
it for a backend/system action.Acting moderator, for attribution.
Promise<{ message: string; moderationStatus: string }>
spaces.handleSpaceChatReport
Resolves a report against a space-conversation message: remove the message, ban the user, and/or dismiss.dismiss cannot be combined with the other actions.Required when actions include
remove-message.The user to ban (target); required when actions include
ban-user.Stored as the report’s resolution note.
Acting moderator, for attribution.
Promise<{ message: string; code: string }>
