Skip to content

MSC4426: User Status Profile Fields - #4426

Open
anoadragon453 wants to merge 18 commits into
mainfrom
anoa/user_status_profile_fields
Open

anoadragon453 wants to merge 18 commits into
mainfrom
anoa/user_status_profile_fields

Conversation

@anoadragon453

@anoadragon453 anoadragon453 commented Feb 25, 2026 •

Copy link
Copy Markdown
Member

Rendered

Disclosure: I am a member of the Matrix Spec Core Team (SCT) and am employed by Element. This proposal is written and published with my Element hat on to improve clarity when messaging users in a team-based environment. I'm also personally excited to advance user-scoped profile information in Matrix, with these fields being just the beginning.

Implementations:

@anoadragon453 anoadragon453 changed the title MSCXXXX: User Status Profile Fields MSC4426: User Status Profile Fields Feb 25, 2026
@anoadragon453 anoadragon453 added T-Improvement A suggestion for a relatively simple improvement to the protocol proposal A matrix spec change proposal. Process state. A-Client Server Client-Server API kind:feature MSC for not-core and not-maintenance stuff needs-implementation This MSC does not have a qualifying implementation for the SCT to review. The MSC cannot enter FCP. proposal-in-review labels Feb 25, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation requirements:

  • Client (sending)
  • Client (rendering)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Client implementation (Voyage):

VoyageClient/Voyage@524782a

Comment on lines +136 to +155
#### Moderation

A free-form, user-controlled text field that can be displayed in clients to
other users is a prime opportunity for spammers and malicious actors. Attacks
include:
* Displaying hate speech
* Linking to malware/phishing content
* With custom emoji support, displaying explicit/illegal imagery by their display name across the app

As user status is tied to a user - rather than a room - simply kicking a user from a room may not immediately solve the issue.

* Clients should take care not to display associated status emoji/text in
membership change messages (i.e. “User 🌴 was kicked from the room).
* The emoji in question may appear in the results of a user search (clients
SHOULD NOT display these by default. Instead, require the user to perform
some explicit action first, e.g. inviting the user to a room or DM.)
* To remove offensive material from the room timeline and members list, a
moderator should kick/ban the user. A client that displays the status
information in the timeline should stop doing so if the user has left/been
kicked from the room.

@Gnuxie Gnuxie Feb 25, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concerns about free-text were deferred during the review process of MSC4133 and did not receive proper review or consideration. It's not fair to the first proposer of an MSC with free-text or any user generated content has to solve the problem on their own and also get the burden of me and others writing review about it on their proposal.

When it was always inevitable and clear that the merit of MSC4133 was to handle user generated content

@Gnuxie Gnuxie Feb 25, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to see an MSC that allows room moderators or their tooling to review profiles proactively. To start with this would mean an MSC that can trace history and updates to global profiles so that moderators can review them.

@Gnuxie Gnuxie Feb 25, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Who reviews profiles, and approves profiles, needs thinking about.

One option is to make the homeserver admin and their tooling responsible for reviewing global profile changes (which would be deferred/assisted by distributed moderation via policy lists). This seems like the easiest place to intervene rather than deferring to room moderators directly.

@Gnuxie Gnuxie Feb 25, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense to use reasonable metrics like a common direct message to be able to see the profile. Another important rule would be that the moderator of a room in common with the user should always be able to see their profile (unless the user's profile has been blocked on the server, but they will need to know that it has been blocked so they can ban them).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for engaging on this @Gnuxie!

Who reviews profiles, and approves profiles, needs thinking about.

One option is to make the homeserver admin and their tooling responsible for reviewing global profile changes (which would be deferred/assisted by distributed moderation via policy lists). This seems like the easiest place to intervene rather than deferring to room moderators directly.

I agree that doing moderation at a room level for user-scoped data doesn't really make sense. A user's profile can appear through a user search (completely disconnected from a room). You could share multiple rooms with a user, and it'd then be unclear which policyserver to ask.

I like the idea of proactive moderation at the homeserver level. Though I don't think human moderation of all profile updates can really scale. Profiles can appear over through federation transactions (eventually MSC4259) or via manual queries. It's not unreasonable for those to be checked by a locally-configured policyserver before they're sent down to clients.

The recent policyserver system of signing messages doesn't really work here, as every homeserver would probably be using a different policyserver (and wouldn't trust signatures from other ones).

