Overview
DecodedMessage is the enriched message type returned by list_enriched_messages() / listEnrichedMessages(). It includes decoded content, reactions, reply counts, and references to replied-to messages.
Use DecodedMessage when building message UIs that need to display:
- Reaction counts and emoji
- Reply threads
- Deleted message states
- Full message metadata
Message type from list_messages() / listMessages().
Structure
Rust
crates/xmtp_mls/src/messages/decoded_message.rs:108
Node.js
bindings/node/src/messages/decoded_message.rs:11
Metadata
DecodedMessageMetadata (Rust)
crates/xmtp_mls/src/messages/decoded_message.rs:84
Field descriptions
id
Unique message identifier as bytes. In Node.js bindings, exposed as hex string.group_id / conversationId
Identifies which group/conversation this message belongs to. Bytes in Rust, hex string in Node.js.sent_at_ns
Timestamp when the message was sent, in nanoseconds since Unix epoch.kind
Message purpose:Application- User-generated content (text, reactions, etc.)MembershipChange- Group membership updates
sender_installation_id
Unique identifier for the sender’s installation. A single inbox can have multiple installations (devices).sender_inbox_id
Inbox ID of the message sender. This is the primary identifier for users in XMTP.delivery_status
Current delivery state:Unpublished- Message prepared but not sent to networkPublished- Successfully sent and confirmedFailed- Send attempt failed
content_type
Identifies the content type:inserted_at_ns
When the message was inserted into the local database (nanoseconds).expires_at_ns
Optional expiration timestamp. After this time, the message should be deleted.Content
MessageBody (Rust)
Thecontent field is a MessageBody enum representing different content types:
crates/xmtp_mls/src/messages/decoded_message.rs:61
DecodedMessageContent (Node.js)
In Node.js, content is wrapped inDecodedMessageContent with type-safe getters:
Reactions
Thereactions field contains all reaction messages referencing this message.
Reaction filtering
Reactions include both added and removed:Replies
num_replies
Count of messages that reference this message as a reply:in_reply_to (Reply content only)
For messages withReply content, the in_reply_to field contains the referenced message:
crates/xmtp_mls/src/messages/decoded_message.rs:32
Deleted messages
When a message is deleted, its content is replaced with:Fallback text
Many content types include fallback text for clients that don’t support them:Querying enriched messages
List with options
Performance considerations
Enriched messages are more expensive to load than basic messages because they:- Decode message content
- Query related reactions
- Query reply counts
- Fetch referenced messages for replies
- Check deletion status
- Use
listMessages()for simple message lists - Use
listEnrichedMessages()only when displaying reactions/replies - Implement pagination to limit batch size
- Cache enriched data on the client side
Enrichment process
The enrichment process (fromcrates/xmtp_mls/src/messages/enrichment.rs):
- Decode content - Convert stored bytes to
MessageBody - Load reactions - Query reactions referencing each message
- Count replies - Count messages with
reference_idmatching message ID - Load reply context - For reply messages, fetch the referenced message
- Apply deletions - Replace content with
DeletedMessageif deleted - Validate deletions - Ensure deletion is by sender or admin
crates/xmtp_mls/src/messages/enrichment.rs:73
Example: Message thread UI
See also
- Messages Overview - Message lifecycle and patterns
- Content Types - Available content types
- Sending Messages - Guide to sending messages
