Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions proposals/4485-featured-endpoint.md

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:

  • Server (offering)
  • Application (using) - ideally multiple

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Should 30x redirects be possible on this endpoint? (3rd time commenting this because I wanted this to be a thread)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

It should be handled in the same way as the other client-server well known endpoints. The spec doesn't specify, but the server-server one must follow redirects

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Side note: looks like it's about to get spec'd #4402

Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# MSC4485: Homeserver feature controls

Currently 'featured homeserver lists' are gaining more attention as community
members think about user onboarding. These would direct new users to homeservers
curated to provide a good experience. However, many homeservers don't have
the ability to accommodate any rate of growth, or a global audience. This
proposal provides a way to give server admins more responsive control over their
visibility on such lists.

## Proposal

This proposal adds a new well-known endpoint, `.well-known/matrix/featured`.
This endpoint responds with the following fields:

```jsonc
{
"display": 0.5, // A number from 0 to 1 defining the probability that this homeserver should be shown in a list, with 0 being never and 1 being always.
"languages": { // optional
"allow": ["en", "en-US", "fr-FR"], // Optional. Language codes that the server should be featured in. If present, should not be shown for other languages.
"deny": ["es"], // Optional. Language codes that the server should *not* be featured in.
},
"geos": { // optional
"allow": ["GB"], // Optional. Country codes that the server should be featured in. If present, should not be shown for other countries.
"deny": ["CN"], // Optional. Country codes that the server should *not* be featured in.
},
}
```

Where language codes are specified, BCP 47 tags MUST be used. Where country
codes are specified, ISO 3166-1 alpha-2 codes MUST be used.

Implementations featuring this server in a list SHOULD fetch this endpoint, and
follow the rules to decide whether the server should be shown to users.

Implementations SHOULD follow the cache control headers specified in the
response, or otherwise MUST NOT cache the response for longer than an hour.
This is because servers MAY dynamically generate the response in reaction to the
amount of registrations they are getting.

To decide whether to show the server, featured homeserver lists should follow
the below algorithm. This MUST be evaluated for each unique user that views
the list:

- If the implementation encounters an error fetching this endpoint, for example
it is missing, it SHOULD NOT display the server. Old lists MAY ignore this if
they have many servers that do not have this endpoint, but should move towards
following this rule over time.
- The implementation MUST generate a number in the range `( 0, 1 ]` with an
approximately uniform distribution - that is from 0, exclusive, to 1,
inclusive. If the result is greater than the value of the `display` property,
it MUST NOT display the server.
- If the `languages` property is present:
- The implementation should fetch the user's configured / spoken languages. If
this is not possible, skip this section
- If the user's primary language is present in the `deny` property, it SHOULD NOT
display the server.
- If the `allow` property is present, and none of the user's spoken languages are
present, it SHOULD NOT display the server.
- If the `geos` property is present:
- The implementation should fetch the user's geolocation, or otherwise their
geographic jurisdiction. If this is not possible, skip this section.
- If the user's geolocation is present in the `deny` property, it MUST NOT display
the server.
- If the `allow` property is present, and the user's geolocation is not present,
it SHOULD NOT display the server.
- Otherwise, it SHOULD display the server.


## Potential issues

Because the algorithm includes randomness, reevaluating the algorithm on
each page load may result in a poor user experience as servers disappear
and reappear. Implementations should seed their random number generation
appropriately to ensure the list remains reasonably stable.
Comment on lines +71 to +74

@Johennes Johennes Jun 8, 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.

Does seeding appropriately mean using a constant seed?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

It probably means persisting the seed in the session, or similar.


Methods for determining a user's geographic region and language often run into
cases where they do not get an accurate or useful result. Because of this,
clients may want to allow manual selection of these values.
Comment thread
Johennes marked this conversation as resolved.

Creating a new `.well-known` endpoint adds another HTTP round-trip for
clients or aggregators who are already fetching other .well-known endpoints
for discovery. This is considered an acceptable tradeoff here, because this
endpoint may want different caching and server-side treatment compared to other
`.well-known` endpoints.

## Alternatives

Homeservers could simply disable registrations, use registration tokens, or
block IPs from certain regions at the reverse-proxy level. However, this creates
a frustrating user experience: the user selects a server from a featured list,
attempts to register, and is met with an error. This proposal is preferable
because it filters the servers before the user attempts to sign up, and avoids
blocking users who already know which server they want to register at.

The `display` property could be a boolean. However, that reduces the ability of
servers to throttle registrations, rather than abruptly cutting them off. That
would make the proposal less useful for servers that want to maintain a specific
rate of growth.

## Security considerations

If a client fetches the rules by itself for evaluation, it leaks technical data
like the IP address to (a potentially large number of) third party servers.
For this reason, and to reduce load on servers, it is heavily recommended that
implementations proxy these rules, potentially bundling them with the server
list itself.
Comment on lines +104 to +106

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.

Does this mean bundling the server list and well-known responses in the client? Or do you mean creating a separate service that hosts them for the client to load?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

A client might have a server list service that returns a response containing a list of vetted servers with each server's respective rules. A stand-alone implementation might build it into the webpage itself.

This explicitly does not mean bundling the responses at compile time (hence proxy), because otherwise servers would no longer be able to update rules on the fly, in response to load or other conditions.


## Unstable prefix

While this endpoint is unstable, it should be served from
`.well-known/continuwuity/featured`

## Dependencies

None