It makes sense to use reasonable metrics like a common direct message to be able to see the profile.

I caution against preventing profiles from being sent to clients entirely. This doesn't matter as much with User Status, but for an m.bio profile field (plus avatar and displayname), I would find that helpful to see before opening a DM with someone, to ensure that I'm messaging the right person. It makes sense for clients to hide this information behind an interaction though.

And in a workplace environment, all users are "trusted" already, so such a barrier likely isn't necessary and will just frustrate people. So it needs to be able to be disabled.

So bottom line: I'm interested in proactive tooling, and am curious what the spec can do here to enable that (another policyserver endpoint?). Currently, I could see implementations mostly solving this on their own by hooking into the profile set/fetch endpoints and sending the request off to a policyserver before allowing/denying the request. The policyserver would be configured in the homeserver config, instead of in room state.


Another important rule would be that the moderator of a room in common with the user should always be able to see their profile (unless the user's profile has been blocked on the server, but they will need to know that it has been blocked so they can ban them).

Future plans in this area involve only sharing a profile with certain users (i.e. your family vs. your more excentric friends). This invites the possibility to hide one profile from room moderators, while showing it to users. However, other messaging apps do allow this (i.e. Telegram) and I'm not aware of this being a problem (perhaps the reporting system works well enough?). You can even change your avatar based on who's looking.

Something to think about for a future "multi-profile" / "profile privacy" MSC.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Future plans in this area involve only sharing a profile with certain users (i.e. your family vs. your more excentric friends). This invites the possibility to hide one profile from room moderators, while showing it to users. However, other messaging apps do allow this (i.e. Telegram) and I'm not aware of this being a problem (perhaps the reporting system works well enough?). You can even change your avatar based on who's looking.

Actually, this is also possible with this proposal by federating one status to one homeserver, and a different one to another.

@Gnuxie Gnuxie Feb 27, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, other messaging apps do allow this (i.e. Telegram) and I'm not aware of this being a problem (perhaps the reporting system works well enough?). You can even change your avatar based on who's lookin

Multiple profiles might not be a problem but user generated content in profiles is a problem and we shouldn't just settle when all the other companies have way more resources than we do to fire hose profiles down than we do. And also the reputational clout and inertia to soak up things going wrong. The direction matrix is heading in at the moment with policy server genuinely makes it close to being a leader in safety. And we should keep going. Yeah no other protocol might not take profiles as seriously as i am proposing here but we should and we should lead.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can write this proposal. But please let's stop looking for excuses out of solving the problem.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, please do!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this proposal written and are you now happy to close this thread?

@Half-Shot
Half-Shot self-requested a review February 25, 2026 20:54
Comment thread proposals/xxxx-messages-custom-state.md Outdated
emoji, even if it’s valid to the client and other clients.


## Alternatives

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about presence? That is what other clients already use and if you start sending out profile change events every time you start or end your call in addition to possible status messages about what song you are currently listening to, you likely have the same performance characteristics as presence events.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Presence was initially considered for this project (and should indeed be listed in the alternatives here). It would not take much to re-use the status_msg field and add a status_msg_emoji field beside it.

But profile fields have a few advantages:

  • They have simple semantics for multiple, distinct fields. This proposal introduces m.status and m.call. But if you eventually add m.music, m.application/game, m.holiday etc. you'd end up with quite a fat presence object with no way for clients to selectively query (or opt-in to selective updates via /sync) parts of it. You'd need to build out those semantics as well.
  • Presence currently exists, but is disabled everywhere. Part of using presence is a political problem: you need to convince everyone to turn it back on. Many homeserver implementations and distributions disable it by default, which would significantly slow the roll-out of any feature built on top of it.
  • Profile fields are a burgeoning feature, but haven't quite crossed the threshold of being widely used yet. We wanted this work to help push it over that line.

I actually initially wanted to build this on presence; finally a reason to refactor it and make it usable! But the above eventually muddied that vision.

I do still want to improve presence - but that's probably best left to an effort specifically targeting/optimising for its featureset (quick online/offline/busy indicators).

And on the performance front:

  1. (We discussed before) that profile updates will generally be much less frequent than presence updates by default. Of course you can limit profile or presence updates however you like on your own homeserver/client. Profile fields make it easy to set different rate-limits/debouncing logic for each field ID, e.g. you could limit m.call updates much more strictly than m.music.
  2. I think limiting who can see which profile will significantly cut down on the traffic. A mechanism for allowing anyone to see your avatar/displayname, but only friends seeing your current song, would go a long way. Presence didn't have such a granular level of user-controlled recipients. I currently have a draft MSC for profile privacy fleshing this out, and will publish it soon.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I expanded on the performance discussion over on the Profile Fields federation MSC: https://github.com/matrix-org/matrix-spec-proposals/pull/4259/files#r2858835260

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And wrote a summary on the MSC itself: d1b8f85.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe an appropriate method of doing this is more akin to the Discord API's custom status system - the "Type" is one of PLAYING/WATCHING/LISTENING TO/STREAMING/etc and then there's free form text. They don't need to be separate fields I feel.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the time elapsed I think we can consider this resolved? There are good grounds presented here for why the existing presence system isn't being used for this.

Users should not put security sensitive information in `m.status`. Clients MAY
wish to remind them of this.

## Privacy Considerations

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Access control for profile look-ups is configured by the homeserver admin and, I think, clients have no way of knowing what the configuration is. Is there a risk here that anyone on the same server could spy on your availability updates?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Access control for profile look-ups is configured by the homeserver admin and, I think, clients have no way of knowing what the configuration is.

It will depend on the homeserver implementation. The spec recommends that 403 always be returned, whether profile lookup is denied or the user does not exist. But Synapse will return a 404 in the latter case.

Is there a risk here that anyone on the same server could spy on your availability updates?

The spec currently requires that profile information should be shared with those users you share a room with. This is based off the old notion that a profile is only an avatar and displayname. It makes sense to always share those with users you share a room with.

Currently I think this is fine, even if you're on matrix.org. I'd want to share my availability with any user that might message me, and that means those users whom I share a room with.

Critically you should not allow sharing profile information if you've only been invited to a room. That would allow anyone to start a DM with you and then fetch your profile without your consent. Homeserver implementations already have this limitation in place this for profiles, though.


There is certainly room for further restricting the circle of who you'd want to share your availability with (just work colleagues, on a public homeserver), but this MSC doesn't aim to address that. An separate MSC I have in the works does, though!

@Johennes Johennes Feb 27, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spec currently requires that profile information should be shared with those users you share a room with.

Yes, I think that is totally sensible. What I'm trying to say is that the spec only declares this as the minimum. It doesn't prevent home servers from allowing profile look-ups regardless of room membership though. The client has no way of knowing what policy the server enforces. So my availability might be made available to anyone on the same server.

This is a problem of profile data in general of course. It just feels like the status introduced here is something that as user I would explicitly not want to share with just anyone.

Maybe a compromise could be to introduce a way for clients to find out what look-up rules the server enforces on profiles, e.g. through a capability?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So my availability might be made available to anyone on the same server.

Or indeed on any server. In general I think this and extensible profile fields is written to assume this is public information unless you know that the homeserver's policy means that it isn't.

My suggestion would be that this would be something for a different MSC as this is not related to these specific profile fields per se.

| Field | Type | Required | Description | Example |
| :---- | :---- | :---- | :---- | :---- |
| `text` | `string` | Yes | The user’s chosen status text. Does not support HTML. Clients MAY choose to linkify links. | “On holiday in …” |
| `emoji` | `string` | Yes | The user’s chosen status emoji. | 🌴 |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Being able to set an emoji is cool but I feel like what's missing is a status category a la available, away, etc. I think it would be a lot more useful if you could tell at a glance whether somebody is available or not without having to decipher the meaning of their status emoji.

Here's what Teams does, for instance:

Image

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like it's treading on the toes of presence a smidge, but unsure. If so, we could potentially standardize on some "m." status messages which helps with a11y-ing.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Different companies and communities will have different cultures. I'm not sure if we need to standardise on a set of emojis and messages for every use case ever. At Element, we usually use: 🤒 (sick), 🌴 (holiday), 👶 (m/paternity leave), etc. But other companies probably have their own set.

It makes sense for certain clients to have certain (configurable) defaults - or even have the homeserver suggest some via /capabilities. But I've specifically avoided hardcoding defaults into the spec. It makes more sense to leave it up to specific enterprises, apps, etc.

If so, we could potentially standardize on some "m." status messages which helps with a11y-ing.

I touched on internationalisation in the MSC:

### Internationalisation
Often a user may set their status in one language, and it will be viewed by a
user who primarily uses another language. This MSC explicitly does not include a
method for setting multiple statuses in multiple languages:
1. This would expand the scope of implementation noticeably.
2. A UI where a user could set multiple statuses in different languages is not
something users are familiar with in messaging apps today.
Clients are free to provide some suggested default status texts and emoji, and
they may do so based on the user's chosen language in the application.
A future MSC may allow setting a different status *per-community*, which would
be a more familiar way for users to communicate in different languages with
different social groups.

Having a specific set of statuses would be a requirement, and the above explains why I don't think that's necessary in practice (maybe it will be after implementation and people try it, who knows!).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't necessarily mean to switch to a fixed set of status messages and emojis. Rather to add another field a la category = available | do_not_disturb | away | ... that would let others quickly recognize the type of availability.

It feels like the freeform text and emoji could introduce quite a bit of ambiguity. For instance, I might be feeling sickly while still working, thus using 🤒, or I might actually be working from the beach, thus using 🌴. There is value in being able to express that via the status. What I really need in a work context though is more of a binary "can I reach this person" cue.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The question that comes to my mind here is how that fields would be populated and how it would be shown, which is to say that whilst this document described the protocol, our design needs to start from user experience and I'm not sure what UX would be applied here, at least when setting a status. Is the aim to make a user's availability machine readable?

My take here is that the approach with this field is to make it more human-driven and richer, conveying this information verbally and avoiding the requirement to pigeon-hole your status into available/busy etc.


| Field | Type | Required | Description | Example |
| :---- | :---- | :---- | :---- | :---- |
| `call_joined_ts` | `number` | No | The time that the user joined the call. Unix timestamp in seconds. This allows users to see how long someone has been in a call. | 1770140640 |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While we're here, maybe we could add an optional presenting field indicating whether the user is currently screen sharing? The rationale is that somebody who's presenting will most definitely not read your messages while being in a call while somebody who's not presenting might.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That feels a little weak to me. For instance, I could be leading a meeting without screen sharing; or I could be sharing a slide deck for someone else who's narrating it, while I'm just listening for the word "next" to hit a button.

It's also a slight metadata leak.

Matrix clients could include this information already, if you're in the room with the call (but not necessarily in the call yourself). MatrixRTC defines events for screen-sharing which your client could pick up in the background and display in a user's profile UI. That eliminates the metadata leak concern as well.

@Johennes Johennes Feb 27, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Teams has this feature for whatever that's worth and I've personally found it useful. It's not a definite metric, true. But it gives you another hint of what the chances are that the other person will read and respond to your message.

I don't see this as a material metadata leak when we're already sharing that you are in a call and since when. I would also see it as an optional property so clients could still choose whether or not to fill it.

All that being said, I don't think this is a critical feature. It might as well be offloaded to a separate proposal if it is deemed controversial.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would probably say deferring this to a separate MSC seems sensible, although I don't have any particular objection to it, I would rather add it in response to clients wanting to use it rather than because we think it's a nice addition to the protocol.

with more than one grapheme. This is due to Unicode byte to grapheme definitions
being continuous added over time.

`m.call`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems weird that this a separate field if it is tied this close to status?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another advantage of the separate field is that it gives a hint to Matrix clients that you're on a call. They can then display that fact separately from your status - or try and pull in more information about the call (title, join link, etc.) if you happen to share a room with the user and they're using MatrixRTC.

The same goes for the theoretical m.holiday field. If a user is explicitly on holiday, you may want to display a much louder warning when trying to message them. See this example from Google Doc's comments UI:


image

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not a field under the m.status though?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that the fields are largely related, and typically if a client wants one of these fields, they probably want both.

But it might still be useful to be able to refer to them separately. Perhaps a company wants to allow their employee to share some pre-defined statuses to partner companies, but keep whether someone is on a call internal-only. Assuming that's realistic, having these be separate fields makes configuring that easier.

The argument is stronger for other field types (such as m.holiday above). Google Docs would only query for m.holiday when you type a comment - not m.status. Or in a world of scoped access tokens, you'd only want to give your HR software access to modifying m.holiday. Perhaps the same argument can be made for separate calling software (e.g. Element Call) and not allowing it to read/modify m.status.

Having these be separate fields out of the gate does set a precedent in that direction, at the very least.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was confused about the split, too, but I think the shape of the profile API (where you read and write by top-level key) and the ability to restrict access to parts of the profile in future are good arguments. 👍

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like this needs to be included in the MSC then.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To clarify, when you say, 'this', you mean the justifications given in these comments should go in?

Comment on lines +50 to +53
Applications SHOULD NOT automatically update this field. It’s intended to be
controlled by the user manually, and it may be confusing for most users if their
manually-set status is overridden by an application they may have no control
over.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be pretty helpful to automatically clear this field out or for the server to set it automatically, this paragraph seems to say these things should not happen.

Additionally, was it considered to add an "end time" to the status?

@anoadragon453 anoadragon453 Feb 26, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@clokep both of your comments (link) are intertwined. m.call as a separate field makes it easier for calling software to avoid accidentally overwriting your manually-set status as you join/leave meetings. As such, m.call is primarily meant to be updated automatically.

Whereas I put the no-automation warning on m.status to dissuade applications from building on it as a mechanism for showing public information about a user (which may then trample on top of a user's manually set status).

The warning is currently quite broad (discouraging automatic updates). And you're right - it does prevent the use case of "please clear this status after I come back from holiday on 08/25" or "after 30m", etc. Which are really nice to have!

So I think this needs to be rewritten or removed. Perhaps we can just trust that applications won't cause bad experiences for users... because then they wouldn't be popular?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rewritten in 8c389db

Comment thread proposals/4426-user-status-profile-fields.md
Comment thread proposals/4426-user-status-profile-fields.md Outdated
added. It is already sent proactively to clients and over federation to other
homeservers.

But profile fields have a few advantages:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Profiles also have disadvantages, the most prominent one being that the data needs to be queried on demand. This makes it infeasible for clients to use the status in room or member lists (where many other messaging systems appear to be including availability information). Maybe it would help to make the intended scenarios in which a client would fetch and display the data a little more explicit?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is entirely unclear to me from this proposal and the current spec, on which basis clients are expected to receive this updated profile information timely enough to be relevant. in practice, many server instances today disable the presence feature - i don't know if that means presence is still expected to be send on profile updates (https://spec.matrix.org/v1.17/client-server-api/#events-on-change-of-profile-information). even still, that event only includes displayname and avatar (and presence) info - not any of the "custom profile fields". the same is true for profile updates propagating via room member event state events.

the implication of no push mechanism for custom profile field updates existing is that clients need to poll. this is somewhat reasonable if we expect the existing m.tz field only to be shown when inspecting a user more closely rather than constantly showing this value in the timeline. such behaviour would only cause rare additional profile lookups and only when a client even supports the feature. in fact i believe profile lookups are generally rare in present day matrix since the default views of a typical client can rely on the fact that (profile) data which is typically constantly shown gets updated via sync. however this MSC introduces different UI expectations: these new fields should also be shown constantly, but to my understanding don't come down /sync yet. this means that with the status quo, clients would need to constantly poll the profiles of O(all users they share a room with), or ideally only those on screen at a given time.

TLDR: @anoadragon453 has adviced me that #4429 and #4262 are in progress in parallel to resolve this concern. I think this MSC needs to make a statement on how it imagines to resolve the issue without those, or if it assumes this resolved by the sync extensions, declare them proper dependencies. At the very least this caveat and perhaps solution proposal should be mentioned.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FTR, element web/mobile's impls use these PRs respectively and their usage of these fields is very much tied to these MSCs. However, I don't know that I would add them as formal dependencies: they're not required for the MSC to be valid and useful in its own right (we could mention them as related).

Comment thread proposals/4426-user-status-profile-fields.md Outdated
Comment thread proposals/4426-user-status-profile-fields.md
There is currently no mechanism to remove multiple fields in a single request,
just as there is no mechanism to set multiple fields at once.

## Potential Issues

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clients that show the contents of the emoji field next to the displayname in a room timeline should be aware of and aim to mitigate a potential impersonation attack.

If a user's displayname is "Bill 🎧", and someone with displayname "Bill" sets "🎧" as their emoji in m.status then clients should take care to not render the users in exactly the same manner, i.e.:

Image

This is made even easier by the fact that non-emoji (and multiple characters) are allowed in the emoji field. For instance, you could easily write someone's last name.

Mitigations include:

  • Visually distinguishing the emoji text from the displayname in some manner (different background, a separator, etc.)
  • Choosing a different font color for text in emoji from the displayname.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Written up in 0ad2889

Comment on lines +47 to +48
*Note: A future MSC may add an additional field to support custom emotes, ala.
[MSC2545](https://github.com/matrix-org/matrix-spec-proposals/pull/2545).*

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want to derail, but I'm curious what you had in mind and a bare minimum sketch of how this evolution would be done, so we can be confident that we have the room to expand this in a compatible-ish way.

e.g. Might it be worth reserving some 'space' to enable this in the future, like saying m.emoji would in the future be a JSON object with appropriate keys for a media URI and a fallback emoji?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would just say add another field alongside emoji, eg. custom_emoji that contains details on the custom emoji, that way the regular emoji could stay as a fallback (although I don't know how clients would decide what fallback emoji to set: most likely a static one).

Comment thread proposals/4426-user-status-profile-fields.md Outdated
Comment thread proposals/4426-user-status-profile-fields.md Outdated
Comment thread proposals/4426-user-status-profile-fields.md Outdated
#### `text` and `emoji` field grammar

The `text` field is encoded UTF-8, and limited to 256 bytes. The `emoji` field
is limited to 32 bytes. Homeservers SHOULD reject statuses that contain fields

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
is limited to 32 bytes. Homeservers SHOULD reject statuses that contain fields
is limited to 32 bytes. Homeservers SHOULD reject clients trying to set statuses over the Client-Server API that contain fields

i suppose this is implicit since federating status is a pull rather than push operation. should my homeserver protect me from profiles exceeding these limits when i request them on the C2S API?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added manually in cd098b2

Comment thread proposals/4426-user-status-profile-fields.md Outdated
Comment on lines +208 to +209
Homeservers should consider implementing limits on both a per-field and entire
profile basis for each user.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since PUT already is rate limited according to spec, this is intended to mean GET?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think not necessarily: clarified a little in 7811556


## Alternatives

### Single `m.status` field

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we know how competing protocols handle the multitude of possible things to put into rich status fields?

i'm not convinced i see the use case to allow more than one. in an office setting, you client might monitor several different sources to populate your status according to some priority, e.g. appointments from you calendar as they start and end, matrixrtc calls or out of band calls, etc. I think the need to keep around a "I am on holiday" status when a call happens in the meantime wouldn't be so high. Either your calendar still has the holiday notice in when you hang up, or this doesn't actually happen.

this basically opens the door to having an infinite amount, making the m.status itself obsolete, and making UX unbearable, to solve a problem i don't see. my tendency is to rather be conservative here instead.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem here is similar to the conflict you mention, although more with a manually set status like, "Focus Time" which you would not want to have to manually reset if your focus time got interrupted by a call. The conclusion was that the system works better if you keep different sources of status separate and aggregate them up into something sensible, especially since we don't live in a world of one client per user.

I disagree that it opens the door to an infinite amount of statuses, there's a difference between a finite, specced collection and an arbitrary list. I also don't understand why the UX would be unbearable. These different fields will be completely invisible to the user: this is now implemented in Element (web + X) if you'd like to see for yourself.

thread](https://github.com/matrix-org/matrix-spec-proposals/pull/4259/files#r2858835260).
It's intended for federation-related performance discussion to continue there.

## Alternatives

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have you considered an array?

PUT /_matrix/client/v3/profile/@alice:example.org/m.status

[{
  "text": "Morning standup",
  "emoji": "📅"
},
{
  "text": "In a call",
  "emoji": "📞"
}]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe so but whilst I think I understand what your example is trying to represent, I don't have a clear image of how a client might be expected to render it? This would take some very strong convincing on my part.

added. It is already sent proactively to clients and over federation to other
homeservers.

But profile fields have a few advantages:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is entirely unclear to me from this proposal and the current spec, on which basis clients are expected to receive this updated profile information timely enough to be relevant. in practice, many server instances today disable the presence feature - i don't know if that means presence is still expected to be send on profile updates (https://spec.matrix.org/v1.17/client-server-api/#events-on-change-of-profile-information). even still, that event only includes displayname and avatar (and presence) info - not any of the "custom profile fields". the same is true for profile updates propagating via room member event state events.

the implication of no push mechanism for custom profile field updates existing is that clients need to poll. this is somewhat reasonable if we expect the existing m.tz field only to be shown when inspecting a user more closely rather than constantly showing this value in the timeline. such behaviour would only cause rare additional profile lookups and only when a client even supports the feature. in fact i believe profile lookups are generally rare in present day matrix since the default views of a typical client can rely on the fact that (profile) data which is typically constantly shown gets updated via sync. however this MSC introduces different UI expectations: these new fields should also be shown constantly, but to my understanding don't come down /sync yet. this means that with the status quo, clients would need to constantly poll the profiles of O(all users they share a room with), or ideally only those on screen at a given time.

TLDR: @anoadragon453 has adviced me that #4429 and #4262 are in progress in parallel to resolve this concern. I think this MSC needs to make a statement on how it imagines to resolve the issue without those, or if it assumes this resolved by the sync extensions, declare them proper dependencies. At the very least this caveat and perhaps solution proposal should be mentioned.

`m.application/game`, `m.holiday` etc. you'd end up with quite a fat presence
object with no way for clients to selectively query (or opt-in to selective
updates via /sync) parts of it. You'd need to build out those semantics as well.
- Presence currently exists, but is disabled *everywhere*. Part of using

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, perhaps by solving presence's problems you would also solve this MSC's problems? There is a significant overlap as stated and essentially this MSC is reintroducing many of the problems that led to presence becoming widely disabled (mostly performance? next privacy?). Why will this one perform better in that area?

@lveneris lveneris Sep 8, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also note that this proposal seems to require a lot of machinery to support. Profile update EDUs, sending those profile updates down sync, et cetera. Given that #4532 now exists, and the performance concerns of presence are being resolved, I would like to see some reconsideration of the mechanisms used in this proposal. The only part of this proposal that is not already covered by presence is m.call (unless there is special casing for the emoji rendering), since the status segment is a duplicate of the status segment of presence. Given that, it would be far easier to just put m.call in an extensible status field of presence than to introduce several other MSCs to enable this one to exist.

Put simply, I am concerned that presence is being reinvented purely because nobody wanted to fix it at the time this was submitted, and that reinventing presence within profiles might be a mistake. That is not a criticism of the goals of this proposal, though.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think #4426 (comment) covers the case for using the existing presence mechanism vs extensible profiles?

@lveneris lveneris Sep 11, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think not, given that there is now only one point made in that comment that still holds, that being the first point about separated fields. This is mentioned primarily for the purposes of future work, where I would expect m.music or m.game to fall within the boundaries of any rich presence efforts, so that is not applicable here (particularly as it is a hypothetical regardless). All that remains is m.status, which is effectively reinventing status_msg as Andrew acknowledged, the emoji field beside it, and m.call. If you take #4532 as a basis, for example, this proposal could be flattened into adding a single field to presence, and whatever would be required for m.call. My concerns remain.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added 5fdf8e6 to talk about the fact that the m.call part could be implemented with extensible presence. Please let me know if there's anything else you think could address this, I'm not certain I've understood all your points or why you believe the points made in that comment are refuted.

@lveneris lveneris Sep 14, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It occurs to me that I probably jumped the gun by leaving that comment. It seemed to me that work on this proposal was picking back up, so it felt necessary, given that I hadn't been able to coordinate a good time with Andrew for him to reevaluate the situation.

What I am saying is ultimately that a discussion needs to be had and a decision needs to be made on whether or not this proposal is the correct way to achieve the goals it lays out. The points in that initial comment are largely no longer true, which is why I dismissed them. Putting presence information in profiles is as peculiar of an idea as putting profiles in presence, because they exist for different reasons and hold different longevities. This proposal did not use presence originally because presence was, at the time, broken and considered to not be worth working on. These things are now being resolved, so the reasoning behind this proposal needs to be reconsidered, especially before other entire mechanisms are added just to make it feasible. That is not something that can be addressed by adding a few lines and moving on.

I hope this clears things up. If you're now responsible for continuing this proposal, and you would like to discuss further, I would be more than happy to do so.

(P.S. your latest commit made a typo in "extensible")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, typo fixed!

I'm not sure I buy that because information has different lifetimes it must live in different places, or that they exist for different reasons: it's all ultimately information about the user themselves. I'm also not 100% up to speed on what work is ongoing to resolve the issues in presence (other than #4532). We should document the current state here, for example updates over federation are still being implemented for extensible profiles but I don't believe there's an MSC yet for presence over sliding sync.

@lveneris lveneris Sep 15, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you recall your own writing on the matter, lifetimes are indeed relevant. Semantically speaking, profiles are intended for long-term identifying information about a user that may evolve over time, while presence is intended for near-term information about the user's state of being. They could perhaps share a store if they did not require differing broadcast mechanisms. This proposal, and indeed the concept of putting any presence in profiles, is contingent on doing all of the work that comes with adding broadcast mechanisms to profiles. I would still not advise trying to have it both ways; either all presence belongs in profiles, or presence should remain separate. This proposal remains a half-measure.

Your note about presence for sliding sync is true, though, and that is on our to-do list. If you are interested in the other work being done, we have #4495, and our own working group of sorts. We would be more than happy to work with you on reconciling the different paths we seem to be taking.

I would also be inclined to note the dubious nature of federated profile update broadcasts. The profile updates MSC is incomplete, in my eyes, and exactly parallels the issues presence had when we started working on it. Profiles should be retrieved at will, not broadcasted, and data will be sent to many wholly disinterested parties in the process of adding federated updates to them. This is part of why they are content-addressable to begin with.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The important context in that MSC is that it was because, "we don't need to update the whole profile each time": as Anoa says, extensible profile don't have this problem and sync subscribers can choose which fields they subscribe to so I still don't quite buy that data needs to be segregated based on how we as spec authors think that clients will want to interact with it.

So I believe this boils down to the choice of either fixing in the spec what information is live-updating ("presence") and then extensible profiles become purely poll-only, or allowing extensible profile data to be used in both ways. Does that seem like a fair summary of the contention?

Also, if you've identified issues with other MSCs, constructive feedback on them would be super useful, especially if you've identified specific things that can be fixed. (I'd caution against the use of terms like, "dubious" and "half-measure" in favour of more targeted and actionable criticism as these can often be misconstrued).


#### `text` and `emoji` field grammar

The `text` field is encoded UTF-8, and limited to 256 bytes. The `emoji` field

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Element clients have found it difficult to design a UI that can handle long user status strings. Other clients may struggle with this as well.

Therefore it may make sense to limit this (currently arbitrary) length to something smaller, such as 32 bytes.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also handle this on the client side, by shortening with "..." If it gets too long

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 13b108d. I think clients are best placed to decide how they might truncate sensibly.

@Tyagiquamar

Copy link
Copy Markdown

Element's product team has aligned on a roughly 30-character status limit: element-hq/element-web#34983 (comment). Element Web PR #35034 is blocked until MSC4426 reflects that agreement. Could this proposal be updated from the current 256-byte text limit, with the intended Unicode counting rule clarified for clients?

@lveneris

lveneris commented Sep 11, 2026 •

Copy link
Copy Markdown

Element's product team has aligned on a roughly 30-character status limit

I do not see any thought having been given to language information density, user preferences, how annoying it would be to come up with a nicely worded status of 31 characters, or the fact that clients of all kinds have rather different interfaces. I would be quite interested to hear the justification for this, especially given the lack of cited platform or spec precedent.

It may also be good to hear from other client teams with their thoughts before considering an update to the value. 32 bytes for the emoji field is also peculiar, while I'm on the subject.

@nvnvnvnvnvnvnv

nvnvnvnvnvnvnv commented Sep 12, 2026 •

Copy link
Copy Markdown

Element's product team has aligned on a roughly 30-character status limit: element-hq/element-web#34983 (comment). Element Web PR #35034 is blocked until MSC4426 reflects that agreement. Could this proposal be updated from the current 256-byte text limit, with the intended Unicode counting rule clarified for clients?

should not be necessary, this can be handled client-side by shortening excessively long statuses with a "...". I don't think this MSC should declare a length limit for statuses.

@dbkr

dbkr commented Sep 15, 2026

Copy link
Copy Markdown
Member

Folks commenting here: remember that github only lets you create threads from comment on specific lines, so if you want your comment to be discussed, please pick a line to add it to (if there's no relevant line, the header of the relevant section is fine). Otherwise, your comments are likely to go into the void.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Client Server Client-Server API kind:feature MSC for not-core and not-maintenance stuff needs-implementation This MSC does not have a qualifying implementation for the SCT to review. The MSC cannot enter FCP. proposal A matrix spec change proposal. Process state. T-Improvement A suggestion for a relatively simple improvement to the protocol

Projects

None yet

Development

Successfully merging this pull request may close these issues.