Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/xmtp/libxmtp/llms.txt

Use this file to discover all available pages before exploring further.

Groups are the core of XMTP conversations. This guide covers creating groups, managing membership, and working with direct messages.

Creating Groups

Basic Group Creation

Create a new group with default settings:
use xmtp_mls::groups::MlsGroup;

// Create an empty group
let group = client.create_group(None, None)?;
When you create a group, you are automatically:
  • Added as the only member
  • Designated as a super admin
  • Required to update installations before other operations

Create Group with Members

Add members at creation time using wallet addresses:
use xmtp_id::associations::Identifier;

let members = vec![
    Identifier::Address("0x1234...".to_string()),
    Identifier::Address("0x5678...".to_string()),
];

let group = client.create_group_with_identifiers(
    &members,
    None,  // Default permissions
    None,  // Default metadata
).await?;
Or use inbox IDs directly:
let inbox_ids = vec!["inbox_1", "inbox_2"];

let group = client.create_group_with_members(
    &inbox_ids,
    None,  // permissions  
    None,  // metadata
).await?;

Group Metadata

Set group name, description, and image:
use xmtp_mls_common::group::GroupMetadataOptions;
use xmtp_mls_common::group_mutable_metadata::MessageDisappearingSettings;

let metadata = GroupMetadataOptions {
    name: Some("My Group".to_string()),
    description: Some("A group for friends".to_string()),
    image_url_square: Some("https://example.com/image.jpg".to_string()),
    pinned_frame_url: None,
    message_disappearing_settings: None,
};

let group = client.create_group(None, Some(metadata))?;

Managing Members

1
Add Members
2
Add members by wallet address:
3
use xmtp_id::associations::Identifier;

let new_members = vec![
    Identifier::Address("0xabcd...".to_string()),
];

let result = group.add_members_by_identity(&new_members).await?;

println!("Added {} installations", result.added_members.len());
4
Or by inbox ID:
5
let inbox_ids = vec!["inbox_id_here"];
let result = group.add_members(&inbox_ids).await?;
6
Remove Members
7
Remove members by wallet address:
8
let members_to_remove = vec![
    Identifier::Address("0x1234...".to_string()),
];

group.remove_members_by_identity(&members_to_remove).await?;
9
Or by inbox ID:
10
group.remove_members(&["inbox_id"]).await?;
11
List Members
12
Get all current group members:
13
let members = group.members().await?;

for member in members {
    println!("Inbox: {}", member.inbox_id);
    println!("  Installations: {}", member.installation_ids.len());
    println!("  Permission: {:?}", member.permission_level);
}

Direct Messages (DMs)

DMs are a special type of group limited to two participants.

Find or Create DM

The recommended approach automatically handles duplicate DMs:
use xmtp_id::associations::Identifier;

// By wallet address
let dm = client.find_or_create_dm_by_identity(
    Identifier::Address("0x5678...".to_string()),
    None,  // metadata options
).await?;

// By inbox ID
let dm = client.find_or_create_dm(
    "inbox_id_here",
    None,
).await?;
find_or_create_dm prevents duplicate DMs by:
  1. Checking for existing active DMs with the target inbox
  2. Returning the existing DM if found
  3. Creating a new DM only if none exists

DM Metadata

Customize DM settings:
use xmtp_mls_common::group::DMMetadataOptions;

let dm_metadata = DMMetadataOptions {
    name: Some("Chat with Alice".to_string()),
    image_url_square: Some("https://example.com/alice.jpg".to_string()),
    message_disappearing_settings: None,
};

let dm = client.find_or_create_dm(
    target_inbox_id,
    Some(dm_metadata),
).await?;

Syncing Groups

Sync Welcomes

Fetch groups you’ve been added to:
// Download and process welcome messages
let new_groups = client.sync_welcomes().await?;

println!("Joined {} new groups", new_groups.len());

Sync Group Messages

Update a specific group:
// Fetch new messages and membership updates
group.sync().await?;
Sync all groups:
let groups = client.find_groups(GroupQueryArgs::default())?;
let summary = client.sync_all_groups(groups).await?;

