Skip to content

Read conversations and messages

messages() returns enriched messages on all four SDKs. Each message includes reactions, a reply count, and its reply parent when available. There is no separate enrichedMessages() method.

OptionDefaultDescription
limitNoneMaximum result count
sentBefore, sentAfterNoneFilter by sent time
insertedBefore, insertedAfterNoneFilter by local insertion time
sortBySent timeSort by sent or inserted time
directionAscendingAscending or descending
deliveryStatusAllPublished, unpublished, or failed
kindAllApplication or membership change
contentTypes, excludeContentTypesAll / noneInclude or exclude content types
excludeSenderInboxIdsNoneExclude sender inbox IDs

Time filters use Timestamp values. A Timestamp has an ns field for nanoseconds. Pass direction when order matters.

countMessages(options) returns a count without loading messages. It accepts ListMessagesOptions, but ignores limit, direction, and sortBy.

const
const messages: Message[]
messages
= await
conversation: Conversation
conversation
.
function messages(options?: ListMessagesOptions): Promise<Array<Message>>
messages
({
limit?: number | undefined
limit
: 10 });

Read the message’s content value and handle its content kind. For a reply, also inspect replyContent or inReplyToContent.

By default, messages are sorted by sentAt. A message can arrive after a newer message. Use insertedAt to paginate the local history by insertion time on all four SDKs.

A timestamp-only cursor can skip messages that have the same timestamp at a page boundary. For recent history followed by live delivery, use a message history snapshot and delivery cursor. A snapshot is a bounded recent tail. To replay all retained delivery history, start an independent reader at client.conversations.beginningDeliveryCursor() in each SDK.

Here is how to paginate messages with the cursor that each SDK exposes:

const
const firstPage: Message[]
firstPage
= await
group: Group
group
.
Group.messages(options?: ListMessagesOptions): Promise<Array<Message>>
messages
({
limit?: number | undefined
limit
: 20,
sortBy?: MessageSortBy | undefined
sortBy
: "insertedAt",
direction?: MessageOrder | undefined
direction
: "descending",
});
const
const secondPage: Message[]
secondPage
= await
group: Group
group
.
Group.messages(options?: ListMessagesOptions): Promise<Array<Message>>
messages
({
limit?: number | undefined
limit
: 20,
sortBy?: MessageSortBy | undefined
sortBy
: "insertedAt",
direction?: MessageOrder | undefined
direction
: "descending",
insertedBefore?: Timestamp | undefined
insertedBefore
:
const firstPage: Message[]
firstPage
.
Array<Message>.at(index: number): Message | undefined

Returns the item located at the specified index.

@param ― index The zero-based index of the desired code unit. A negative index will count back from the last item.

at
(-1)?.
MessageFields.insertedAt: Timestamp | undefined
insertedAt
,
});

We recommend listing allowed conversations only. This ensures that spammy conversations don’t appear in the main inbox.

MethodReturns
conversations.list(options)Groups and DMs
conversations.listGroups(options)Groups only
conversations.listDms(options)DMs only
const
const conversations: Conversation[]
conversations
= await
client: Client
client
.
ClientMembers.conversations: Conversations
conversations
.
Conversations.list(options?: ListConversationsOptions): Promise<Array<Conversation>>
list
({
consentStates?: ConsentState[] | undefined
consentStates
: ["allowed"],
});
OptionDefaultDescription
consentStatesAllowed and unknownConsent states to include
kindBothGroups or DMs
limitNoneMaximum result count
orderByCreated timeCreation or last activity
createdBefore, createdAfterNoneCreation-time bounds
lastActivityBefore, lastActivityAfterNoneLast-activity bounds
includeDuplicateDmsfalseInclude every underlying stitched DM

These options are available on all four SDKs. Time bounds use Timestamp values. Set orderBy to creation time and use createdBefore to paginate. A timestamp-only boundary can skip conversations with the same creation time.

Do not use with streaming

Do not paginate a conversation list while a conversation stream adds items to that same list. Keep the stream and paginated result separate until pagination ends.