Skip to content

Manage XMTP inboxes and installations

With XMTP, a user can have one or more inboxes they use to access their messages. An inbox can have multiple identities associated with it. An identity has a kind, such as EOA or SCW, and a string, which in the case of an EOA or SCW, is an Ethereum address. However, this extensible inbox-based identity model means that support for additional kinds of identities, such as Passkey or Bitcoin, can be added in the future.

All messages associated with these identities flow through the one inbox ID and are accessible in any XMTP app.

The first time someone uses your app with an identity they've never used with any app built with XMTP, your app creates an inbox ID and installation ID associated with the identity. To do this, you create a client for their identity.

The client creates an inbox ID and installation ID associated with the identity. By default, this identity is designated as the recovery identity. A recovery identity will always have the same inbox ID and cannot be reassigned to a different inbox ID.

When you make subsequent calls to create a client for the same identity and a local database is not present, the client uses the same inbox ID, but creates a new installation ID.

An inbox ID can have up to 5 app installations before it needs to revoke an installation.

You can enable a user to add multiple identities to their inbox. Added identities use the same inbox ID and the installation ID of the installation used to add the identity.

You can enable a user to remove an identity from their inbox. You cannot remove the recovery identity.

Inbox update and installation limits

🎥 walkthrough: Installation limits and static revocation

This video provides a walkthrough of the idea behind the XMTP installation limit (5) and how to use static installation revocation. After watching, feel free to continue reading for more details.

An inbox ID is limited to 256 inbox updates. Inbox updates include actions like:

  • Add a wallet
  • Remove a wallet
  • Add an installation
  • Revoke an installation

This means that one inbox ID can have up to 256 installations. When you add an inbox ID to a group, you are adding every installation as a member of the group. This means a group with an inbox that has 200+ installations can very quickly make a group size very large, which can have downstream performance implications.

If an inbox is allowed to reach its limit of 256 inbox updates, the user will need to rotate their inbox to continue using their identity with XMTP. Rotating their inbox will cause the user to lose of their existing conversations, but will enable them to continue using their identity with new XMTP conversations.

To avoid this scenario altogether, inboxes are limited to having only 5 active installations. When an inbox has 5 active installations, the user must revoke 1 installation before they are able to add another. This helps keep groups to a reasonable size and also helps keep users from accidentally reaching the 256 limit. However, note that revoking a installation counts toward the 256 inbox update limit, so frequently revoking installations and adding new ones can still cause a user to quickly reach the inbox update limit.

Have feedback about the inbox update and installation limits? We'd love to hear it. Post to the XMTP Community Forums.

Rotate an inbox ID

When you create an inbox ID, there is a nonce on it that is used to create the ID. If an inbox reaches its inbox updates limit, you can increment the nonce and it will create a new inbox ID associated with the user's information.

Help users manage installations

By default, your app stores the following information about installations:

  • id (random byte array)
  • createdAt (date)

To help users make informed decisions when managing and revoking their installations, you should aim to store additional useful information about installations, such as:

  • Last date logged in
  • Device make and model

Installation IDs that don't have this additional information can be treated as unknown installations, which can also provide helpful signals to users.

Revoke installations

🎥 walkthrough: Revoking installations

This video provides a walkthrough of revoking installations, covering the key ideas discussed in this doc. After watching, feel free to continue reading for more details.

Revoke a specific installation

You can revoke one or more specific installations by ID, as long as it isn't the currently accessed installation.

An inbox ID can have up to 5 app installations before it needs to revoke an installation.

  • If an inbox ID has 5 installations and the user wants to add another installation, use this function to enable them to revoke an installation before they can add the new one.

  • If an inbox ID was created before this installation limit was implemented, the inbox ID might have more than 5 installations. If this is the case, the user will receive an error when they try to add another installation. Use this function to enable them to revoke the required number of installations before they can add the new one. For example, if an inbox ID has 20 installations, the user will need to revoke 16 installations before they can add the new one.

If preferred, you can use the revoke all other installations function to revoke all installations other than the currently accessed installation.

Browser
await client.revokeInstallations([installationId1, installationId2])

Revoke all other installations

You can revoke all installations other than the currently accessed installation.

For example, consider a user using this current installation:

When the user revokes all other installations, the action removes their identity's access to all installations other than the current installation:

An inbox ID can have up to 5 app installations before it needs to revoke an installation.

If preferred, you can use the revoke a specific installation function to revoke one or more specific installations by ID.

Browser
await client.revokeAllOtherInstallations()

Revoke installations for a user who can't log in

For a video walkthrough of this feature, see 🎥 walkthrough: Installation limits and static revocation.

Static installation revocation enables users to revoke installations without needing to log in or have access to their installations.

This feature is especially useful in the following scenarios:

  • A user has reached the 5-installation limit and can't log in to revoke installations to make room for a new installation.
  • A user logs out of an app installation and chooses the option to delete their local database. Choosing this option will cause them to permanently lose access to the installation. For this reason, you should revoke the installation.