println!("Synced {} groups", summary.num_groups_synced);

Combined Sync

Sync welcomes and all groups in one call:
use xmtp_db::consent_record::ConsentState;

// Only sync allowed/unknown groups
let summary = client.sync_all_welcomes_and_groups(
    Some(vec![ConsentState::Allowed, ConsentState::Unknown])
).await?;

println!("Total groups synced: {}", summary.num_groups_synced);

Querying Groups

Find Groups

Query with filters:
use xmtp_db::group::{GroupQueryArgs, GroupMembershipState, ConversationType};

let args = GroupQueryArgs::default()
    .allowed_states(vec![GroupMembershipState::Allowed])
    .conversation_types(vec![ConversationType::Group])  // Exclude DMs
    .created_after_ns(Some(start_time))
    .limit(Some(50));

let groups = client.find_groups(args)?;

Get Specific Group

Look up by group ID:
let group = client.group(&group_id)?;
Get DM by target inbox:
let dm = client.dm_group_from_target_inbox(target_inbox_id)?;

List Conversations

Get conversations with last message:
use xmtp_db::group::GroupQueryOrderBy;

let args = GroupQueryArgs::default()
    .order_by(Some(GroupQueryOrderBy::LastActivity));

let conversations = client.list_conversations(args)?;

for conv in conversations {
    println!("Group: {:?}", conv.group.group_id);
    if let Some(msg) = conv.last_message {
        println!("  Last message at: {}", msg.sent_at_ns);
    }
}

Updating Group Metadata

Group admins can update metadata:
// Update group name
group.update_group_name("New Name".to_string()).await?;

// Update description
group.update_group_description("New description".to_string()).await?;

// Update image
group.update_group_image_url_square("https://new-image.jpg".to_string()).await?;
Metadata updates are governed by the group’s permission policies. See Permissions and Policies for details.

Group Properties

// Basic properties
let group_id = group.group_id.clone();
let created_at = group.created_at_ns;
let conversation_type = group.conversation_type;

// Check if DM
if conversation_type == ConversationType::Dm {
    println!("This is a direct message");
}

// Get metadata
let metadata = group.metadata()?;
println!("Name: {:?}", metadata.group_name);
println!("Description: {:?}", metadata.description);

Error Handling

Common group management errors:
use xmtp_mls::groups::GroupError;

match group.add_members(&inbox_ids).await {
    Ok(result) => {
        println!("Added {} members", result.added_members.len());
    }
    Err(GroupError::UserLimitExceeded) => {
        eprintln!("Group is full (max {} members)", MAX_GROUP_SIZE);
    }
    Err(GroupError::NotFound(NotFound::InboxIdForAddress(addr))) => {
        eprintln!("Address {} not found on network", addr);
    }
    Err(GroupError::InvalidPermission) => {
        eprintln!("You don't have permission to add members");
    }
    Err(e) => {
        eprintln!("Failed to add members: {}", e);
    }
}

Best Practices

1
Keep Groups Synced
2
Regularly sync to get updates:
3
// Before important operations
group.sync().await?;

// Or use periodic background sync
let summary = client.sync_all_welcomes_and_groups(None).await?;
4
Handle Member Updates
5
Group members may add new installations:
6
// Update group to include new installations
group.update_installations().await?;
7
Use find_or_create for DMs
8
Always use find_or_create_dm to prevent duplicates:
9
// Good - prevents duplicates
let dm = client.find_or_create_dm(inbox_id, None).await?;

// Avoid - can create duplicates
// let dm = client.create_dm_by_inbox_id(inbox_id, None).await?;
10
Verify Network Presence
11
Check if addresses can receive messages:
12
let identifiers = vec![
    Identifier::Address("0x1234...".to_string()),
];

let can_message = client.can_message(&identifiers).await?;

for (identifier, can_msg) in can_message {
    if !can_msg {
        println!("Cannot message {}", identifier);
    }
}

Next Steps

Sending Messages

Send and receive messages in groups

Permissions and Policies

Configure who can perform actions in groups