The first step to creating a conversation is to verify that participants’ identities are reachable on XMTP. The canMessage method checks each identity’s compatibility, returning a response indicating whether each identity can receive messages.
Once you have the verified identities, you can create a new conversation, whether it’s a group chat or direct message (DM).
Client.canMessage(identities, backend) works without a client on Browser and Node. Kotlin and Swift use SDKClient.canMessage with an explicit backend. An existing client also has canMessage. Browser and Node return a Map; Kotlin and Swift return a dictionary keyed by the identity identifier.
A PublicIdentity can also name a handle, such as nick#2341, with the kind handle. canMessage reports it under the key handle:<handle>, in lowercase. true means only that the backend names an inbox for the handle: the SDK does not check this answer against the inbox’s identity log. createDm and createGroup check their own lookup answer before they use the inbox. See Use a handle.
The backend sets the group member limit. The default limit is 250 inboxes.
All four SDKs use conversations.createGroup(members, options). Pass a list of inbox IDs or a list of PublicIdentity values. Do not mix the two in one list. Swift uses the labels members: and options:. Kotlin and Swift get the collection with client.conversations.
Set the group name, description, image URL, app data, permissions, and disappearing-message settings at creation. See Groups.
Optimistic group creation enables you to prepare a group and messages before you know its members. The group stays only in the local database until you add a member. It is not visible to anyone else before that step.
All four SDKs use createGroupOptimistic(options). The call is asynchronous. Add members, then call publishMessages() to publish prepared messages.
Creating a DM returns the existing conversation if you already have one with that peer. You cannot create a DM with yourself.
All four SDKs use conversations.createDm(peer, options). Pass an inbox ID or a PublicIdentity value. Swift uses the labels peer: and options:.
Different installations can create separate DMs for the same pair. XMTP stitches these records into one visible DM. A lookup can therefore return a different conversation ID. Do not key app state on a DM conversation ID. See DM stitching.
createDm, createGroup, and getDmByIdentity take a handle as they take an account. One list of PublicIdentity values can mix handles and accounts. Before the SDK uses a lookup answer, it checks that the inbox’s own identity log claimed the handle. An old handle reaches the inbox that claimed it. For a handle that no inbox claimed, createDm and createGroup fail with IdentityNotFound, and getDmByIdentity returns no DM.
The Agent SDK adds createDmWithAddress, createGroupWithAddresses, and addMembersWithAddresses, and createDmWithHandle, createGroupWithHandles, and addMembersWithHandles for handles. getSenderAddress() resolves the first identifier for the sender and returns undefined when none exists.