In both scenarios, static revocation enables logged out users to revoke installations using only their recovery address signer.

Here is how static installation revocation works behind the scenes:

  1. Determines which installation IDs to revoke
  2. Generates a signature request for the revocation
  3. Uses the recovery address signer to authorize the revocation
  4. Submits the signed request to revoke the specified installations
Browser
const inboxStates = Client.inboxStateFromInboxIds([inboxId], "production");
 
const toRevokeInstallationBytes = inboxStates[0].installations.map((i) => i.bytes);
 
await Client.revokeInstallations(
  signer,
  inboxId,
  toRevokeInstallationBytes,
  "production", // optional, defaults to "dev"
);

View the inbox state

Find an inboxId for an identity:

Browser
const inboxState = await client.preferences.inboxState()

View the state of any inbox to see the identities, installations, and other information associated with the inboxId.

Sample request
Browser
// the second argument is optional and refreshes the state from the network.
const states = await client.preferences.inboxStateFromInboxIds([inboxId, inboxId], true)
Sample response
InboxState
{
  "recoveryIdentity": "string",
  "identities": [
    {
      "kind": "ETHEREUM",
      "identifier": "string",
      "relyingPartner": "string"
    },
    {
      "kind": "PASSKEY",  // not yet supported; provided as an example only.
      "identifier": "string",
      "relyingPartner": "string"
    }
  ],
  "installations": ["string"],
  "inboxId": "string"
}

Add an identity to an inbox

Browser
await client.unsafe_addAccount(signer, true)

Remove an identity from an inbox

Browser
await client.removeAccount(identifier)

FAQ

What happens when a user removes an identity?

Consider an inbox with three associated identities:

If the user removes an identity from the inbox, the identity no longer has access to the inbox it was removed from.

The identity can no longer be added to or used to access conversations in that inbox. If someone sends a message to the identity, the message is not associated with the original inbox. If the user logs in to a new installation with the identity, this will create a new inbox ID.

How is the recovery identity used?

The recovery identity and its signer can be used to sign transactions that remove identities and revoke installations.

For example, Alix can give Bo access to their inbox so Bo can see their groups and conversations and respond for Alix.

If Alix decides they no longer want Bo have access to their inbox, Alix can use their recovery identity signer to remove Bo.

However, while Bo has access to Alix's inbox, Bo cannot remove Alix from their own inbox because Bo does not have access to Alix's recovery identity signer.

If a user created two inboxes using two identities, is there a way to combine the inboxes?

If a user logs in with an identity with address 0x62EE...309c and creates inbox 1 and then logs in with an identity with address 0xd0e4...DCe8 and creates inbox 2; there is no way to combine inbox 1 and 2.

You can add an identity with address 0xd0e4...DCe8 to inbox 1, but both identities with addresses 0x62EE...309c and 0xd0e4...DCe8 would then have access to inbox 1 only. The identity with address 0xd0e4...DCe8 would no longer be able to access inbox 2.

To help users avoid this state, ensure that your UX surfaces their ability to add multiple identities to a single inbox.

What happens if I remove an identity from an inbox ID and then initiate a client with the private key of the removed identity?

Does the client create a new inbox ID or does it match it with the original inbox ID the identity was removed from?

The identity used to initiate a client should be matched to its original inbox ID.

You do have the ability to rotate inbox IDs if a user reaches the limit of 256 identity actions (adding, removing, or revoking identities or installations). Hopefully, users won't reach this limit, but if they do, inbox IDs have a nonce and can be created an infinite number of times.

However, anytime a new inbox ID is created for an identity, the conversations and messages in any existing inbox ID associated with the identity are lost.

I have multiple identities associated with one inbox ID. If I log in with any one of these identities, does it access that inbox ID, or does it create a new inbox ID?

The identity accesses that inbox ID and does not create a new inbox ID.

For example, let's say that you create a client with an identity with address 0x62EE...309c. Inbox ID 1 is generated from that identity.

If you then add an identity with address 0xd0e4...DCe8 to inbox ID 1, the identity is also associated with inbox ID 1.

If you then log into a new app installation with the identity with address 0xd0e4...DCe8, it accesses inbox ID 1 and does not create a new inbox ID.

Once the identity with address 0xd0e4...DCe8 has been associated with inbox ID 1, it can then be used to log into inbox ID 1 using a new app installation.

The inverse is also true. Let's say an identity with address 0xd0e4...DCe8 was previously used to create and log into inbox ID 2.

If the identity is then added as an associated identity to inbox ID 1, the identity will no longer be able to log into inbox ID 2.

To enable the user of the identity with address 0xd0e4...DCe8 to log into inbox ID 2 again, you can use the recovery identity for inbox ID 2 to add a different identity to inbox ID 2 and have the user use that identity access it.

If you are interested in providing this functionality in your app and want some guidance, post to the XMTP Community Forums.