From f9fcab129dbe3daf1a77a404575e46252b47e94f Mon Sep 17 00:00:00 2001 From: Logan Devine Date: Thu, 30 Apr 2026 11:22:59 -0700 Subject: [PATCH 1/7] Specify Mutual Rooms (MSC2666) Signed-off-by: Logan Devine --- .../client_server/newsfragments/2367.feature | 2 + content/client-server-api/_index.md | 4 + data/api/client-server/mutual_rooms.yaml | 118 ++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 changelogs/client_server/newsfragments/2367.feature create mode 100644 data/api/client-server/mutual_rooms.yaml diff --git a/changelogs/client_server/newsfragments/2367.feature b/changelogs/client_server/newsfragments/2367.feature new file mode 100644 index 00000000..7b470b14 --- /dev/null +++ b/changelogs/client_server/newsfragments/2367.feature @@ -0,0 +1,2 @@ +Specify the `mutual_rooms` API to get rooms in common with another user, as per +[MSC2666](https://github.com/matrix-org/matrix-spec-proposals/pull/2666). diff --git a/content/client-server-api/_index.md b/content/client-server-api/_index.md index 4cdb84ac..7a82406c 100644 --- a/content/client-server-api/_index.md +++ b/content/client-server-api/_index.md @@ -4233,6 +4233,10 @@ users, they should include the display name and avatar URL fields in these events so that clients already have these details to hand, and do not have to perform extra round trips to query it. +### Mutual Rooms + +{{% http-api spec="client-server" api="mutual_rooms" %}} + ## Modules Modules are parts of the Client-Server API which are not universal to diff --git a/data/api/client-server/mutual_rooms.yaml b/data/api/client-server/mutual_rooms.yaml new file mode 100644 index 00000000..1a7583c4 --- /dev/null +++ b/data/api/client-server/mutual_rooms.yaml @@ -0,0 +1,118 @@ +# Copyright 2026 Logan Devine +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +openapi: 3.1.0 +info: + title: Matrix Client-Server Mutual Rooms API + version: 1.0.0 +paths: + /mutual_rooms: + get: + summary: Get the list of rooms that the user shares with another user. + description: |- + Get the list of rooms that the user shares with another user. The + server will return a list of room IDs that the user shares with the + specified `user_id`. + operationId: getMutualRooms + security: + - accessTokenQuery: [] + - accessTokenBearer: [] + parameters: + - in: query + name: user_id + required: true + description: The MXID of the user to check for mutual rooms with. + example: "@alice:example.com" + schema: + type: string + - in: query + name: from + required: false + description: A pagination token from a previous result. + example: next_batch_token + schema: + type: string + responses: + "200": + description: |- + A list of room IDs that the user shares with the specified user. + If the provided `user_id` is not a valid user, the server MUST return an empty list of rooms. + content: + application/json: + schema: + type: object + required: + - joined + - count + properties: + joined: + type: array + description: |- + A list of room IDs where both the authenticated user and `user_id` have a + membership of type `join`. + items: + type: string + example: "!OGEhHVWSdvArJzumhm:matrix.org" + count: + type: integer + description: |- + The number of such rooms. This is the total count even if the response is + batched and joined doesn't include all rooms. This MAY be inaccurate + if the server is unable to calculate the exact number of rooms. + example: 1 + next_batch: + type: string + description: |- + A pagination token to retrieve the next batch of results. This will be absent + if there are no more results to return. + example: next_batch_token + + "400": + description: |- + The user ID provided was [non-compliant](/appendices/#historical-user-ids). + content: + application/json: + schema: + $ref: definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_INVALID_PARAM", + "error": "The user ID provided was invalid" + } + "429": + description: This request was rate-limited. + content: + application/json: + schema: + $ref: definitions/errors/rate_limited.yaml + tags: + - Mutual Rooms +servers: + - url: "{protocol}://{hostname}{basePath}" + variables: + protocol: + enum: + - http + - https + default: https + hostname: + default: localhost:8008 + basePath: + default: /_matrix/client/v1 +components: + securitySchemes: + accessTokenQuery: + $ref: definitions/security.yaml#/accessTokenQuery + accessTokenBearer: + $ref: definitions/security.yaml#/accessTokenBearer From e3155ec85b64d483ff195356512b90faac3e5d84 Mon Sep 17 00:00:00 2001 From: Logan Devine Date: Fri, 1 May 2026 10:42:42 -0700 Subject: [PATCH 2/7] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Logan Devine Co-authored-by: Kévin Commaille <76261501+zecakeh@users.noreply.github.com> --- data/api/client-server/mutual_rooms.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/data/api/client-server/mutual_rooms.yaml b/data/api/client-server/mutual_rooms.yaml index 1a7583c4..4d03d6a7 100644 --- a/data/api/client-server/mutual_rooms.yaml +++ b/data/api/client-server/mutual_rooms.yaml @@ -35,6 +35,8 @@ paths: example: "@alice:example.com" schema: type: string + format: mx-user-id + pattern: "^@" - in: query name: from required: false @@ -62,12 +64,14 @@ paths: membership of type `join`. items: type: string + format: mx-room-id + pattern: "^!" example: "!OGEhHVWSdvArJzumhm:matrix.org" count: type: integer description: |- The number of such rooms. This is the total count even if the response is - batched and joined doesn't include all rooms. This MAY be inaccurate + batched and `joined` doesn't include all rooms. This MAY be inaccurate if the server is unable to calculate the exact number of rooms. example: 1 next_batch: From edb68ea238a996b566a343694daea7cc4b26a5d5 Mon Sep 17 00:00:00 2001 From: Logan Devine Date: Fri, 1 May 2026 10:50:17 -0700 Subject: [PATCH 3/7] Clarify `next_batch` behavior and possible error responses Signed-off-by: Logan Devine --- content/client-server-api/_index.md | 13 +++++++++++++ data/api/client-server/mutual_rooms.yaml | 9 +++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/content/client-server-api/_index.md b/content/client-server-api/_index.md index 7a82406c..cb7087b9 100644 --- a/content/client-server-api/_index.md +++ b/content/client-server-api/_index.md @@ -4237,6 +4237,19 @@ not have to perform extra round trips to query it. {{% http-api spec="client-server" api="mutual_rooms" %}} +#### Server behaviour + +The server may decide that the response to this endpoint is too large, and only return a +subset of the results. In this case, the server should populate the optional field `next_batch` +with an [opaque identifier](/appendices/#opaque-identifiers). The client may then supply +the identifier as the `from` query parameter in a subsequent request, along with the original +`user_id`, to fetch the next batch of responses. This will continue until the server no longer +inserts `next_batch`, meaning there are no further results. + +Batch tokens generated by this endpoint SHOULD be valid for at least 10 minutes, after which, +tokens can expire. Expired tokens SHOULD be handled similar to invalid tokens, and return +a 400 response. + ## Modules Modules are parts of the Client-Server API which are not universal to diff --git a/data/api/client-server/mutual_rooms.yaml b/data/api/client-server/mutual_rooms.yaml index 4d03d6a7..2d764e6c 100644 --- a/data/api/client-server/mutual_rooms.yaml +++ b/data/api/client-server/mutual_rooms.yaml @@ -40,7 +40,10 @@ paths: - in: query name: from required: false - description: A pagination token from a previous result. + description: |- + A pagination token from a previous result. This should be a `next_batch` result from + a previous call to this endpoint. If not provided, the server will return the first + batch of results. example: next_batch_token schema: type: string @@ -83,7 +86,9 @@ paths: "400": description: |- - The user ID provided was [non-compliant](/appendices/#historical-user-ids). + Part of the request was invalid. The `from` token provided was invalid or expired, + the `user_id` parameter was missing, [non-compliant](/appendices/#historical-user-ids), + or was the sender's own user ID. content: application/json: schema: From 7887d4628b59951f8c71ad0fe6d89c606ae47bbf Mon Sep 17 00:00:00 2001 From: Logan Devine Date: Sat, 9 May 2026 09:56:30 -0700 Subject: [PATCH 4/7] split mutual rooms into its own module, add `added-in` line --- content/client-server-api/_index.md | 19 ++----------------- .../client-server-api/modules/mutual_rooms.md | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 17 deletions(-) create mode 100644 content/client-server-api/modules/mutual_rooms.md diff --git a/content/client-server-api/_index.md b/content/client-server-api/_index.md index cb7087b9..ed7e1e9f 100644 --- a/content/client-server-api/_index.md +++ b/content/client-server-api/_index.md @@ -4233,23 +4233,6 @@ users, they should include the display name and avatar URL fields in these events so that clients already have these details to hand, and do not have to perform extra round trips to query it. -### Mutual Rooms - -{{% http-api spec="client-server" api="mutual_rooms" %}} - -#### Server behaviour - -The server may decide that the response to this endpoint is too large, and only return a -subset of the results. In this case, the server should populate the optional field `next_batch` -with an [opaque identifier](/appendices/#opaque-identifiers). The client may then supply -the identifier as the `from` query parameter in a subsequent request, along with the original -`user_id`, to fetch the next batch of responses. This will continue until the server no longer -inserts `next_batch`, meaning there are no further results. - -Batch tokens generated by this endpoint SHOULD be valid for at least 10 minutes, after which, -tokens can expire. Expired tokens SHOULD be handled similar to invalid tokens, and return -a 400 response. - ## Modules Modules are parts of the Client-Server API which are not universal to @@ -4319,6 +4302,7 @@ that profile. | [Third-party Networks](#third-party-networks) | Optional | Optional | Optional | Optional | Optional | | [Threading](#threading) | Optional | Optional | Optional | Optional | Optional | | [Invite permission](#invite-permission) | Optional | Optional | Optional | Optional | Optional | +| [Mutual Rooms](#mutual-rooms) | Optional | Optional | Optional | Optional | Optional | *Please see each module for more details on what clients need to implement.* @@ -4409,3 +4393,4 @@ systems. {{% cs-module name="Recently used emoji" filename="recent_emoji" %}} {{% cs-module name="Threading" filename="threading" %}} {{% cs-module name="Reference relations" filename="reference_relations" %}} +{{% cs-module name="Mutual Rooms" filename="mutual_rooms" %}} diff --git a/content/client-server-api/modules/mutual_rooms.md b/content/client-server-api/modules/mutual_rooms.md new file mode 100644 index 00000000..162e9c71 --- /dev/null +++ b/content/client-server-api/modules/mutual_rooms.md @@ -0,0 +1,19 @@ +### Mutual Rooms + +{{% added-in v="1.19" %}} + +{{% http-api spec="client-server" api="mutual_rooms" %}} + +#### Server behaviour + +The server may decide that the response to this endpoint is too large, and only return a +subset of the results. In this case, the server should populate the optional field `next_batch` +with an [opaque identifier](/appendices/#opaque-identifiers). The client may then supply +the identifier as the `from` query parameter in a subsequent request, along with the original +`user_id`, to fetch the next batch of responses. This will continue until the server no longer +inserts `next_batch`, meaning there are no further results. + +Batch tokens generated by this endpoint SHOULD be valid for at least 10 minutes, after which, +tokens can expire. Expired tokens SHOULD be handled similar to invalid tokens, and return +a 400 response. When a client uses batch tokens, servers MAY omit rooms that the user joined +after the first token was generated. From ab7b7595146354fe23367a3b46317fa7a945e854 Mon Sep 17 00:00:00 2001 From: Logan Devine Date: Mon, 25 May 2026 10:55:43 -0700 Subject: [PATCH 5/7] update changelog entry to include the name of the API Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- changelogs/client_server/newsfragments/2367.feature | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/changelogs/client_server/newsfragments/2367.feature b/changelogs/client_server/newsfragments/2367.feature index 7b470b14..c127c545 100644 --- a/changelogs/client_server/newsfragments/2367.feature +++ b/changelogs/client_server/newsfragments/2367.feature @@ -1,2 +1 @@ -Specify the `mutual_rooms` API to get rooms in common with another user, as per -[MSC2666](https://github.com/matrix-org/matrix-spec-proposals/pull/2666). +Add `GET /mutual_rooms` API, as per [MSC2666](https://github.com/matrix-org/matrix-spec-proposals/pull/2666). From a3a18a2814b2d544c529f8ba2b03d3b2c24b23be Mon Sep 17 00:00:00 2001 From: Logan Devine Date: Mon, 25 May 2026 10:58:18 -0700 Subject: [PATCH 6/7] add 2367.new changelog --- changelogs/client_server/newsfragments/2367.new | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2367.new diff --git a/changelogs/client_server/newsfragments/2367.new b/changelogs/client_server/newsfragments/2367.new new file mode 100644 index 00000000..88520ba9 --- /dev/null +++ b/changelogs/client_server/newsfragments/2367.new @@ -0,0 +1 @@ +Add `GET /_matrix/client/v1/mutual_rooms`, as per [MSC2666](https://github.com/matrix-org/matrix-spec-proposals/pull/2666). From d3dee159e433f257720ba033ae42eb7a24fd6cad Mon Sep 17 00:00:00 2001 From: Logan Devine Date: Wed, 27 May 2026 14:33:15 -0700 Subject: [PATCH 7/7] Delete changelogs/client_server/newsfragments/2367.feature --- changelogs/client_server/newsfragments/2367.feature | 1 - 1 file changed, 1 deletion(-) delete mode 100644 changelogs/client_server/newsfragments/2367.feature diff --git a/changelogs/client_server/newsfragments/2367.feature b/changelogs/client_server/newsfragments/2367.feature deleted file mode 100644 index c127c545..00000000 --- a/changelogs/client_server/newsfragments/2367.feature +++ /dev/null @@ -1 +0,0 @@ -Add `GET /mutual_rooms` API, as per [MSC2666](https://github.com/matrix-org/matrix-spec-proposals/pull/2666).