Compare commits

...

19 commits

Author SHA1 Message Date
codedust d55062bc2f
Merge f0affdfa3c into 2aacc1feda 2025-09-22 13:46:45 +01:00
Kévin Commaille 2aacc1feda
Remove legacy mentions (#2186)
Some checks failed
Spec / 🔎 Validate OpenAPI specifications (push) Has been cancelled
Spec / 🔎 Check Event schema examples (push) Has been cancelled
Spec / 🔎 Check OpenAPI definitions examples (push) Has been cancelled
Spec / 🔎 Check JSON Schemas inline examples (push) Has been cancelled
Spec / ⚙️ Calculate baseURL for later jobs (push) Has been cancelled
Spec / 📢 Run towncrier for changelog (push) Has been cancelled
Spell Check / Spell Check with Typos (push) Has been cancelled
Spec / 🐍 Build OpenAPI definitions (push) Has been cancelled
Spec / 📖 Build the spec (push) Has been cancelled
Spec / 🔎 Validate generated HTML (push) Has been cancelled
Spec / 📖 Build the historical backup spec (push) Has been cancelled
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2025-09-21 12:44:16 +03:00
Travis Ralston 2a8c0bc7b8 Return to unstable
Some checks failed
Spec / 🔎 Validate OpenAPI specifications (push) Has been cancelled
Spec / 🔎 Check Event schema examples (push) Has been cancelled
Spec / 🔎 Check OpenAPI definitions examples (push) Has been cancelled
Spec / 🔎 Check JSON Schemas inline examples (push) Has been cancelled
Spec / ⚙️ Calculate baseURL for later jobs (push) Has been cancelled
Spec / 📢 Run towncrier for changelog (push) Has been cancelled
Spell Check / Spell Check with Typos (push) Has been cancelled
Spec / 🐍 Build OpenAPI definitions (push) Has been cancelled
Spec / 📖 Build the spec (push) Has been cancelled
Spec / 🔎 Validate generated HTML (push) Has been cancelled
Spec / 📖 Build the historical backup spec (push) Has been cancelled
2025-09-17 10:48:48 -06:00
Travis Ralston 81a864545f Matrix 1.16 2025-09-17 10:46:16 -06:00
Travis Ralston 671bc674cd Changelog normalization 2025-09-17 10:37:37 -06:00
Johannes Marbach 72a2ebc7ad
Spec PR - MSC4142: Remove unintentional intentional mentions in replies (#2210)
Some checks are pending
Spec / 🔎 Validate OpenAPI specifications (push) Waiting to run
Spec / 🔎 Check Event schema examples (push) Waiting to run
Spec / 🔎 Check OpenAPI definitions examples (push) Waiting to run
Spec / 🔎 Check JSON Schemas inline examples (push) Waiting to run
Spec / ⚙️ Calculate baseURL for later jobs (push) Waiting to run
Spec / 🐍 Build OpenAPI definitions (push) Blocked by required conditions
Spec / 📢 Run towncrier for changelog (push) Waiting to run
Spec / 📖 Build the spec (push) Blocked by required conditions
Spec / 🔎 Validate generated HTML (push) Blocked by required conditions
Spec / 📖 Build the historical backup spec (push) Blocked by required conditions
Spell Check / Spell Check with Typos (push) Waiting to run
2025-09-16 11:14:19 -04:00
Travis Ralston 7bc016bda6
Specification for MSC4311: Create event availability in stripped state (#2207)
Some checks failed
Spec / 🔎 Validate OpenAPI specifications (push) Has been cancelled
Spec / 🔎 Check Event schema examples (push) Has been cancelled
Spec / 🔎 Check OpenAPI definitions examples (push) Has been cancelled
Spec / 🔎 Check JSON Schemas inline examples (push) Has been cancelled
Spec / ⚙️ Calculate baseURL for later jobs (push) Has been cancelled
Spec / 📢 Run towncrier for changelog (push) Has been cancelled
Spell Check / Spell Check with Typos (push) Has been cancelled
Spec / 🐍 Build OpenAPI definitions (push) Has been cancelled
Spec / 📖 Build the spec (push) Has been cancelled
Spec / 🔎 Validate generated HTML (push) Has been cancelled
Spec / 📖 Build the historical backup spec (push) Has been cancelled
* Part 1: Invites

* Part 2: Knocks

* Use correct schema and examples; Remind readers often about formats

* changelogs

* Add schema warning

* Name the objects

* Move changed-in and expand upon it

* Rename the example

* address review feedback
2025-09-12 13:47:13 -06:00
Patrick Cloke fea0b925a0
Add time zone profile field from MSC4175 (#2206)
Some checks failed
Spec / 🔎 Validate OpenAPI specifications (push) Has been cancelled
Spec / 🔎 Check Event schema examples (push) Has been cancelled
Spec / 🔎 Check OpenAPI definitions examples (push) Has been cancelled
Spec / 🔎 Check JSON Schemas inline examples (push) Has been cancelled
Spec / ⚙️ Calculate baseURL for later jobs (push) Has been cancelled
Spec / 📢 Run towncrier for changelog (push) Has been cancelled
Spell Check / Spell Check with Typos (push) Has been cancelled
Spec / 🐍 Build OpenAPI definitions (push) Has been cancelled
Spec / 📖 Build the spec (push) Has been cancelled
Spec / 🔎 Validate generated HTML (push) Has been cancelled
Spec / 📖 Build the historical backup spec (push) Has been cancelled
2025-09-09 12:02:39 -04:00
Kim Brose bfbeb5e257
clarify world_readable history visibility (#2204)
Signed-off-by: HarHarLinks <2803622+HarHarLinks@users.noreply.github.com>
2025-09-09 16:02:51 +01:00
Kim Brose d1a51f7b8c
fix typo in MSC process (#2205)
Co-authored-by: Andrew Morgan <andrew@amorgan.xyz>
2025-09-09 09:02:32 +00:00
V02460 6e16a19ac9
[schema] Application Service Registration meta schema (#2132)
Some checks failed
Spec / 🔎 Validate OpenAPI specifications (push) Has been cancelled
Spec / 🔎 Check Event schema examples (push) Has been cancelled
Spec / 🔎 Check OpenAPI definitions examples (push) Has been cancelled
Spec / 🔎 Check JSON Schemas inline examples (push) Has been cancelled
Spec / ⚙️ Calculate baseURL for later jobs (push) Has been cancelled
Spec / 📢 Run towncrier for changelog (push) Has been cancelled
Spell Check / Spell Check with Typos (push) Has been cancelled
Spec / 🐍 Build OpenAPI definitions (push) Has been cancelled
Spec / 📖 Build the spec (push) Has been cancelled
Spec / 🔎 Validate generated HTML (push) Has been cancelled
Spec / 📖 Build the historical backup spec (push) Has been cancelled
2025-08-27 07:39:05 +01:00
Kévin Commaille 4d4069166d
Upgrade docsy to 0.12.0 (#2160) 2025-08-27 07:35:57 +01:00
Travis Ralston b5ee6adc0f
Remove extraneous v11 tag in v12 auth rules (#2199)
Some checks failed
Spec / 🔎 Validate OpenAPI specifications (push) Has been cancelled
Spec / 🔎 Check Event schema examples (push) Has been cancelled
Spec / 🔎 Check OpenAPI definitions examples (push) Has been cancelled
Spec / 🔎 Check JSON Schemas inline examples (push) Has been cancelled
Spec / ⚙️ Calculate baseURL for later jobs (push) Has been cancelled
Spec / 📢 Run towncrier for changelog (push) Has been cancelled
Spell Check / Spell Check with Typos (push) Has been cancelled
Spec / 🐍 Build OpenAPI definitions (push) Has been cancelled
Spec / 📖 Build the spec (push) Has been cancelled
Spec / 🔎 Validate generated HTML (push) Has been cancelled
Spec / 📖 Build the historical backup spec (push) Has been cancelled
* Remove extraneous v11 tag in v12 auth rules

* Changelog to copy #2193
2025-08-22 21:10:51 +03:00
Travis Ralston f97d2944ae
Room version 12 (#2193)
Some checks failed
Spec / 🔎 Validate OpenAPI specifications (push) Has been cancelled
Spec / 🔎 Check Event schema examples (push) Has been cancelled
Spec / 🔎 Check OpenAPI definitions examples (push) Has been cancelled
Spec / 🔎 Check JSON Schemas inline examples (push) Has been cancelled
Spec / ⚙️ Calculate baseURL for later jobs (push) Has been cancelled
Spec / 📢 Run towncrier for changelog (push) Has been cancelled
Spell Check / Spell Check with Typos (push) Has been cancelled
Spec / 🐍 Build OpenAPI definitions (push) Has been cancelled
Spec / 📖 Build the spec (push) Has been cancelled
Spec / 🔎 Validate generated HTML (push) Has been cancelled
Spec / 📖 Build the historical backup spec (push) Has been cancelled
* Placeholder

* i++

* Room version 12

Template out a v12 room version

Make v12 default, per MSC4304

Update PDU checks and auth event selection per MSC4291

Describe new room_id format per MSC4291

Move v6 depth definition to a component for easier referencing

Move room_id to a component to prep for v12, per MSC4291

Create and use a new room_id component for v12+ per MSC4291

Reflect auth events selection change onto all room versions per MSC4291

The MSC asks the `description` of `auth_events` to be adjusted, however this feels like a better representation of the change.

Add `room_id` format rules and renumber per MSC4291

Reflect change to rule 1.2 per MSC4291

Insert same room_id check to v1-12 auth rules per MSC4307 and MSC4291

Deprecate `predecessor.event_id` per MSC4291

Insert auth rule to validate `additional_creators` per MSC4289

Insert rule for `users` validation of creators and renumber per MSC4289

Define "room creator(s)" per MSC4289

Spec `additional_creators` on create events per MSC4289

Spec `additional_creators` on `/upgrade` per MSC4289

The MSC doesn't mention how to handle unsupported room versions, but the Synapse implementation used for FCP ignores the field in such room versions. This feels like a good approach, and will need clarifying in the MSC too (if accepted at the spec level).

Add notes to `/upgrade` behaviour per MSC4289 and MSC4291

Describe how additional creators work during room creation per MSC4289

Fix default user power level descriptions per MSC4289

Describe tombstone power level changes per MSC4289

Warn clients about event format changes in v12 per MSC4289 and MSC4291

Flag additional room creators support for client reference per MSC4289

Remove TODO now that it's fully addressed

Copy state res into v12 as-is for modification

Apply Modification 1 to SR2.1 per MSC4297

Apply Modification 2 to SR2.1 per MSC4297

Add summary box to the top of SR2.1 for ease of developer reference

Modification 2 was split into items 2 and 3 for further ease of understanding.

Add all the changelogs

`x` is used until a real PR number can be assigned.

Some changelogs are duplicated to the Client-Server API to increase visibility of the changes to v12.

Review: Minor phrasing adjustments in changelogs

Review: Clarify that v12 isn't quite the default yet in the changelog

Review: Clarify to clients that creators are immutable

Review: Improve 'how to parse a domain' advice for legacy apps

Review: Add a bit more detail as to why a room ID might be required

Apply suggestions from code review

Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com>

Clarify that clients can override the tombstone default

Mention creatorship UI label by finishing the Permissions section

We probably should have removed the WIP note in v1.0, but alas.

Add changelog for tombstone changes

Use assigned spec PR number in changelogs

(cherry picked from commit ec81eea7e4532fd398b8013071d6981c97117d9e)
2025-08-14 11:16:00 -06:00
Tom Foster c4bfd2feb8
Spec for MSC4133: Update profile endpoints to support extended fields (#2071)
Some checks failed
Spec / 🔎 Validate OpenAPI specifications (push) Has been cancelled
Spec / 🔎 Check Event schema examples (push) Has been cancelled
Spec / 🔎 Check OpenAPI definitions examples (push) Has been cancelled
Spec / 🔎 Check JSON Schemas inline examples (push) Has been cancelled
Spec / ⚙️ Calculate baseURL for later jobs (push) Has been cancelled
Spec / 📢 Run towncrier for changelog (push) Has been cancelled
Spell Check / Spell Check with Typos (push) Has been cancelled
Spec / 🐍 Build OpenAPI definitions (push) Has been cancelled
Spec / 📖 Build the spec (push) Has been cancelled
Spec / 🔎 Validate generated HTML (push) Has been cancelled
Spec / 📖 Build the historical backup spec (push) Has been cancelled
Signed-off-by: Tom Foster <tom@tcpip.uk>
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
Co-authored-by: Patrick Cloke <clokep@users.noreply.github.com>
Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org>
Co-authored-by: Richard van der Hoff <richard@matrix.org>
2025-08-12 12:17:57 +01:00
Eric Eastwood 04f42ac208
Fix /sync flow referencing incorrect parameter to use with /messages (#2195)
* Fix wrong parameter to use with `/messages`

* Add changelog
2025-08-12 12:12:17 +02:00
Andy Balaam f6d5009959
Clarify that clients should replace events with the most recent replacement by origin_server_ts (#2190)
Some checks failed
Spec / 🔎 Validate OpenAPI specifications (push) Has been cancelled
Spec / 🔎 Check Event schema examples (push) Has been cancelled
Spec / 🔎 Check OpenAPI definitions examples (push) Has been cancelled
Spec / 🔎 Check JSON Schemas inline examples (push) Has been cancelled
Spec / ⚙️ Calculate baseURL for later jobs (push) Has been cancelled
Spec / 📢 Run towncrier for changelog (push) Has been cancelled
Spell Check / Spell Check with Typos (push) Has been cancelled
Spec / 🐍 Build OpenAPI definitions (push) Has been cancelled
Spec / 📖 Build the spec (push) Has been cancelled
Spec / 🔎 Validate generated HTML (push) Has been cancelled
Spec / 📖 Build the historical backup spec (push) Has been cancelled
Signed-off-by: Andy Balaam <andy.balaam@matrix.org>
2025-08-07 11:45:19 +01:00
Kévin Commaille 9c313b099f
Add state_after to /sync (#2187)
Some checks are pending
Spec / 🔎 Validate OpenAPI specifications (push) Waiting to run
Spec / 🔎 Check Event schema examples (push) Waiting to run
Spec / 🔎 Check OpenAPI definitions examples (push) Waiting to run
Spec / 🔎 Check JSON Schemas inline examples (push) Waiting to run
Spec / ⚙️ Calculate baseURL for later jobs (push) Waiting to run
Spec / 🐍 Build OpenAPI definitions (push) Blocked by required conditions
Spec / 📢 Run towncrier for changelog (push) Waiting to run
Spec / 📖 Build the spec (push) Blocked by required conditions
Spec / 🔎 Validate generated HTML (push) Blocked by required conditions
Spec / 📖 Build the historical backup spec (push) Blocked by required conditions
Spell Check / Spell Check with Typos (push) Waiting to run
* Add `state_after` to `/sync`

As per MSC4222.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add changelog

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Improve wording

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Clarify to not use timeline with state_after

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

---------

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2025-08-06 15:49:32 -04:00
Richard van der Hoff 67a2aa4761
Specify a correct spelling for "display name" (#2189)
Some checks are pending
Spec / 🔎 Validate OpenAPI specifications (push) Waiting to run
Spec / 🔎 Check Event schema examples (push) Waiting to run
Spec / 🔎 Check OpenAPI definitions examples (push) Waiting to run
Spec / 🔎 Check JSON Schemas inline examples (push) Waiting to run
Spec / ⚙️ Calculate baseURL for later jobs (push) Waiting to run
Spec / 🐍 Build OpenAPI definitions (push) Blocked by required conditions
Spec / 📢 Run towncrier for changelog (push) Waiting to run
Spec / 📖 Build the spec (push) Blocked by required conditions
Spec / 🔎 Validate generated HTML (push) Blocked by required conditions
Spec / 📖 Build the historical backup spec (push) Blocked by required conditions
Spell Check / Spell Check with Typos (push) Waiting to run
* Specify a correct spelling for "display name"

* RST uses double-backticks
2025-08-06 07:21:58 +01:00
201 changed files with 1809 additions and 512 deletions

View file

@ -1,7 +1,7 @@
name: "Spec"
env:
HUGO_VERSION: 0.139.0
HUGO_VERSION: 0.148.1
PYTHON_VERSION: 3.13
on:

View file

@ -61,7 +61,7 @@ place after an MSC has been accepted, not as part of a proposal itself.
1. Install the extended version (often the OS default) of Hugo:
<https://gohugo.io/getting-started/installing>. Note that at least Hugo
v0.123.1 is required.
v0.146.0 is required.
Alternatively, use the Docker image at
https://hub.docker.com/r/klakegg/hugo/. (The "extended edition" is required

View file

@ -1 +0,0 @@
Minor fixes to JSON schemas.

View file

@ -1 +0,0 @@
Clarify that `format` is required if `formatted_body` is specified.

View file

@ -1 +0,0 @@
The `latest_event` in an aggregated set of thread events uses the same format as the event itself.

View file

@ -1 +0,0 @@
Fix various typos throughout the specification.

View file

@ -1 +0,0 @@
Add `format` query parameter to `GET /state/{eventType}/{stateKey}` to allow fetching metadata of a specific state event.

View file

@ -1 +0,0 @@
Fix various typos throughout the specification.

View file

@ -1 +0,0 @@
Fix various typos throughout the specification.

View file

@ -1 +0,0 @@
Minor fixes to JSON schemas.

View file

@ -0,0 +1 @@
Remove legacy mentions, as per [MSC4210](https://github.com/matrix-org/matrix-spec-proposals/issues/4210).

View file

@ -1 +0,0 @@
Add "placeholder MSC" process definition.

View file

@ -1 +0,0 @@
GitHub actions are now building the OpenAPI `spec/identity-service-api/api.json` file.

View file

@ -8,7 +8,7 @@ enableRobotsTXT = true
# We disable RSS, because (a) it's useless, (b) Hugo seems to generate broken
# links to it when used with a --baseURL (for example, https://spec.matrix.org/v1.4/
# contains `<link rel="alternate" type="application/rss&#43;xml" href="/v1.4/v1.4/index.xml">`).
disableKinds = ["taxonomy", "RSS"]
disableKinds = ["taxonomy", "rss"]
[languages]
[languages.en]
@ -67,7 +67,7 @@ current_version_url = "https://spec.matrix.org/latest"
# The following is used when status = "stable", and is displayed in various UI elements on a released version
# of the spec.
# major = "1"
# minor = "15"
# minor = "16"
# User interface configuration
[params.ui]
@ -134,7 +134,7 @@ sidebar_menu_compact = true
[module]
[module.hugoVersion]
extended = true
min = "0.123.1"
min = "0.146.0"
[[module.imports]]
path = "github.com/matrix-org/docsy"
disable = false

View file

@ -657,27 +657,48 @@ provides no way to encode ASCII punctuation).
#### Room IDs
A room has exactly one room ID. A room ID has the format:
{{% changed-in v="1.16" %}} Room IDs can now appear without a domain depending on
the room version.
A room has exactly one room ID. Room IDs take the form:
!opaque_id
However, the precise format depends upon the [room version specification](/rooms):
some room versions included a `domain` component, whereas more recent room versions
omit the domain and use a base64-encoded hash instead.
Room IDs are case-sensitive and not meant to be human-readable. They are intended
to be used as fully opaque strings by clients, even when a `domain` component is
present.
If the room version requires a `domain` component, room IDs take the following
form:
!opaque_id:domain
The `domain` of a room ID is the [server name](#server-name) of the
homeserver which created the room. The domain is used only for
namespacing to avoid the risk of clashes of identifiers between
different homeservers. There is no implication that the room in
question is still available at the corresponding homeserver.
In such a form, the `opaque_id` is a localpart. The localpart MUST only contain
valid non-surrogate Unicode code points, including control characters, except `:`
and `NUL` (U+0000). The localpart SHOULD only consist of alphanumeric characters
(`A-Z`, `a-z`, `0-9`) when generating them. The `domain` is the [server name](#server-name)
of the homeserver which created the room - it is only used to reduce namespace
collisions. There is no implication that the room in question is still available
at the corresponding homeserver. Combined, the localpart, domain, and `!` sigil
MUST NOT exceed 255 bytes.
Room IDs are case-sensitive. They are not meant to be
human-readable. They are intended to be treated as fully opaque strings
by clients.
When a room version requires the `domain`-less format, room IDs are simply the
[event ID](#event-ids) of the `m.room.create` event using `!` as the sigil instead
of `$`. The grammar is otherwise inherited verbatim.
The localpart of a room ID (`opaque_id` above) may contain any valid
non-surrogate Unicode code points, including control characters, except `:` and `NUL`
(U+0000), but it is recommended to only include ASCII letters and
digits (`A-Z`, `a-z`, `0-9`) when generating them.
{{% boxes/note %}}
Applications which previously relied upon the `domain` in a room ID can instead
parse the [user IDs](#user-identifiers) found in the `m.room.create` event's `sender`.
The length of a room ID, including the `!` sigil and the domain, MUST
NOT exceed 255 bytes.
Though the `m.room.create` event's `additional_creators` (in `content`) may be
used when present, applications should take care when parsing or interpreting the
list. The user IDs in `additional_creators` will have correct grammar, but may
not be real users or may not belong to actual Matrix homeservers.
{{% /boxes/note %}}
#### Room Aliases

View file

@ -1,6 +1,7 @@
---
title: Changelog
type: docs
layout: changelog-index
weight: 1000
---

103
content/changelog/v1.16.md Normal file
View file

@ -0,0 +1,103 @@
---
title: v1.16 Changelog
linkTitle: v1.16
type: docs
layout: changelog
outputs:
- html
- checklist
date: 2025-09-17
---
## Client-Server API
**Deprecations**
- Deprecate `m.set_avatar_url` and `m.set_displayname` capabilities, as per [MSC4133](https://github.com/matrix-org/matrix-spec-proposals/pull/4133). ([#2071](https://github.com/matrix-org/matrix-spec/issues/2071))
**Removed Endpoints**
- Remove unintentional intentional mentions in replies, as per [MSC4142](https://github.com/matrix-org/matrix-spec-proposals/pull/4142). ([#2210](https://github.com/matrix-org/matrix-spec/issues/2210))
**Backwards Compatible Changes**
- Update user profile endpoints to handle custom fields, and add a new `m.profile_fields` capability, as per [MSC4133](https://github.com/matrix-org/matrix-spec-proposals/pull/4133). ([#2071](https://github.com/matrix-org/matrix-spec/issues/2071))
- Add `format` query parameter to `GET /state/{eventType}/{stateKey}` to allow fetching metadata of a specific state event. ([#2175](https://github.com/matrix-org/matrix-spec/issues/2175))
- Add the `use_state_after` query parameter and `state_after` response property to `GET /sync`, as per [MSC4222](https://github.com/matrix-org/matrix-spec-proposals/issues/4222). ([#2187](https://github.com/matrix-org/matrix-spec/issues/2187))
- When upgrading rooms to [room version 12](/rooms/v12), `additional_creators` may be specified on the [`POST /_matrix/client/v3/rooms/{roomId}/upgrade`](/client-server-api/#post_matrixclientv3roomsroomidupgrade) endpoint, as per [MSC4289](https://github.com/matrix-org/matrix-spec-proposals/pull/4289). ([#2193](https://github.com/matrix-org/matrix-spec/issues/2193))
- When creating rooms with [room version 12](/rooms/v12), the `trusted_private_chat` preset should merge the invitees into the supplied `content.additional_creators` in the resulting room, as per [MSC4289](https://github.com/matrix-org/matrix-spec-proposals/pull/4289). ([#2193](https://github.com/matrix-org/matrix-spec/issues/2193))
- In [room version 12](/rooms/v12), the power level of room creators is now infinitely high as per [MSC4289](https://github.com/matrix-org/matrix-spec-proposals/pull/4289). ([#2193](https://github.com/matrix-org/matrix-spec/issues/2193))
- In [room version 12](/rooms/v12), room IDs no longer have a domain component as per [MSC4291](https://github.com/matrix-org/matrix-spec-proposals/pull/4291). ([#2193](https://github.com/matrix-org/matrix-spec/issues/2193))
- When creating rooms with [room version 12](/rooms/v12), the initial power levels will restrict the ability to upgrade rooms by default, as per [MSC4289](https://github.com/matrix-org/matrix-spec-proposals/pull/4289). ([#2193](https://github.com/matrix-org/matrix-spec/issues/2193))
- Add a profile field for a user's time zone, as per [MSC4175](https://github.com/matrix-org/matrix-spec-proposals/pull/4175). ([#2206](https://github.com/matrix-org/matrix-spec/issues/2206))
- Invites and knocks are now expected to contain the `m.room.create` event in their stripped state entries, as per [MSC4311](https://github.com/matrix-org/matrix-spec-proposals/pull/4311). ([#2207](https://github.com/matrix-org/matrix-spec/issues/2207))
**Spec Clarifications**
- Clarify that `format` is required if `formatted_body` is specified. ([#2167](https://github.com/matrix-org/matrix-spec/issues/2167))
- The `latest_event` in an aggregated set of thread events uses the same format as the event itself. ([#2169](https://github.com/matrix-org/matrix-spec/issues/2169))
- Fix various typos throughout the specification. ([#2171](https://github.com/matrix-org/matrix-spec/issues/2171), [#2177](https://github.com/matrix-org/matrix-spec/issues/2177), [#2179](https://github.com/matrix-org/matrix-spec/issues/2179))
- Clarify that clients should replace events with the most recent replacement by `origin_server_ts`. ([#2190](https://github.com/matrix-org/matrix-spec/issues/2190))
- Fix `/sync` flow referencing incorrect parameter to use with `/messages`. ([#2195](https://github.com/matrix-org/matrix-spec/issues/2195))
- Clarify wording around the `world_readable` history visibility setting. Contributed by @HarHarLinks. ([#2204](https://github.com/matrix-org/matrix-spec/issues/2204))
## Server-Server API
**Backwards Compatible Changes**
- `invite_room_state` and `knock_room_state` now have additional requirements and validation depending on the room version, as per [MSC4311](https://github.com/matrix-org/matrix-spec-proposals/pull/4311). ([#2207](https://github.com/matrix-org/matrix-spec/issues/2207))
## Application Service API
No significant changes.
## Identity Service API
No significant changes.
## Push Gateway API
No significant changes.
## Room Versions
**Backwards Compatible Changes**
- Room IDs in room version 12 are now the event ID of the create event with the normal room ID sigil (`!`), as per [MSC4291](https://github.com/matrix-org/matrix-spec-proposals/pull/4291). ([#2193](https://github.com/matrix-org/matrix-spec/issues/2193))
- Room creators are formalized in room version 12 and have infinitely high power level, as per [MSC4289](https://github.com/matrix-org/matrix-spec-proposals/pull/4289). ([#2193](https://github.com/matrix-org/matrix-spec/issues/2193))
- State Resolution is updated in room version 12 to reduce the opportunity for "state resets", as per [MSC4297](https://github.com/matrix-org/matrix-spec-proposals/pull/4297). ([#2193](https://github.com/matrix-org/matrix-spec/issues/2193))
- The default room version is now room version 12, though servers SHOULD keep using room version 11 for a little while, as per [MSC4304](https://github.com/matrix-org/matrix-spec-proposals/pull/4304). ([#2193](https://github.com/matrix-org/matrix-spec/issues/2193))
- Add [room version 12](/rooms/v12) as per [MSC4304](https://github.com/matrix-org/matrix-spec-proposals/pull/4304). ([#2193](https://github.com/matrix-org/matrix-spec/issues/2193), [#2199](https://github.com/matrix-org/matrix-spec/issues/2199))
**Spec Clarifications**
- In room versions 1 through 12, an event's `auth_events` have always needed to belong to the same room as per [MSC4307](https://github.com/matrix-org/matrix-spec-proposals/pull/4307). ([#2193](https://github.com/matrix-org/matrix-spec/issues/2193))
## Appendices
**Backwards Compatible Changes**
- Room IDs can now appear without a domain component in [room version 12](/rooms/v12), as per [MSC4291](https://github.com/matrix-org/matrix-spec-proposals/pull/4291). ([#2193](https://github.com/matrix-org/matrix-spec/issues/2193))
## Internal Changes/Tooling
**Backwards Compatible Changes**
- Add "placeholder MSC" process definition. ([#2157](https://github.com/matrix-org/matrix-spec/issues/2157))
**Spec Clarifications**
- Declare the Application Service Registration schema to follow JSON Schema spec 2020-12. ([#2132](https://github.com/matrix-org/matrix-spec/issues/2132))
- Declare the event schemas to follow JSON Schema spec 2020-12. ([#2132](https://github.com/matrix-org/matrix-spec/issues/2132))
- Upgrade the docsy theme to version 0.12.0. ([#2160](https://github.com/matrix-org/matrix-spec/issues/2160))
- GitHub actions are now building the OpenAPI `spec/identity-service-api/api.json` file. ([#2172](https://github.com/matrix-org/matrix-spec/issues/2172))
- Minor fixes to JSON schemas. ([#2182](https://github.com/matrix-org/matrix-spec/issues/2182))
- Specify a correct spelling for "display name". ([#2189](https://github.com/matrix-org/matrix-spec/issues/2189))
- Fix a grammatical typo on the Matrix Spec Process documentation page. ([#2205](https://github.com/matrix-org/matrix-spec/issues/2205))

View file

@ -2491,8 +2491,66 @@ using an `unstable` version.
When this capability is not listed, clients should use `"1"` as the
default and only stable `available` room version.
### `m.profile_fields` capability
{{% added-in v="1.16" %}}
This capability defines which [profile](#profiles) fields the user is
able to change.
The capability value has a required flag, `enabled`, and two optional lists, `allowed` and
`disallowed`.
When `enabled` is `false`, all profile fields are managed by the server
and the client is not permitted to make any changes.
When `enabled` is `true`, clients are permitted to modify profile fields,
subject to the restrictions implied by the OPTIONAL lists `allowed` and
`disallowed`.
If `allowed` is present, clients can modify only the fields
listed. They SHOULD assume all other fields to be managed by
the server. In this case, `disallowed` has no meaning and should be ignored.
If `disallowed` is present (and `allowed` is not), clients SHOULD assume
that the listed fields are managed by the server. Clients may modify any
fields that are *not* listed, provided `enabled` is `true`.
If neither `allowed` nor `disallowed` is present, clients can modify all fields
without restrictions, provided `enabled` is `true`.
When this capability is not listed, clients SHOULD assume the user is able to change
profile fields without any restrictions, provided the homeserver
advertises a specification version that includes the `m.profile_fields`
capability in the [`/versions`](/client-server-api/#get_matrixclientversions)
response.
An example of the capability API's response for this capability is:
```json
{
"capabilities": {
"m.profile_fields": {
"enabled": true,
"disallowed": ["displayname"]
}
}
}
```
### `m.set_displayname` capability
{{% boxes/note %}}
{{% changed-in v="1.16" %}}
This capability is now deprecated. Clients SHOULD use the
[`m.profile_fields`](/client-server-api/#mprofile_fields-capability)
capability instead.
For backwards compatibility, servers that forbid setting the
`displayname` profile field in the `m.profile_fields` capability
MUST still present this capability with `"enabled": false`.
{{% /boxes/note %}}
This capability has a single flag, `enabled`, to denote whether the user
is able to change their own display name via profile endpoints. Cases for
disabling might include users mapped from external identity/directory
@ -2517,6 +2575,17 @@ An example of the capability API's response for this capability is:
### `m.set_avatar_url` capability
{{% boxes/note %}}
{{% changed-in v="1.16" %}}
This capability is now deprecated. Clients SHOULD use the
[`m.profile_fields`](/client-server-api/#mprofile_fields-capability)
capability instead.
For backwards compatibility, servers that forbid setting the
`avatar_url` profile field in the `m.profile_fields` capability
MUST still present this capability with `"enabled": false`.
{{% /boxes/note %}}
This capability has a single flag, `enabled`, to denote whether the user
is able to change their own avatar via profile endpoints. Cases for
disabling might include users mapped from external identity/directory
@ -2749,6 +2818,14 @@ should be represented as stripped state events when possible:
* [`m.room.canonical_alias`](#mroomcanonical_alias)
* [`m.room.encryption`](#mroomencryption)
{{% changed-in v="1.16" %}} The `m.room.create` event is now **required** in
the following places:
* [`invite_state`](#get_matrixclientv3sync_response-200_invited-room) and
[`knock_state`](#get_matrixclientv3sync_response-200_knocked-room) on
[`/sync`](#get_matrixclientv3sync) responses.
* On [`m.room.member`](#mroommember) events, the `invite_room_state`
and `knock_room_state` under `unsigned` on the event.
{{% boxes/note %}}
Clients should inspect the list of stripped state events and not assume any
particular event is present. The server might include events not described
@ -2779,6 +2856,12 @@ events are not signed and could theoretically be modified, or outdated due to
updates not being sent.
{{% /boxes/warning %}}
{{% boxes/warning %}}
{{% added-in v="1.16" %}} Servers cannot pass through what they receive over
federation to clients as stripped state. Servers are expected to prune the events
into the stripped state schema below before passing the details onto clients.
{{% /boxes/warning %}}
{{% event-fields event_type="stripped_state" %}}
### Size limits
@ -2837,7 +2920,7 @@ most recent message events for each room, as well as the state of the
room at the start of the returned timeline. The response also includes a
`next_batch` field, which should be used as the value of the `since`
parameter in the next call to `/sync`. Finally, the response includes,
for each room, a `prev_batch` field, which can be passed as a `start`
for each room, a `prev_batch` field, which can be passed as a `from`/`to`
parameter to the [`/rooms/<room_id>/messages`](/client-server-api/#get_matrixclientv3roomsroomidmessages) API to retrieve earlier
messages.
@ -3345,27 +3428,49 @@ request.
### Permissions
{{% boxes/note %}}
This section is a work in progress.
{{% /boxes/note %}}
{{% changed-in v="1.16" %}} Updated section to discuss creator power level
in room version 12 and beyond.
Permissions for rooms are done via the concept of power levels - to do
any action in a room a user must have a suitable power level. Power
levels are stored as state events in a given room. The power levels
required for operations and the power levels for users are defined in
`m.room.power_levels`, where both a default and specific users' power
levels can be set. By default all users have a power level of 0, other
than the room creator whose power level defaults to 100. Users can grant
other users increased power levels up to their own power level. For
example, user A with a power level of 50 could increase the power level
of user B to a maximum of level 50. Power levels for users are tracked
per-room even if the user is not present in the room. The keys contained
in `m.room.power_levels` determine the levels required for certain
operations such as kicking, banning and sending state events. See
[m.room.power\_levels](#room-events) for more information.
required for operations and the power levels assigned to specific users
are defined in the `m.room.power_levels` state event. The `m.room.power_levels`
state event additionally defines some defaults, though room creators
are special in that:
Clients may wish to assign names to particular power levels. A suggested
mapping is as follows: - 0 User - 50 Moderator - 100 Admin
* In [room versions](/rooms) 1 through 11, room creators by default
have power level 100 but still can have that level changed by power level
events, by the same rules as other members.
* In [room version 12](/rooms/v12) (and beyond), room creators are
*not* specified in the power levels event and have an infinitely high
power level that is immutable. After room creation, users
cannot be given this same infinitely high power level.
Users can grant other users increased power levels up to their own
power level (or the maximum allowable integer for the room when their
power level is infinitely high). For example, user A with a power level
of 50 could increase the power level of user B to a maximum of level 50.
Power levels for users are tracked per-room even if the user is not
present in the room. The keys contained in `m.room.power_levels` determine
the levels required for certain operations such as kicking, banning, and
sending state events. See [`m.room.power_levels`](#mroompower_levels) for more
information.
Clients may wish to assign names to particular power levels. Most rooms
will use the default power level hierarchy assigned during room creation,
but rooms may still deviate slightly.
A suggested mapping is as follows:
* 0 to `state_default-1` (typically 49): User
* `state_default` to the level required to send `m.room.power_levels` events
minus 1 (typically 99): Moderator
* The level required send `m.room.power_levels` events and above: Administrator
* Creators of the room, in room version 12 and beyond: Creator
Clients may also wish to distinguish "above admin" power levels based on the
level required to send `m.room.tombstone` events.
### Room membership

View file

@ -195,7 +195,7 @@ given event (for example, if an event is edited multiple times). These should
be [aggregated](#aggregations-of-child-events) by the homeserver.
The aggregation format of `m.replace` relationships gives the **most recent**
replacement event, formatted [as normal](#room-event-format).
valid replacement event, formatted [as normal](#room-event-format).
The most recent event is determined by comparing `origin_server_ts`; if two or
more replacement events have identical `origin_server_ts`, the event with the
@ -268,6 +268,11 @@ Client authors are reminded to take note of the requirements for [Validity of
replacement events](#validity-of-replacement-events), and to ignore any
invalid replacement events that are received.
Clients should render the content of the **most recent** valid replacement event. The
most recent event is determined by comparing `origin_server_ts`; if two or more
replacement events have identical `origin_server_ts`, the event with the
lexicographically largest `event_id` is treated as more recent.
##### Permalinks
When creating [links](/appendices/#uris) to events (also known as permalinks),

View file

@ -63,7 +63,8 @@ for sending events:
The following API endpoints are allowed to be accessed by guest accounts
for their own account maintenance:
* [PUT /profile/{userId}/displayname](#put_matrixclientv3profileuseriddisplayname)
* [PUT /profile/{userId}/displayname](#put_matrixclientv3profileuseridkeyname). Guest users may only modify their display name; other profile fields may not be changed.
* {{% added-in v="1.16" %}} [DELETE /profile/{userId}/displayname](#delete_matrixclientv3profileuseridkeyname). Again, guest users may delete their display name but not other profile fields.
* [GET /devices](#get_matrixclientv3devices)
* [GET /devices/{deviceId}](#get_matrixclientv3devicesdeviceid)
* [PUT /devices/{deviceId}](#put_matrixclientv3devicesdeviceid)

View file

@ -16,8 +16,8 @@ The four options for the `m.room.history_visibility` event are:
- `world_readable` - All events while this is the
`m.room.history_visibility` value may be shared by any participating
homeserver with anyone, regardless of whether they have ever joined
the room.
homeserver with any authenticated user, regardless of whether they have
ever joined the room. This includes [guest users](#guest-access).
- `shared` - Previous events are always accessible to newly joined
members. All events in the room are accessible, even those sent when
the member was not a part of the room.
@ -44,7 +44,7 @@ setting at that time was more restrictive.
#### Client behaviour
Clients may want to display a notice that events may be read by
non-joined people if the history visibility is set to `world_readable`.
non-joined users if the history visibility is set to `world_readable`.
#### Server behaviour

View file

@ -3,6 +3,9 @@
{{% changed-in v="1.7" %}}
{{% changed-in v="1.17" %}}: the legacy push rules that looked for mentions in
the `body` of the event were removed.
This module allows users to "mention" other users and rooms within a room event.
This is primarily used as an indicator that the recipient should receive a notification
about the event.
@ -38,19 +41,18 @@ encrypted as normal. To properly process mentions in encrypted rooms, events
must be decrypted first. See [receiving notifications](#receiving-notifications).
{{% /boxes/warning %}}
Note that, for backwards compatibility, push rules such as [`.m.rule.contains_display_name`](#_m_rule_contains_display_name),
[`.m.rule.contains_user_name`](#_m_rule_contains_user_name), and
[`.m.rule.roomnotif`](#_m_rule_roomnotif) continue to match if the `body` of
the event contains the user's display name or ID. To avoid unintentional notifications,
**it is recommended that clients include a `m.mentions` property on each event**.
(If there are no mentions to include it can be an empty object.)
{{% boxes/rationale %}}
{{% boxes/note %}}
In previous versions of the specification, mentioning users was done by
including the user's display name or the localpart of their Matrix ID and room
mentions were done by including the string "@room" in the plaintext `body` of
the event. This was prone to confusing and buggy behaviour.
{{% /boxes/rationale %}}
the event. When the `m.mentions` field was introduced, those push rules were
disabled if the `m.mentions` field was present.
To avoid unintentional notifications with clients and servers that still use
those push rules, **it is recommended that clients still include a `m.mentions`
property on each event**. (If there are no mentions to include it can be an
empty object.)
{{% /boxes/note %}}
#### Client behaviour

View file

@ -382,6 +382,9 @@ The following `alt_aliases` values will NOT match:
**`contains_display_name`**
{{% changed-in v="1.17" %}}: this condition is deprecated and **should not be
used in new push rules**.
This matches messages where `content.body` contains the owner's display name in
that room. This is a separate condition because display names may change and as such
it would be hard to maintain a rule that matched the user's display name. This
@ -413,6 +416,9 @@ Parameters:
#### Predefined Rules
{{% changed-in v="1.17" %}}: the legacy default push rules that looked for
mentions in the `body` of the event were removed.
Homeservers can specify "server-default rules". They operate at a lower
priority than "user-defined rules", except for the `.m.rule.master` rule
which has always a higher priority than any other rule. The `rule_id`
@ -557,41 +563,6 @@ Definition:
}
```
<a id="_m_rule_contains_display_name"></a> **`.m.rule.contains_display_name`**
{{% changed-in v="1.7" %}}
As of `v1.7`, this rule is deprecated and **should only be enabled if the event
does not have an [`m.mentions` property](#definition-mmentions)**.
Matches any message whose content contains the user's current display name
in the room in which it was sent.
Definition:
```json
{
"rule_id": ".m.rule.contains_display_name",
"default": true,
"enabled": true,
"conditions": [
{
"kind": "contains_display_name"
}
],
"actions": [
"notify",
{
"set_tweak": "sound",
"value": "default"
},
{
"set_tweak": "highlight"
}
]
}
```
<a id="_m_rule_is_room_mention"></a> **`.m.rule.is_room_mention`**
{{% added-in v="1.7" %}}
@ -626,44 +597,6 @@ Definition:
}
```
<a id="_m_rule_roomnotif"></a> **`.m.rule.roomnotif`**
{{% changed-in v="1.7" %}}
As of `v1.7`, this rule is deprecated and **should only be enabled if the event
does not have an [`m.mentions` property](#definition-mmentions)**.
Matches any message from a sender with the proper power level whose content
contains the text `@room`, signifying the whole room should be notified of
the event.
Definition:
```json
{
"rule_id": ".m.rule.roomnotif",
"default": true,
"enabled": true,
"conditions": [
{
"kind": "event_match",
"key": "content.body",
"pattern": "@room"
},
{
"kind": "sender_notification_permission",
"key": "room"
}
],
"actions": [
"notify",
{
"set_tweak": "highlight"
}
]
}
```
**<a id="mruletombstone"></a>`.m.rule.tombstone`**
Matches any state event whose type is `m.room.tombstone`. This is
@ -776,39 +709,6 @@ Definition:
}
```
##### Default Content Rules
<a id="_m_rule_contains_user_name"></a> **`.m.rule.contains_user_name`**
{{% changed-in v="1.7" %}}
As of `v1.7`, this rule is deprecated and **should only be enabled if the event
does not have an [`m.mentions` property](#definition-mmentions)**.
Matches any message whose content contains the local part of the user's
Matrix ID, separated by word boundaries.
Definition (as a `content` rule):
```json
{
"rule_id": ".m.rule.contains_user_name",
"default": true,
"enabled": true,
"pattern": "[the local part of the user's Matrix ID]",
"actions": [
"notify",
{
"set_tweak": "sound",
"value": "default"
},
{
"set_tweak": "highlight"
}
]
}
```
##### Default Underride Rules
**`.m.rule.call`**

View file

@ -64,11 +64,16 @@ as if it were to be under `m.relates_to` directly instead.
#### Mentioning the replied to user
In order to notify users of the reply, it may be desirable to include the `sender`
of the replied to event and any users mentioned in that event. See
[user and room mentions](#user-and-room-mentions) for additional information.
{{% boxes/note %}}
{{% changed-in v="1.16" %}}
Clients SHOULD no longer propagate mentioned users in the replied to event.
{{% /boxes/note %}}
An example including mentioning the original sender and other users:
In order to notify users of the reply, it MAY be desirable to include the `sender`
of the replied to event. See [user and room mentions](#user-and-room-mentions) for
additional information.
An example including mentioning the original sender:
```json
{
@ -83,8 +88,6 @@ An example including mentioning the original sender and other users:
"user_ids": [
// The sender of $another_event.
"@alice:example.org",
// Another Matrix ID copied from the m.mentions property of $another_event.
"@bob:example.org"
]
}
},

View file

@ -6,7 +6,7 @@ It is sometimes desirable to offer a preview of a room, where a user can
This can be particularly effective when combined with [Guest Access](#guest-access).
Previews are implemented via the `world_readable` [Room History
Visibility](#room-history-visibility). setting, along with a special version of the [GET
Visibility](#room-history-visibility) setting, along with a special version of the [GET
/events](#get_matrixclientv3events) endpoint.
#### Client behaviour

View file

@ -36,6 +36,17 @@ server:
previous room, no `type` is specified on the new room's create event
either.
{{% boxes/note %}}
{{% added-in v="1.16" %}} If both the new and old [room version](/rooms) support
additional creators, the server will not transfer those additional creators automatically.
They must be explicitly set during the `/upgrade` call.
{{% /boxes/note %}}
{{% boxes/note %}}
{{% added-in v="1.16" %}} When upgrading to room version 12 or later, the `predecessor` field MAY NOT contain
an `event_id`.
{{% /boxes/note %}}
3. Replicates transferable state events to the new room. The exact
details for what is transferred is left as an implementation detail,
however the recommended state events to transfer are:

View file

@ -555,7 +555,7 @@ resolve to the desired MSC, whether it started as an issue or a PR.
Other metadata:
- The MSC number is taken from the GitHub Pull Request ID. This is
carried for the lifetime of the proposal. These IDs do not necessary
carried for the lifetime of the proposal. These IDs do not necessarily
represent a chronological order.
- The GitHub PR title will act as the MSC's title.
- Please link to the spec PR (if any) by adding a "PRs: \#1234" line

View file

@ -36,11 +36,12 @@ Alternatively, consider flipping the column/row organization to be features
up top and versions on the left.
-->
| Feature \ Version | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
|-------------------|---|---|---|---|---|---|---|---|---|----|----|
| **Knocking** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ |
| **Restricted join rules** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ |
| **`knock_restricted` join rule** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ |
| Feature \ Version | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
|-------------------|---|---|---|---|---|---|---|---|---|----|----|----|
| **Knocking** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| **Restricted join rules** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ |
| **`knock_restricted` join rule** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | ✔ |
| **Additional room creators** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ |
## Complete list of room versions
@ -52,9 +53,22 @@ stable and unstable periodically for a variety of reasons, including
discovered security vulnerabilities and age.
Clients should not ask room administrators to upgrade their rooms if the
room is running a stable version. Servers SHOULD use **room version 11** as
room is running a stable version. Servers SHOULD use **room version 12** as
the default room version when creating new rooms.
{{% boxes/note %}}
{{% added-in v="1.16" %}}
Room version 12 is introduced and made default in this specification release.
Servers are encouraged to continue using room version 11 as the default room
version for the early days and weeks following this specification release,
and then gradually switch the default over when they deem appropriate.
<!-- TODO(SCT): Remove this note box in Matrix 1.17 -->
{{% /boxes/note %}}
The available room versions are:
- [Version 1](/rooms/v1) - **Stable**. The initial room version.
@ -76,6 +90,9 @@ The available room versions are:
- [Version 10](/rooms/v10) - **Stable**. Enforces integer-only power levels
and adds `knock_restricted` join rule.
- [Version 11](/rooms/v11) - **Stable**. Clarifies the redaction algorithm.
- [Version 12](/rooms/v12) - **Stable**. Changes room IDs to be hashes of the
create event, formalizes room creators with infinite power level, and iterates
on state resolution.
## Room version grammar

View file

@ -30,10 +30,14 @@ The rules are as follows:
specified by the [auth events
selection](/server-server-api#auth-events-selection)
algorithm described in the server specification, reject.
**Note**: This room version requires an `m.room.create` event to be selected.
3. If there are entries which were themselves rejected under the [checks
performed on receipt of a
PDU](/server-server-api/#checks-performed-on-receipt-of-a-pdu), reject.
4. If there is no `m.room.create` event among the entries, reject.
5. If any event in `auth_events` has a `room_id` which does not match that of
the event being authorised, reject.
3. If the `content` of the `m.room.create` event in the room state has the
property `m.federate` set to `false`, and the `sender` domain of the event
does not match the `sender` domain of the create event, reject.

View file

@ -0,0 +1,4 @@
Events in rooms of this version have the following structure:
{{% definition path="api/server-server/definitions/pdu_v12" %}}

View file

@ -38,10 +38,14 @@ The complete list of rules, as of room version 3, is as follows:
specified by the [auth events
selection](/server-server-api#auth-events-selection)
algorithm described in the server specification, reject.
**Note**: This room version requires an `m.room.create` event to be selected.
3. If there are entries which were themselves rejected under the [checks
performed on receipt of a
PDU](/server-server-api/#checks-performed-on-receipt-of-a-pdu), reject.
4. If there is no `m.room.create` event among the entries, reject.
5. If any event in `auth_events` has a `room_id` which does not match that of
the event being authorised, reject.
3. If the `content` of the `m.room.create` event in the room state has the
property `m.federate` set to `false`, and the `sender` domain of the event
does not match the `sender` domain of the create event, reject.

View file

@ -44,10 +44,14 @@ The rules are as follows:
specified by the [auth events
selection](/server-server-api#auth-events-selection)
algorithm described in the server specification, reject.
**Note**: This room version requires an `m.room.create` event to be selected.
3. If there are entries which were themselves rejected under the [checks
performed on receipt of a
PDU](/server-server-api/#checks-performed-on-receipt-of-a-pdu), reject.
4. If there is no `m.room.create` event among the entries, reject.
5. If any event in `auth_events` has a `room_id` which does not match that of
the event being authorised, reject.
3. If the `content` of the `m.room.create` event in the room state has the
property `m.federate` set to `false`, and the `sender` domain of the event
does not match the `sender` domain of the create event, reject.

View file

@ -120,10 +120,14 @@ The rules are as follows:
specified by the [auth events
selection](/server-server-api#auth-events-selection)
algorithm described in the server specification, reject.
**Note**: This room version requires an `m.room.create` event to be selected.
3. If there are entries which were themselves rejected under the [checks
performed on receipt of a
PDU](/server-server-api/#checks-performed-on-receipt-of-a-pdu), reject.
4. If there is no `m.room.create` event among the entries, reject.
5. If any event in `auth_events` has a `room_id` which does not match that of
the event being authorised, reject.
3. If the `content` of the `m.room.create` event in the room state has the
property `m.federate` set to `false`, and the `sender` domain of the event
does not match the `sender` domain of the create event, reject.

View file

@ -127,10 +127,14 @@ The rules are as follows:
specified by the [auth events
selection](/server-server-api#auth-events-selection)
algorithm described in the server specification, reject.
**Note**: This room version requires an `m.room.create` event to be selected.
3. If there are entries which were themselves rejected under the [checks
performed on receipt of a
PDU](/server-server-api/#checks-performed-on-receipt-of-a-pdu), reject.
4. If there is no `m.room.create` event among the entries, reject.
5. If any event in `auth_events` has a `room_id` which does not match that of
the event being authorised, reject.
3. If the `content` of the `m.room.create` event in the room state has the
property `m.federate` set to `false`, and the `sender` domain of the event
does not match the `sender` domain of the create event, reject.

501
content/rooms/v12.md Normal file
View file

@ -0,0 +1,501 @@
---
title: Room Version 12
type: docs
weight: 100
version: 12
---
This room version builds on [version 11](/rooms/v11), iterating on the state resolution
algorithm, giving room creators infinite power level, and changing the format of room
IDs to be a hash of the create event.
## Client considerations
### Event format
Clients SHOULD observe the following changes to events in this room version:
* Room IDs no longer include a domain component and are instead a hash of the
`m.room.create` event, per below. See the [room ID grammar](/appendices#room-ids)
for more information.
* A concept of "room creators" is formally defined as the `sender` of the `m.room.create`
event *plus* any `additional_creators` from the `m.room.create` event's `content`,
if present. In prior room versions, the only creator was the `sender` of the
`m.room.create` event (or `creator` in much older room versions).
* Room creators have infinitely high power level and cannot be specified in the
`m.room.power_levels` event, nor can they be changed after the room is created.
## Server implementation components
{{% boxes/warning %}}
The information contained in this section is strictly for server
implementors. Applications which use the Client-Server API are generally
unaffected by the intricacies contained here. The section above
regarding client considerations is the resource that Client-Server API
use cases should reference.
{{% /boxes/warning %}}
Room version 12 is based upon room version 11 with the following considerations.
### Event format
{{% rver-fragment name="v12-event-format" %}}
### Authorization rules
Events must be signed by the server denoted by the `sender` property.
The types of state events that affect authorization are:
- [`m.room.create`](/client-server-api#mroomcreate)
- [`m.room.member`](/client-server-api#mroommember)
- [`m.room.join_rules`](/client-server-api#mroomjoin_rules)
- [`m.room.power_levels`](/client-server-api#mroompower_levels)
- [`m.room.third_party_invite`](/client-server-api#mroomthird_party_invite)
{{% boxes/note %}}
Power levels are inferred from defaults when not explicitly supplied.
For example, mentions of the `sender`'s power level can also refer to
the default power level for users in the room.
{{% /boxes/note %}}
{{% boxes/note %}}
{{% added-in v=12 %}} The power level of "room creators" is infinitely high.
Room creators include:
* The user ID denoted by the `sender` of the `m.room.create` event in the room.
* Any user IDs contained in the `additional_creators` array in `content` of the
`m.room.create` event in the room, if `additional_creators` is present.
Room creators cannot be demoted to a lower power level, even through `m.room.power_levels`.
This is reflected in rule 10.4 below.
{{% /boxes/note %}}
{{% boxes/note %}}
`m.room.redaction` events are subject to auth rules in the same way as any other event.
In practice, that means they will normally be allowed by the auth rules, unless the
`m.room.power_levels` event sets a power level requirement for `m.room.redaction`
events via the `events` or `events_default` properties. In particular, the _redact
level_ is **not** considered by the auth rules.
The ability to send a redaction event does not mean that the redaction itself should
be performed. Receiving servers must perform additional checks, as described in
the [Handling redactions](#handling-redactions) section.
{{% /boxes/note %}}
{{% boxes/note %}}
The `m.room.create` event MUST NOT be selected for `auth_events` on events. The
`room_id` (being the `m.room.create` event's ID) implies this instead. This is
reflected in a change to rule 3.2 below.
{{% /boxes/note %}}
The rules are as follows:
1. If type is `m.room.create`:
1. If it has any `prev_events`, reject.
2. {{% changed-in v=12 %}} If the event has a `room_id`, reject.
**Note**: The room ID is the event ID of the event with sigil `!` instead
of `$`.
3. If `content.room_version` is present and is not a recognised
version, reject.
4. {{% added-in v=12 %}} If `additional_creators` is present in `content` and
is not an array of strings where each string passes the same [user ID](/appendices#user-identifiers)
validation applied to `sender`, reject.
5. Otherwise, allow.
2. {{% added-in v=12 %}} If the event's `room_id` is not an event ID for an accepted
(not rejected) `m.room.create` event, with the sigil `!` instead of `$`, reject.
3. Considering the event's `auth_events`:
1. If there are duplicate entries for a given `type` and `state_key` pair,
reject.
2. {{% changed-in v=12 %}} If there are entries whose `type` and `state_key`
don't match those specified by the [auth events selection](/server-server-api#auth-events-selection)
algorithm described in the server specification, reject.
**Note**: In this room version, `m.room.create` MUST NOT be selected.
3. If there are entries which were themselves rejected under the [checks
performed on receipt of a
PDU](/server-server-api/#checks-performed-on-receipt-of-a-pdu), reject.
5. If any event in `auth_events` has a `room_id` which does not match that of
the event being authorised, reject.
4. If the `content` of the `m.room.create` event in the room state has the
property `m.federate` set to `false`, and the `sender` domain of the event
does not match the `sender` domain of the create event, reject.
5. If type is `m.room.member`:
1. If there is no `state_key` property, or no `membership` property in
`content`, reject.
2. If `content` has a `join_authorised_via_users_server`
key:
1. If the event is not validly signed by the homeserver of the user ID denoted
by the key, reject.
3. If `membership` is `join`:
1. If the only previous event is an `m.room.create` and the
`state_key` is the sender of the `m.room.create`, allow.
2. If the `sender` does not match `state_key`, reject.
3. If the `sender` is banned, reject.
4. If the `join_rule` is `invite` or `knock` then allow if
membership state is `invite` or `join`.
5. If the `join_rule` is `restricted` or `knock_restricted`:
1. If membership state is `join` or `invite`, allow.
2. If the `join_authorised_via_users_server` key in `content`
is not a user with sufficient permission to invite other
users, reject.
3. Otherwise, allow.
6. If the `join_rule` is `public`, allow.
7. Otherwise, reject.
4. If `membership` is `invite`:
1. If `content` has a `third_party_invite` property:
1. If *target user* is banned, reject.
2. If `content.third_party_invite` does not have a `signed`
property, reject.
3. If `signed` does not have `mxid` and `token` properties,
reject.
4. If `mxid` does not match `state_key`, reject.
5. If there is no `m.room.third_party_invite` event in the
current room state with `state_key` matching `token`,
reject.
6. If `sender` does not match `sender` of the
`m.room.third_party_invite`, reject.
7. If any signature in `signed` matches any public key in
the `m.room.third_party_invite` event, allow. The public
keys are in `content` of `m.room.third_party_invite` as:
1. A single public key in the `public_key` property.
2. A list of public keys in the `public_keys` property.
8. Otherwise, reject.
2. If the `sender`'s current membership state is not `join`,
reject.
3. If *target user*'s current membership state is `join` or
`ban`, reject.
4. If the `sender`'s power level is greater than or equal to
the *invite level*, allow.
5. Otherwise, reject.
5. If `membership` is `leave`:
1. If the `sender` matches `state_key`, allow if and only if
that user's current membership state is `invite`, `join`,
or `knock`.
2. If the `sender`'s current membership state is not `join`,
reject.
3. If the *target user*'s current membership state is `ban`,
and the `sender`'s power level is less than the *ban level*,
reject.
4. If the `sender`'s power level is greater than or equal to
the *kick level*, and the *target user*'s power level is
less than the `sender`'s power level, allow.
5. Otherwise, reject.
6. If `membership` is `ban`:
1. If the `sender`'s current membership state is not `join`,
reject.
2. If the `sender`'s power level is greater than or equal to
the *ban level*, and the *target user*'s power level is less
than the `sender`'s power level, allow.
3. Otherwise, reject.
7. If `membership` is `knock`:
1. If the `join_rule` is anything other than `knock` or
`knock_restricted`, reject.
2. If `sender` does not match `state_key`, reject.
3. If the `sender`'s current membership is not `ban`, `invite`,
or `join`, allow.
4. Otherwise, reject.
8. Otherwise, the membership is unknown. Reject.
6. If the `sender`'s current membership state is not `join`, reject.
7. If type is `m.room.third_party_invite`:
1. Allow if and only if `sender`'s current power level is greater
than or equal to the *invite level*.
8. If the event type's *required power level* is greater than the
`sender`'s power level, reject.
9. If the event has a `state_key` that starts with an `@` and does not
match the `sender`, reject.
10. If type is `m.room.power_levels`:
1. If any of the properties `users_default`, `events_default`, `state_default`,
`ban`, `redact`, `kick`, or `invite` in `content` are present and
not an integer, reject.
2. If either of the properties `events` or `notifications` in `content`
are present and not an object with values that are integers,
reject.
3. If the `users` property in `content` is not an object with keys that
are valid user IDs with values that are integers, reject.
4. {{% added-in v=12 %}} If the `users` property in `content` contains the
`sender` of the `m.room.create` event or any of the `additional_creators`
array (if present) from the `content` of the `m.room.create` event, reject.
5. If there is no previous `m.room.power_levels` event in the room,
allow.
6. For the properties `users_default`, `events_default`, `state_default`,
`ban`, `redact`, `kick`, `invite` check if they were added,
changed or removed. For each found alteration:
1. If the current value is higher than the `sender`'s current
power level, reject.
2. If the new value is higher than the `sender`'s current power
level, reject.
7. For each entry being changed in, or removed from, the `events` or
`notifications` properties:
1. If the current value is greater than the `sender`'s current
power level, reject.
8. For each entry being added to, or changed in, the `events` or
`notifications` properties:
1. If the new value is greater than the `sender`'s current power
level, reject.
9. For each entry being changed in, or removed from, the `users` property,
other than the `sender`'s own entry:
1. If the current value is greater than or equal to the `sender`'s
current power level, reject.
10. For each entry being added to, or changed in, the `users` property:
1. If the new value is greater than the `sender`'s current power
level, reject.
10. Otherwise, allow.
11. Otherwise, allow.
{{% boxes/note %}}
Some consequences of these rules:
- Unless you are a member of the room, the only permitted operations
(apart from the initial create/join) are: joining a public room;
accepting or rejecting an invitation to a room.
- To unban somebody, you must have power level greater than or equal
to both the kick *and* ban levels, *and* greater than the target
user's power level.
{{% /boxes/note %}}
### State resolution
{{% boxes/note %}}
{{% added-in v=12 %}} This state resolution algorithm is largely the same as the
algorithm found in [room version 2](/rooms/v2) with the following modifications:
1. The *iterative auth checks algorithm* in the [Algorithm](#algorithm) subsection
now starts with an *empty* state map instead of the unconflicted state map.
2. A new [definition](#definitions) for *conflicted state subgraph* has been added
which describes events that are required to authorize events during iterative
auth checks.
3. To ensure the new conflicted state subgraph is actually referenced, the definition
for *full conflicted set* additionally includes the subgraph.
{{% /boxes/note %}}
The room state *S(E)* after an event *E* is defined in terms of the
room state *S(E)* before *E*, and depends on whether *E* is a state
event or a message event:
- If *E* is a message event, then *S(E)*=*S(E)*.
- If *E* is a state event, then *S(E)* is *S(E)*, except that its
entry corresponding to the `event_type` and `state_key` of *E* is
replaced by the `event_id` of *E*.
The room state *S(E)* before *E* is the *resolution* of the set of
states {*S(E*<sub>1</sub>*)*,*S(E*<sub>2</sub>*)*, …}
after the `prev_event`s {*E*<sub>1</sub>,*E*<sub>2</sub>, …} of *E*.
The resolution of a set of states is given in the algorithm below.
#### Definitions
The state resolution algorithm for version 2 rooms uses the following
definitions, given the set of room states
{*S*<sub>1</sub>,*S*<sub>2</sub>, …}:
**Power events.**
A *power event* is a state event with type `m.room.power_levels` or
`m.room.join_rules`, or a state event with type `m.room.member` where
the `membership` is `leave` or `ban` and the `sender` does not match the
`state_key`. The idea behind this is that power events are events that
might remove someone's ability to do something in the room.
**Unconflicted state map and conflicted state set.**
The keys of the state maps *S<sub>i</sub>* are 2-tuples of strings of the form
*K* = `(event_type, state_key)`. The values *V* are state events.
The key-value pairs (*K*, *V*) across all state maps *S<sub>i</sub>* can be
divided into two collections.
If a given key *K* is present in every *S<sub>i</sub>* with the same value *V*
in each state map, then the pair (*K*, *V*) belongs to the *unconflicted state map*.
Otherwise, *V* belongs to the *conflicted state set*.
Note that the unconflicted state map only has one event for each key *K*,
whereas the conflicted state set may contain multiple events with the same key.
**Auth chain.**
The *auth chain* of an event *E* is the set containing all of *E*'s auth events,
all of *their* auth events, and so on recursively, stretching back to the
start of the room. Put differently, these are the events reachable by walking
the graph induced by an event's `auth_events` links.
**Auth difference.**
The *auth difference* is calculated by first calculating the full auth
chain for each state *S*<sub>*i*</sub>, that is the union of the auth
chains for each event in *S*<sub>*i*</sub>, and then taking every event
that doesn't appear in every auth chain. If *C*<sub>*i*</sub> is the
full auth chain of *S*<sub>*i*</sub>, then the auth difference is
*C*<sub>*i*</sub> − ∩ *C*<sub>*i*</sub>.
{{% added-in v=12 %}} **Conflicted state subgraph.**
Starting from an event in the *conflicted state set* and following `auth_events`
edges may lead to another event in the conflicted state set. The union of all
such paths between any pair of events in the conflicted state set (including
endpoints) forms a subgraph of the original `auth_event` graph, called the
*conflicted state subgraph*.
{{% changed-in v=12 %}} **Full conflicted set.**
The *full conflicted set* is the union of the conflicted state set, the conflicted
state subgraph, and the auth difference.
**Reverse topological power ordering.**
The *reverse topological power ordering* of a set of events is the
lexicographically smallest topological ordering based on the DAG formed
by auth events. The reverse topological power ordering is ordered from
earliest event to latest. For comparing two topological orderings to
determine which is the lexicographically smallest, the following
comparison relation on events is used: for events *x* and *y*,
*x*&lt;*y* if
1. *x*'s sender has *greater* power level than *y*'s sender, when
looking at their respective `auth_event`s; or
2. the senders have the same power level, but *x*'s `origin_server_ts`
is *less* than *y*'s `origin_server_ts`; or
3. the senders have the same power level and the events have the same
`origin_server_ts`, but *x*'s `event_id` is *less* than *y*'s
`event_id`.
The reverse topological power ordering can be found by sorting the
events using Kahn's algorithm for topological sorting, and at each step
selecting, among all the candidate vertices, the smallest vertex using
the above comparison relation.
**Mainline ordering.**
Let *P* = *P*<sub>0</sub> be an `m.room.power_levels` event.
Starting with *i* = 0, repeatedly fetch *P*<sub>*i*+1</sub>, the
`m.room.power_levels` event in the `auth_events` of *P<sub>i</sub>*.
Increment *i* and repeat until *P<sub>i</sub>* has no `m.room.power_levels`
event in its `auth_events`.
The *mainline of P*<sub>0</sub> is the list of events
[*P*<sub>0</sub> , *P*<sub>1</sub>, ... , *P<sub>n</sub>*],
fetched in this way.
Let *e* = *e<sub>0</sub>* be another event (possibly another
`m.room.power_levels` event). We can compute a similar list of events
[*e*<sub>1</sub>, ..., *e<sub>m</sub>*],
where *e*<sub>*j*+1</sub> is the `m.room.power_levels` event in the
`auth_events` of *e<sub>j</sub>* and where *e<sub>m</sub>* has no
`m.room.power_levels` event in its `auth_events`. (Note that the event we
started with, *e<sub>0</sub>*, is not included in this list. Also note that it
may be empty, because *e* may not cite an `m.room.power_levels` event in its
`auth_events` at all.)
Now compare these two lists as follows.
* Find the smallest index *j* ≥ 1 for which *e<sub>j</sub>* belongs to the
mainline of *P*.
* If such a *j* exists, then *e<sub>j</sub>* = *P<sub>i</sub>* for some unique
index *i* ≥ 0. Otherwise set *i* = ∞, where ∞ is a sentinel value greater
than any integer.
* In both cases, the *mainline position* of *e* is *i*.
Given mainline positions calculated from *P*, the *mainline ordering based on* *P* of a set of events is the ordering,
from smallest to largest, using the following comparison relation on
events: for events *x* and *y*, *x*&lt;*y* if
1. the mainline position of *x* is **greater** than
the mainline position of *y* (i.e. the auth chain of
*x* is based on an earlier event in the mainline than *y*); or
2. the mainline positions of the events are the same, but *x*'s
`origin_server_ts` is *less* than *y*'s `origin_server_ts`; or
3. the mainline positions of the events are the same and the events have the
same `origin_server_ts`, but *x*'s `event_id` is *less* than *y*'s
`event_id`.
**Iterative auth checks.**
The *iterative auth checks algorithm* takes as input an initial room
state and a sorted list of state events, and constructs a new room state
by iterating through the event list and applying the state event to the
room state if the state event is allowed by the [authorization
rules](/server-server-api#authorization-rules).
If the state event is not allowed by the authorization rules, then the
event is ignored. If a `(event_type, state_key)` key that is required
for checking the authorization rules is not present in the state, then
the appropriate state event from the event's `auth_events` is used if
the auth event is not rejected.
#### Algorithm
The *resolution* of a set of states is obtained as follows:
1. Select the set *X* of all *power events* that appear in the *full
conflicted set*. For each such power event *P*, enlarge *X* by adding
the events in the auth chain of *P* which also belong to the full
conflicted set. Sort *X* into a list using the *reverse topological
power ordering*.
2. {{% changed-in v=12 %}} Apply the *iterative auth checks algorithm*,
starting from an *empty* state map, to the list of events from the previous
step to get a partially resolved state.
3. Take all remaining events that weren't picked in step 1 and order
them by the mainline ordering based on the power level in the
partially resolved state obtained in step 2.
4. Apply the *iterative auth checks algorithm* on the partial resolved
state and the list of events from the previous step.
5. Update the result by replacing any event with the event with the
same key from the *unconflicted state map*, if such an event exists,
to get the final resolved state.
#### Rejected events
Events that have been rejected due to failing auth based on the state at
the event (rather than based on their auth chain) are handled as usual
by the algorithm, unless otherwise specified.
Note that no events rejected due to failure to auth against their auth
chain should appear in the process, as they should not appear in state
(the algorithm only uses events that appear in either the state sets or
in the auth chain of the events in the state sets).
{{% boxes/rationale %}}
This helps ensure that different servers' view of state is more likely
to converge, since rejection state of an event may be different. This
can happen if a third server gives an incorrect version of the state
when a server joins a room via it (either due to being faulty or
malicious). Convergence of state is a desirable property as it ensures
that all users in the room have a (mostly) consistent view of the state
of the room. If the view of the state on different servers diverges it
can lead to bifurcation of the room due to e.g. servers disagreeing on
who is in the room.
Intuitively, using rejected events feels dangerous, however:
1. Servers cannot arbitrarily make up state, since they still need to
pass the auth checks based on the event's auth chain (e.g. they
can't grant themselves power levels if they didn't have them
before).
2. For a previously rejected event to pass auth there must be a set of
state that allows said event. A malicious server could therefore
produce a fork where it claims the state is that particular set of
state, duplicate the rejected event to point to that fork, and send
the event. The duplicated event would then pass the auth checks.
Ignoring rejected events would therefore not eliminate any potential
attack vectors.
{{% /boxes/rationale %}}
Rejected auth events are deliberately excluded from use in the iterative
auth checks, as auth events aren't re-authed (although non-auth events
are) during the iterative auth checks.
## Unchanged from v11
The following sections have not been modified since v11, but are included for
completeness.
### Redactions
{{% rver-fragment name="v11-redactions" %}}
### Handling redactions
{{% rver-fragment name="v3-handling-redactions" %}}
### Event IDs
{{% rver-fragment name="v4-event-ids" %}}
### Canonical JSON
{{% rver-fragment name="v6-canonical-json" %}}
### Signing key validity period
{{% rver-fragment name="v5-signing-requirements" %}}

View file

@ -102,10 +102,14 @@ The rules are as follows:
specified by the [auth events
selection](/server-server-api#auth-events-selection)
algorithm described in the server specification, reject.
**Note**: This room version requires an `m.room.create` event to be selected.
3. If there are entries which were themselves rejected under the [checks
performed on receipt of a
PDU](/server-server-api/#checks-performed-on-receipt-of-a-pdu), reject.
4. If there is no `m.room.create` event among the entries, reject.
5. If any event in `auth_events` has a `room_id` which does not match that of
the event being authorised, reject.
3. If the `content` of the `m.room.create` event in the room state has the
property `m.federate` set to `false`, and the `sender` domain of the event
does not match the `sender` domain of the create event, reject.

View file

@ -81,10 +81,14 @@ The rules are as follows:
specified by the [auth events
selection](/server-server-api#auth-events-selection)
algorithm described in the server specification, reject.
**Note**: This room version requires an `m.room.create` event to be selected.
3. If there are entries which were themselves rejected under the [checks
performed on receipt of a
PDU](/server-server-api/#checks-performed-on-receipt-of-a-pdu), reject.
4. If there is no `m.room.create` event among the entries, reject.
5. If any event in `auth_events` has a `room_id` which does not match that of
the event being authorised, reject.
3. If the `content` of the `m.room.create` event in the room state has the
property `m.federate` set to `false`, and the `sender` domain of the event
does not match the `sender` domain of the create event, reject.

View file

@ -119,7 +119,7 @@ to send. The process overall is as follows:
server must present a valid certificate for the hostname.
3. If the hostname is not an IP literal, a regular HTTPS request is
made to `https://<hostname>/.well-known/matrix/server` (according to
made to `https://<hostname>/.well-known/matrix/server` (according to
[RFC 8615](https://datatracker.ietf.org/doc/html/rfc8615)), expecting
the schema defined later in this section. 30x redirects should be
followed, however redirection loops should be avoided. Responses
@ -461,9 +461,12 @@ specification](/rooms).
Whenever a server receives an event from a remote server, the receiving
server must ensure that the event:
1. Is a valid event, otherwise it is dropped. For an event to be valid, it
must contain a `room_id`, and it must comply with the event format of
that [room version](/rooms).
1. {{% changed-in v="1.16" %}} Is a valid event, otherwise it is dropped. For
an event to be valid, it must comply with the event format of that [room version](/rooms).
For some room versions, a `room_id` may also be required on the event in order
to determine the room version to check the event against. See the event format
section of the [room version specifications](/rooms) for details on when it
is required.
2. Passes signature checks, otherwise it is dropped.
3. Passes hash checks, otherwise it is redacted before being processed
further.
@ -529,7 +532,8 @@ the sender permission to send the event. The `auth_events` for the
`m.room.create` event in a room is empty; for other events, it should be
the following subset of the room state:
- The `m.room.create` event.
- {{% changed-in v="1.16" %}} Depending on the [room version](/rooms), the
`m.room.create` event.
- The current `m.room.power_levels` event, if any.
@ -941,6 +945,18 @@ Note that invites are used to indicate that knocks were accepted. As such,
receiving servers should be prepared to manually link up a previous knock
to an invite if the invite event does not directly reference the knock.
{{% boxes/note %}}
{{% added-in v="1.16" %}} `invite_room_state` MUST now have its entries formatted
according to the room's version (see [room version specification](/rooms)). However,
servers SHOULD consider their local ecosystems before returning the described
`400 M_MISSING_PARAM` error code. While migrating, servers SHOULD warn about
invites which fail the validation rather than error in room versions 1 through 11.
All invites to other room versions which fail validation SHOULD result in an error.
The specification suggests that servers finish their migration no later than
January 2026, though servers may extend this as required to support their users.
{{% /boxes/note %}}
{{% http-api spec="server-server" api="invites-v1" %}}
{{% http-api spec="server-server" api="invites-v2" %}}
@ -1050,7 +1066,7 @@ from the user owning the invited third-party identifier.
## Published Room Directory
To complement the [room directory in the Client-Server API](/client-server-api#published-room-directory),
To complement the [room directory in the Client-Server API](/client-server-api#published-room-directory),
homeservers need a way to query the published rooms of another server.
This can be done by making a request to the `/publicRooms` endpoint for
the server the room directory should be retrieved for.

View file

@ -11,6 +11,7 @@
# 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.
$schema: https://json-schema.org/draft/2020-12/schema
type: array
items:

View file

@ -11,6 +11,7 @@
# 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.
$schema: https://json-schema.org/draft/2020-12/schema
type: object
title: Registration

View file

@ -73,11 +73,25 @@ paths:
- default
- available
m.set_displayname:
deprecated: true
$ref: '#/components/schemas/booleanCapability'
description: Capability to indicate if the user can change their display name.
description: |
**Deprecated:** Capability to indicate if the user can change their display name.
Refer to `m.profile_fields` for extended profile management.
For backwards compatibility, servers that directly or indirectly include the
`displayname` profile field in the `m.profile_fields` capability MUST also
set this capability accordingly.
m.set_avatar_url:
deprecated: true
$ref: '#/components/schemas/booleanCapability'
description: Capability to indicate if the user can change their avatar.
description: |
**Deprecated:** Capability to indicate if the user can change their avatar.
Refer to `m.profile_fields` for extended profile management.
For backwards compatibility, servers that directly or indirectly include the
`avatar_url` profile field in the `m.profile_fields` capability MUST also
set this capability accordingly.
m.3pid_changes:
$ref: '#/components/schemas/booleanCapability'
description: Capability to indicate if the user can change 3PID associations
@ -86,6 +100,47 @@ paths:
$ref: '#/components/schemas/booleanCapability'
description: Capability to indicate if the user can generate tokens to log further
clients into their account.
m.profile_fields:
x-addedInMatrixVersion: "1.16"
type: object
title: ProfileFieldsCapability
description: Capability to indicate if the user can set or modify extended profile fields via
[`PUT /_matrix/client/v3/profile/{userId}/{keyName}`](/client-server-api/#put_matrixclientv3profileuseridkeyname).
If absent, clients SHOULD assume custom profile fields are supported, provided the
homeserver advertises a specification version that includes `m.profile_fields` in the
[`/versions`](/client-server-api/#get_matrixclientversions) response.
properties:
allowed:
type: array
description: |
If present, a list of profile fields that clients are allowed to create, modify or delete,
provided `enabled` is `true`; no other profile fields may be changed.
If absent, clients may set all profile fields except those forbidden by the `disallowed`
list, where present.
items:
type: string
example:
- "m.example_field"
- "org.example.job_title"
disallowed:
type: array
description: |
This property has no meaning if `allowed` is also specified.
Otherwise, if present, a list of profile fields that clients are _not_ allowed to create, modify or delete.
Provided `enabled` is `true`, clients MAY assume that they can set any profile field which is not
included in this list.
items:
type: string
example:
- "org.example.managed_field"
enabled:
type: boolean
description: "`true` if the user can create, update or delete any profile fields, `false` otherwise."
example: true
required:
- enabled
examples:
response:
value: {

View file

@ -33,9 +33,23 @@ paths:
2. An `m.room.member` event for the creator to join the room. This is
needed so the remaining events can be sent.
3. A default `m.room.power_levels` event, giving the room creator
(and not other members) permission to send state events. Overridden
by the `power_level_content_override` parameter.
3. A default `m.room.power_levels` event. Overridden by the
`power_level_content_override` parameter.
In [room versions](/rooms) 1 through 11, the room creator (and not
other members) will be given permission to send state events.
In room versions 12 and later, the room creator is given infinite
power level and cannot be specified in the `users` field of
`m.room.power_levels`, so is not listed explicitly.
**Note**: For `trusted_private_chat`, the users specified in the
`invite` parameter SHOULD also be appended to `additional_creators`
by the server, per the `creation_content` parameter.
If the room's version is 12 or higher, the power level for sending
`m.room.tombstone` events MUST explicitly be higher than `state_default`.
For example, set to 150 instead of 100.
4. An `m.room.canonical_alias` event if `room_alias_name` is given.
@ -61,8 +75,10 @@ paths:
The server will create a `m.room.create` event in the room with the
requesting user as the creator, alongside other keys provided in the
`creation_content`.
`creation_content` or implied by behaviour of `creation_content`.
operationId: createRoom
x-changedInMatrixVersion:
"1.16": Added server behaviour for how the initial power levels change depending on room version.
security:
- accessTokenQuery: []
- accessTokenBearer: []
@ -142,11 +158,20 @@ paths:
creation_content:
title: CreationContent
type: object
x-changedInMatrixVersion:
"1.16": Added server behaviour for how to handle `trusted_private_chat` and invited users.
description: |-
Extra keys, such as `m.federate`, to be added to the content
of the [`m.room.create`](/client-server-api/#mroomcreate) event. The server will overwrite the following
of the [`m.room.create`](/client-server-api/#mroomcreate) event.
The server will overwrite the following
keys: `creator`, `room_version`. Future versions of the specification
may allow the server to overwrite other keys.
When using the `trusted_private_chat` preset, the server SHOULD combine
`additional_creators` specified here and the `invite` array into the
eventual `m.room.create` event's `additional_creators`, deduplicating
between the two parameters.
initial_state:
type: array
description: |-
@ -225,7 +250,7 @@ paths:
}
"400":
description: |-
The request is invalid. A meaningful `errcode` and description
error text will be returned. Example reasons for rejection include:

View file

@ -43,7 +43,7 @@ properties:
example: "All things general"
world_readable:
type: boolean
description: Whether the room may be viewed by guest users without joining.
description: Whether the room may be viewed by users without joining.
example: false
guest_can_join:
type: boolean

View file

@ -34,24 +34,6 @@ properties:
type: array
type: object
example: {
"content": [
{
"actions": [
"notify",
{
"set_tweak": "sound",
"value": "default"
},
{
"set_tweak": "highlight"
}
],
"default": true,
"enabled": true,
"pattern": "alice",
"rule_id": ".m.rule.contains_user_name"
}
],
"override": [
{
"actions": [],
@ -113,12 +95,14 @@ example: {
],
"conditions": [
{
"kind": "contains_display_name"
"kind": "event_property_contains",
"key": "content.m\\.mentions.user_ids",
"value": "@alice:example.com"
}
],
"default": true,
"enabled": true,
"rule_id": ".m.rule.contains_display_name"
"rule_id": ".m.rule.is_user_mention"
},
{
"actions": [

View file

@ -16,48 +16,121 @@ info:
title: Matrix Client-Server Profile API
version: 1.0.0
paths:
"/profile/{userId}/displayname":
"/profile/{userId}/{keyName}":
put:
summary: Set the user's display name.
x-changedInMatrixVersion:
"1.16": This endpoint now accepts a variable `keyName` parameter and `m.tz` was added as a defined key. Previously only `displayname` and `avatar_url` were accepted.
summary: Set a profile field for a user.
description: |-
This API sets the given user's display name. You must have permission to
set this user's display name, e.g. you need to have their `access_token`.
operationId: setDisplayName
Set or update a profile field for a user. Must be authenticated with an
access token authorised to make changes. Servers MAY impose size limits
on individual fields, and the total profile MUST be under 64 KiB.
Servers MAY reject `null` values. Servers that accept `null` values SHOULD store
them rather than treating `null` as a deletion request. Clients that want to delete a
field, including its key and value, SHOULD use the `DELETE` endpoint instead.
operationId: setProfileField
security:
- accessTokenQuery: []
- accessTokenBearer: []
parameters:
- in: path
name: userId
description: The user whose display name to set.
description: The user whose profile field should be set.
required: true
example: "@alice:example.com"
schema:
type: string
- in: path
name: keyName
description: The name of the profile field to set. This MUST be either
`avatar_url`, `displayname`, `m.tz`, or a custom field following the
[Common Namespaced Identifier Grammar](/appendices/#common-namespaced-identifier-grammar).
required: true
example: "displayname"
schema:
type: string
pattern: '^(avatar_url|displayname|m\.tz|[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+)$'
requestBody:
description: A JSON object containing the property whose name matches
the `keyName` specified in the URL. See `additionalProperties` for
further details.
required: true
content:
application/json:
schema:
type: object
example: {
"displayname": "Alice Margatroid"
}
properties:
displayname:
type: string
description: The new display name for this user.
description: The new display name information.
required: true
minProperties: 1
description: |
An object which contains exactly one property. The key
of that property MUST match the `keyName` specified in the URL.
For `avatar_url`, the value MUST be an MXC URI string.
For `displayname`, the value MUST be a string.
For `m.tz`, the value MUST be a valid identifier from the [IANA Time Zone Database](https://www.iana.org/time-zones).
Servers MAY choose to validate the value. Clients MUST expect unknown or invalid
values.
For custom keys, any JSON type is allowed. Servers MAY not validate
these values, but clients SHOULD follow the format defined for that key.
additionalProperties: true
example: { "displayname": "Alice Wonderland" }
responses:
"200":
description: The display name was set.
description: The profile field was set.
content:
application/json:
schema:
type: object # empty json object
type: object # empty JSON object
examples:
response:
value: {}
"400":
description: |
The input was invalid in some way. This can include one
of the following error codes:
- `M_BAD_JSON`: The provided value is not valid JSON.
- `M_MISSING_PARAM`: The required `keyName` property is
missing from the request body.
- `M_PROFILE_TOO_LARGE`: Storing the supplied value would
make the profile exceed its maximum allowed size of 64 KiB.
- `M_KEY_TOO_LARGE`: The supplied profile key exceeds the
maximum allowed key length of 255 bytes.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
bad_json:
value:
{
"errcode": "M_BAD_JSON",
"error": "Malformed JSON payload.",
}
invalid_key:
value:
{
"errcode": "M_INVALID_PARAM",
"error": "Invalid profile key.",
}
"403":
description: The server is unwilling to perform the operation, either
due to insufficient permissions or because profile modifications
are disabled.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
forbidden:
value:
{
"errcode": "M_FORBIDDEN",
"error": "Profile modification is not permitted.",
}
"429":
description: This request was rate-limited.
content:
@ -67,98 +140,125 @@ paths:
tags:
- User data
get:
summary: Get the user's display name.
description: |-
Get the user's display name. This API may be used to fetch the user's
own displayname or to query the name of other users; either locally or
on remote homeservers.
operationId: getDisplayName
x-changedInMatrixVersion:
"1.16": This endpoint now accepts a variable `keyName` parameter and `m.tz` was added as a defined key. Previously only `displayname` and `avatar_url` were accepted.
summary: Get a profile field for a user.
description: Get the value of a profile field for a user.
operationId: getProfileField
parameters:
- in: path
name: userId
description: The user whose display name to get.
description: The user whose profile field should be returned.
required: true
example: "@alice:example.com"
schema:
type: string
- in: path
name: keyName
description: The name of the profile field to retrieve.
required: true
example: "displayname"
schema:
type: string
pattern: '^(avatar_url|displayname|m\.tz|[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+)$'
responses:
"200":
description: The display name for this user.
description: The profile field value was retrieved.
content:
application/json:
schema:
type: object
properties:
displayname:
type: string
description: The user's display name if they have set one, otherwise not
present.
description: |
An object with one property, whose key matches the `keyName` specified
in the URL, and whose value is the current setting of that profile field.
additionalProperties: true
examples:
response:
value: {
"displayname": "Alice Margatroid"
}
value: { "displayname": "Alice" }
"403":
x-addedInMatrixVersion: "1.12"
description: The server is unwilling to disclose whether the user exists and/or
has a display name.
description: The server is unwilling to disclose whether the user
exists and/or has the specified profile field.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_FORBIDDEN",
"error": "Profile lookup is disabled on this homeserver"
}
value:
{
"errcode": "M_FORBIDDEN",
"error": "Profile lookup is disabled on this homeserver",
}
"404":
description: There is no display name for this user or this user does not exist.
description: There is no profile field with this key for this user, or
the user does not exist.
tags:
- User data
"/profile/{userId}/avatar_url":
put:
summary: Set the user's avatar URL.
description: |-
This API sets the given user's avatar URL. You must have permission to
set this user's avatar URL, e.g. you need to have their `access_token`.
operationId: setAvatarUrl
delete:
x-addedInMatrixVersion: "1.16"
summary: Remove a profile field from a user.
description: Remove a specific field from a user's profile.
operationId: deleteProfileField
security:
- accessTokenQuery: []
- accessTokenBearer: []
parameters:
- in: path
name: userId
description: The user whose avatar URL to set.
description: The user whose profile field should be deleted.
required: true
example: "@alice:example.com"
schema:
type: string
requestBody:
content:
application/json:
schema:
type: object
example: {
"avatar_url": "mxc://matrix.org/wefh34uihSDRGhw34"
}
properties:
avatar_url:
type: string
format: uri
description: The new avatar URL for this user.
description: The new avatar information.
required: true
- in: path
name: keyName
description: The name of the profile field to delete.
required: true
example: "displayname"
schema:
type: string
pattern: '^(avatar_url|displayname|m\.tz|[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+)$'
responses:
"200":
description: The avatar URL was set.
description: The profile field was deleted or it doesn't exist.
content:
application/json:
schema:
type: object # empty json object
type: object
examples:
response:
value: {}
"400":
description: The request is malformed, contains invalid JSON, or
specifies an invalid key.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
bad_json:
value:
{ "errcode": "M_BAD_JSON", "error": "Malformed request." }
invalid_key:
value:
{
"errcode": "M_INVALID_PARAM",
"error": "Invalid profile key.",
}
"403":
description: The user is not authorised to delete this profile field.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
forbidden:
value:
{
"errcode": "M_FORBIDDEN",
"error": "Profile deletion is not permitted.",
}
"429":
description: This request was rate-limited.
content:
@ -167,63 +267,11 @@ paths:
$ref: definitions/errors/rate_limited.yaml
tags:
- User data
get:
summary: Get the user's avatar URL.
description: |-
Get the user's avatar URL. This API may be used to fetch the user's
own avatar URL or to query the URL of other users; either locally or
on remote homeservers.
operationId: getAvatarUrl
parameters:
- in: path
name: userId
description: The user whose avatar URL to get.
required: true
example: "@alice:example.com"
schema:
type: string
responses:
"200":
description: The avatar URL for this user.
content:
application/json:
schema:
type: object
properties:
avatar_url:
type: string
format: uri
description: The user's avatar URL if they have set one, otherwise not present.
examples:
response:
value: {
"avatar_url": "mxc://matrix.org/SDGdghriugerRg"
}
"403":
x-addedInMatrixVersion: "1.12"
description: The server is unwilling to disclose whether the user exists and/or
has an avatar URL.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_FORBIDDEN",
"error": "Profile lookup is disabled on this homeserver"
}
"404":
description: There is no avatar URL for this user or this user does not exist.
tags:
- User data
"/profile/{userId}":
get:
summary: Get this user's profile information.
summary: Get all profile information for a user.
description: |-
Get the combined profile information for this user. This API may be used
to fetch the user's own profile information or other users; either
locally or on remote homeservers.
Get the complete profile for a user.
operationId: getUserProfile
parameters:
- in: path
@ -243,45 +291,54 @@ paths:
properties:
avatar_url:
type: string
format: uri
format: mx-mxc-uri
description: The user's avatar URL if they have set one, otherwise not present.
displayname:
type: string
description: The user's display name if they have set one, otherwise not
present.
m.tz:
x-addedInMatrixVersion: "1.16"
type: string
description: The user's time zone.
additionalProperties:
x-addedInMatrixVersion: "1.16"
description: Additional profile fields.
examples:
response:
value: {
"avatar_url": "mxc://matrix.org/SDGdghriugerRg",
"displayname": "Alice Margatroid"
}
value:
{
"avatar_url": "mxc://matrix.org/SDGdghriugerRg",
"displayname": "Alice Margatroid",
"m.tz": "Europe/London",
"m.example_field": "custom_value",
}
"403":
x-addedInMatrixVersion: "1.2"
description: The server is unwilling to disclose whether the user exists and/or
has profile information.
description: The server is unwilling to disclose whether the user
exists and/or has profile information.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_FORBIDDEN",
"error": "Profile lookup is disabled on this homeserver"
}
value:
{
"errcode": "M_FORBIDDEN",
"error": "Profile lookup is disabled on this homeserver",
}
"404":
description: There is no profile information for this user or this user does not
exist.
description: There is no profile information for this user or this
user does not exist.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_NOT_FOUND",
"error": "Profile not found"
}
value:
{ "errcode": "M_NOT_FOUND", "error": "Profile not found" }
tags:
- User data
servers:

View file

@ -41,6 +41,23 @@ paths:
new_version:
type: string
description: The new version for the room.
additional_creators:
type: array
items:
type: string
description: Additional user ID to consider a room creator, if the room version supports it.
x-addedInMatrixVersion: "1.16"
description: |-
When upgrading to a [room version](/rooms) which supports additional creators,
the [user IDs](/appendices#user-identifiers) which should be considered room
creators in addition to the user performing the upgrade.
If the room being upgraded has additional creators, they are *not* automatically
copied to the new room. The full set of additional creators needs to be set to
retain (or add/remove) more room creators.
When upgrading to a room version which doesn't support additional creators, this
field is ignored and has no effect during the upgrade process.
example: {
"new_version": "2"
}

View file

@ -117,6 +117,31 @@ paths:
example: 30000
schema:
type: integer
- in: query
name: use_state_after
x-addedInMatrixVersion: "1.16"
description: |-
Controls whether to receive state changes between the previous sync
and the **start** of the timeline, or between the previous sync and
the **end** of the timeline.
If this is set to `true`, servers MUST respond with the state
between the previous sync and the **end** of the timeline in
`state_after` and MUST omit `state`.
If `false`, servers MUST respond with the state between the previous
sync and the **start** of the timeline in `state` and MUST omit
`state_after`.
Even if this is set to `true`, clients MUST update their local state
with events in `state` and `timeline` if `state_after` is missing in
the response, for compatibility with servers that don't support this
parameter.
By default, this is `false`.
example: false
schema:
type: boolean
responses:
"200":
description: The initial snapshot or delta for the client to use to update their
@ -197,16 +222,50 @@ paths:
type: object
description: |-
Updates to the state, between the time indicated by
the `since` parameter, and the start of the
`timeline` (or all state up to the start of the
the `since` parameter, and the **start** of the
`timeline` (or all state up to the **start** of the
`timeline`, if `since` is not given, or
`full_state` is true).
N.B. state updates for `m.room.member` events will
{{% boxes/note %}}
State updates for `m.room.member` events will
be incomplete if `lazy_load_members` is enabled in
the `/sync` filter, and only return the member events
required to display the senders of the timeline events
in this response.
{{% /boxes/note %}}
MUST be omitted if `use_state_after` was set to `true`
in the request.
allOf:
- $ref: definitions/state_event_batch.yaml
state_after:
title: State
type: object
x-addedInMatrixVersion: "1.16"
description: |-
Updates to the state, between the time indicated by
the `since` parameter, and the **end** of the
`timeline` (or all state up to the **end** of the
`timeline`, if `since` is not given, or
`full_state` is true).
{{% boxes/note %}}
State updates for `m.room.member` events will
be incomplete if `lazy_load_members` is enabled in
the `/sync` filter, and only return the member events
required to display the senders of the timeline events
in this response.
{{% /boxes/note %}}
If this field is set, even if it is empty, clients MUST
only update their local state with events in this list,
and MUST NOT update their local state with events in
`timeline`. If this field is not set, clients MUST update
their local state with events in `state` and `timeline`.
**Required** if `use_state_after` was set to `true` in the
request, even if it is empty.
allOf:
- $ref: definitions/state_event_batch.yaml
timeline:
@ -353,7 +412,28 @@ paths:
state:
title: State
type: object
description: The state updates for the room up to the start of the timeline.
description: |-
The state updates for the room up to the **start** of the timeline.
MUST be omitted if `use_state_after` was set to `true` in the
request.
allOf:
- $ref: definitions/state_event_batch.yaml
state_after:
title: State
type: object
x-addedInMatrixVersion: "1.16"
description: |-
The state updates for the room up to the **end** of the timeline.
If this field is set, even if it is empty, clients MUST only
update their local state with events in this list, and MUST NOT
update their local state with events in `timeline`. If this field
is not set, clients MUST update their local state with events in
`state` and `timeline`.
**Required** if `use_state_after` was set to `true` in the
request, even if it is empty.
allOf:
- $ref: definitions/state_event_batch.yaml
timeline:

View file

@ -0,0 +1,25 @@
# Copyright 2025 The Matrix.org Foundation C.I.C.
#
# 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.
type: object
description: |-
The depth field of PDUs for room version 6 and beyond.
properties:
# v6 enforces Canonical JSON and therefore needs a depth limit change
depth:
type: integer
description: |-
The maximum depth of the `prev_events`, plus one. Must be less than the
maximum value for an integer (2^53 - 1). If the room's depth is already at
the limit, the depth must be set to the limit.
example: 12

View file

@ -14,10 +14,6 @@
type: object
description: Common fields for all PDU versions
properties:
room_id:
type: string
description: Room identifier.
example: "!abc123:matrix.org"
sender:
type: string
description: The ID of the user sending the event.
@ -69,7 +65,6 @@ properties:
description: The number of milliseconds that have passed since this message was sent.
example: 4612
required:
- room_id
- sender
- origin_server_ts
- type

View file

@ -0,0 +1,23 @@
# Copyright 2025 The Matrix.org Foundation C.I.C.
#
# 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.
type: object
description: |-
The room_id field of PDUs for room version 11 and prior.
properties:
room_id:
type: string
description: Room identifier.
example: "!abc123:matrix.org"
required:
- room_id

View file

@ -0,0 +1,23 @@
# Copyright 2025 The Matrix.org Foundation C.I.C.
#
# 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.
type: object
description: |-
The room_id field of PDUs for room version 12 and beyond.
properties:
room_id:
type: string
description: Room identifier. Omitted from `m.room.create` events.
example: "!Nhcu5BS-UMnFX7hBVfVSoXiD7OgH6iRT-xyIuqDnpYQ"
required:
- room_id

View file

@ -18,6 +18,7 @@ example:
$ref: "../examples/pdu_v1.json"
allOf:
- $ref: "components/pdu_base.yaml"
- $ref: "components/room_id_before_v12.yaml"
- type: object
properties:
event_id:

View file

@ -13,20 +13,12 @@
# limitations under the License.
type: object
title: Persistent Data Unit
description: A persistent data unit (event) for room version 11 and beyond.
description: A persistent data unit (event) for room version 11.
example:
$ref: "../examples/pdu_v11.json"
allOf:
# v11 is the v6 event, but without redacts.
- $ref: "components/pdu_base.yaml"
- $ref: "components/auth_events_prev_events_v4.yaml"
- type: object
properties:
# v6 enforces Canonical JSON and therefore needs a depth limit change
depth:
type: integer
description: |-
The maximum depth of the `prev_events`, plus one. Must be less than the
maximum value for an integer (2^53 - 1). If the room's depth is already at
the limit, the depth must be set to the limit.
example: 12
- $ref: "components/room_id_before_v12.yaml"
- $ref: "components/depth_v6.yaml"

View file

@ -0,0 +1,24 @@
# Copyright 2025 The Matrix.org Foundation C.I.C.
#
# 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.
type: object
title: Persistent Data Unit
description: A persistent data unit (event) for room version 12 and beyond.
example:
$ref: "../examples/pdu_v12.json"
allOf:
# v12 is the v11 event, but with special room ID requirements.
- $ref: "components/pdu_base.yaml"
- $ref: "components/auth_events_prev_events_v4.yaml"
- $ref: "components/depth_v6.yaml"
- $ref: "components/room_id_v12.yaml" # this is the v12 change

View file

@ -18,6 +18,7 @@ example:
$ref: "../examples/pdu_v3.json"
allOf:
- $ref: "components/pdu_base.yaml"
- $ref: "components/room_id_before_v12.yaml"
- type: object
properties:
redacts:

View file

@ -20,6 +20,7 @@ example:
allOf:
- $ref: "components/pdu_base.yaml"
- $ref: "components/auth_events_prev_events_v4.yaml"
- $ref: "components/room_id_before_v12.yaml"
- type: object
properties:
redacts:

View file

@ -20,17 +20,11 @@ example:
allOf:
- $ref: "components/pdu_base.yaml"
- $ref: "components/auth_events_prev_events_v4.yaml"
- $ref: "components/room_id_before_v12.yaml"
- $ref: "components/depth_v6.yaml"
- type: object
properties:
redacts:
type: string
description: For redaction events, the ID of the event being redacted.
example: "$def_456-oldevent"
# v6 enforces Canonical JSON and therefore needs a depth limit change
depth:
type: integer
description: |-
The maximum depth of the `prev_events`, plus one. Must be less than the
maximum value for an integer (2^53 - 1). If the room's depth is already at
the limit, the depth must be set to the limit.
example: 12

View file

@ -0,0 +1,9 @@
[
{"$ref": "./minimal_pdu.json"},
{
"type": "m.room.create",
"content": {
"see_room_version_spec": "The event format changes depending on the room version."
}
}
]

View file

@ -0,0 +1,9 @@
{
"allOf": [
{ "$ref": "components/pdu_base.json" },
{ "$ref": "components/auth_events_prev_events_v4.json" },
{
"room_id": "!Nhcu5BS-UMnFX7hBVfVSoXiD7OgH6iRT-xyIuqDnpYQ"
}
]
}

View file

@ -71,13 +71,32 @@ paths:
properties:
invite_room_state:
type: array
x-changedInMatrixVersion:
"1.16": |
`m.room.create` and format requirements were added.
description: |-
An optional list of [stripped state events](/client-server-api/#stripped-state)
to help the receiver of the invite identify the room.
A list of state events to help the receiver of the invite identify the room.
Translated as [stripped state events](/client-server-api/#stripped-state)
over the Client-Server API.
MUST contain the `m.room.create` event for the room. All events listed
MUST additionally be formatted according to the room version specification.
Servers might need to apply validation to the `invite_room_state` depending
on room version. See the `400 M_MISSING_PARAM` error definition for more
information.
Note that events have a different format depending on the room
version - check the [room version specification](/rooms) for
precise event formats.
items:
$ref: ../../event-schemas/schema/core-event-schema/stripped_state.yaml
example:
$ref: ../../event-schemas/examples/invite_room_state.json
type: object
title: PDU
properties: {}
description: |-
Note that events have a different format depending on the room
version - check the [room version specification](/rooms) for
precise event formats.
type: object
required: true
responses:
@ -118,24 +137,7 @@ paths:
"origin_server_ts": 1549041175876,
"sender": "@someone:example.org",
"unsigned": {
"invite_room_state": [
{
"type": "m.room.name",
"sender": "@bob:example.org",
"state_key": "",
"content": {
"name": "Example Room"
}
},
{
"type": "m.room.join_rules",
"sender": "@bob:example.org",
"state_key": "",
"content": {
"join_rule": "invite"
}
}
]
"invite_room_state": {"$ref": "./examples/invite_or_knock_state.json"}
},
"content": {
"membership": "invite"
@ -168,6 +170,35 @@ paths:
"errcode": "M_FORBIDDEN",
"error": "User cannot invite the target user."
}
"400":
description: |-
The `M_MISSING_PARAM` error code is used to indicate one or more of
the following:
* The `m.room.create` event is missing from `invite_room_state`.
* One or more entries in `invite_room_state` are not formatted according
to the room's version.
* One or more events fails a [signature check](/server-server-api/#validating-hashes-and-signatures-on-received-events).
* One or more events does not reside in the same room as the invite.
Note: Some room versions may require calculating the room ID for an
event rather than relying on the presence of `room_id`.
Servers MAY apply the validation above to room versions 1 through 11,
and SHOULD apply the validation above to all other room versions.
If `M_MISSING_PARAM` is returned and the request is associated with a
Client-Server API request, the Client-Server API request SHOULD fail
with a 5xx error rather than being passed through.
content:
application/json:
schema:
$ref: ../client-server/definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_MISSING_PARAM",
"error": "Create event not among invite state entries."
}
servers:
- url: "{protocol}://{hostname}{basePath}"
variables:

View file

@ -72,13 +72,32 @@ paths:
$ref: definitions/invite_event.yaml
invite_room_state:
type: array
x-changedInMatrixVersion:
"1.16": |
`m.room.create` and format requirements were added.
description: |-
An optional list of [stripped state events](/client-server-api/#stripped-state)
to help the receiver of the invite identify the room.
A list of state events to help the receiver of the invite identify the room.
Translated as [stripped state events](/client-server-api/#stripped-state)
over the Client-Server API.
MUST contain the `m.room.create` event for the room. All events listed
MUST additionally be formatted according to the room version specification.
Servers might need to apply validation to the `invite_room_state` depending
on room version. See the `400 M_MISSING_PARAM` error definition for more
information.
Note that events have a different format depending on the room
version - check the [room version specification](/rooms) for
precise event formats.
items:
$ref: ../../event-schemas/schema/core-event-schema/stripped_state.yaml
example:
$ref: ../../event-schemas/examples/invite_room_state.json
type: object
title: PDU
properties: {}
description: |-
Note that events have a different format depending on the room
version - check the [room version specification](/rooms) for
precise event formats.
required:
- room_version
- event
@ -111,24 +130,7 @@ paths:
"origin_server_ts": 1549041175876,
"sender": "@someone:example.org",
"unsigned": {
"invite_room_state": [
{
"type": "m.room.name",
"sender": "@bob:example.org",
"state_key": "",
"content": {
"name": "Example Room"
}
},
{
"type": "m.room.join_rules",
"sender": "@bob:example.org",
"state_key": "",
"content": {
"join_rule": "invite"
}
}
]
"invite_room_state": {"$ref": "./examples/invite_or_knock_state.json"}
},
"content": {
"membership": "invite"
@ -151,6 +153,24 @@ paths:
The error should be passed through to clients so that they
may give better feedback to users.
The `M_MISSING_PARAM` error code is used to indicate one or more of
the following:
* The `m.room.create` event is missing from `invite_room_state`.
* One or more entries in `invite_room_state` are not formatted according
to the room's version.
* One or more events fails a [signature check](/server-server-api/#validating-hashes-and-signatures-on-received-events).
* One or more events does not reside in the same room as the invite.
Note: Some room versions may require calculating the room ID for an
event rather than relying on the presence of `room_id`.
Servers MAY apply the validation above to room versions 1 through 11,
and SHOULD apply the validation above to all other room versions.
If `M_MISSING_PARAM` is returned and the request is associated with a
Client-Server API request, the Client-Server API request SHOULD fail
with a 5xx error rather than being passed through.
content:
application/json:
schema:

View file

@ -293,19 +293,41 @@ paths:
knock_room_state:
type: array
items:
$ref: ../../event-schemas/schema/core-event-schema/stripped_state.yaml
type: object
title: PDU
properties: {}
description: |-
Note that events have a different format depending on the room
version - check the [room version specification](/rooms) for
precise event formats.
x-changedInMatrixVersion:
"1.16": |
`m.room.create` and format requirements were added.
description: |-
A list of [stripped state events](/client-server-api/#stripped-state)
to help the initiator of the knock identify the room.
A list of state events to help the initiator of the knock identify
the room. Translated as [stripped state events](/client-server-api/#stripped-state)
over the Client-Server API.
MUST contain the `m.room.create` event for the room. All events
listed MUST additionally be formatted according to the room
version specification.
Entries which are [improperly signed](/server-server-api/#validating-hashes-and-signatures-on-received-events)
or formatted SHOULD be removed by the server prior to supplying
them over the Client-Server API.
Note that events have a different format depending on the room
version - check the [room version specification](/rooms) for
precise event formats.
example:
$ref: ../../event-schemas/examples/knock_room_state.json
"$ref": "./examples/invite_or_knock_state.json"
required:
- knock_room_state
examples:
response:
value: {
"knock_room_state": {
"$ref": "../../event-schemas/examples/knock_room_state.json"
"$ref": "./examples/invite_or_knock_state.json"
}
}
"403":

View file

@ -3,24 +3,6 @@
"type": "m.push_rules",
"content": {
"global": {
"content": [
{
"actions": [
"notify",
{
"set_tweak": "sound",
"value": "default"
},
{
"set_tweak": "highlight"
}
],
"default": true,
"enabled": true,
"pattern": "alice",
"rule_id": ".m.rule.contains_user_name"
}
],
"override": [
{
"actions": [],
@ -82,12 +64,14 @@
],
"conditions": [
{
"kind": "contains_display_name"
"kind": "event_property_contains",
"key": "content.m\\.mentions.user_ids",
"value": "@alice:example.com"
}
],
"default": true,
"enabled": true,
"rule_id": ".m.rule.contains_display_name"
"rule_id": ".m.rule.is_user_mention"
},
{
"actions": [

View file

@ -11,6 +11,8 @@
# 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.
$schema: https://json-schema.org/draft/2020-12/schema
properties:
entity:
description: |-

View file

@ -1,3 +1,5 @@
$schema: https://json-schema.org/draft/2020-12/schema
type: object
x-addedInMatrixVersion: "1.10"
description: |-

View file

@ -1,3 +1,5 @@
$schema: https://json-schema.org/draft/2020-12/schema
description: "The content of all call events shares a set of common fields: those
of room events and some additional VoIP specific fields."
properties:

View file

@ -1,3 +1,5 @@
$schema: https://json-schema.org/draft/2020-12/schema
description: The basic set of fields all events must have.
properties:
content:

View file

@ -1,3 +1,5 @@
$schema: https://json-schema.org/draft/2020-12/schema
description: Metadata about an avatar image.
properties:
h:

View file

@ -1,3 +1,5 @@
$schema: https://json-schema.org/draft/2020-12/schema
description: Metadata about an image.
properties:
h:

View file

@ -1,3 +1,5 @@
$schema: https://json-schema.org/draft/2020-12/schema
description: Metadata about a thumbnail image.
properties:
h:

View file

@ -1,3 +1,5 @@
$schema: https://json-schema.org/draft/2020-12/schema
title: RoomEvent
description: Room Events have the following fields.
allOf:

View file

@ -1,3 +1,5 @@
$schema: https://json-schema.org/draft/2020-12/schema
allOf:
- $ref: room_event.yaml
- $ref: sync_state_event.yaml

View file

@ -18,6 +18,8 @@
# difficult because the schema would be at two different locations, with
# different relative pathing.
$schema: https://json-schema.org/draft/2020-12/schema
title: StrippedStateEvent
type: object
description: |-

View file

@ -17,6 +17,8 @@
# be on events, so we give it a whole event structure as a base for room_event.
# This base doesn't declare a room_id, which instead appears in the room_event.
$schema: https://json-schema.org/draft/2020-12/schema
title: SyncRoomEvent
description: In addition to the Event fields, Room Events have the following additional
fields.

View file

@ -14,6 +14,8 @@
# See sync_room_event.yaml for why this file is here.
$schema: https://json-schema.org/draft/2020-12/schema
title: SyncStateEvent
description: In addition to the Room Event fields, State Events have the following
additional fields.

View file

@ -11,6 +11,7 @@
# 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.
$schema: https://json-schema.org/draft/2020-12/schema
title: UnsignedData
type: object

View file

@ -1,4 +1,6 @@
---
$schema: https://json-schema.org/draft/2020-12/schema
allOf:
- $ref: core-event-schema/event.yaml
description: |-

View file

@ -1,4 +1,5 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"description": "This event is sent by the callee when they wish to answer the call.",
"x-weight": 40,

View file

@ -1,3 +1,5 @@
$schema: https://json-schema.org/draft/2020-12/schema
type: object
description: |-
This event is sent by callers after sending an invite and by the callee after

View file

@ -1,4 +1,6 @@
---
$schema: https://json-schema.org/draft/2020-12/schema
type: object
description: |
Sent by either party to signal their termination of the call. This can

View file

@ -1,4 +1,5 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"description": "This event is sent by the caller when they wish to establish a call.",
"x-weight": 10,

View file

@ -1,4 +1,6 @@
---
$schema: https://json-schema.org/draft/2020-12/schema
type: object
description: |
Provides SDP negotiation semantics for media pause, hold/resume, ICE restarts

View file

@ -1,4 +1,6 @@
---
$schema: https://json-schema.org/draft/2020-12/schema
type: object
description: |
If the `m.call.invite` event has `version` `"1"`, a client wishing to

View file

@ -1,3 +1,5 @@
$schema: https://json-schema.org/draft/2020-12/schema
type: object
x-addedInMatrixVersion: "1.11"
x-weight: 70

View file

@ -1,4 +1,5 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"description": "This event is sent by the caller's client once it has decided which other client to talk to, by selecting one of multiple possible incoming `m.call.answer` events. Its `selected_party_id` field indicates the answer it's chosen. The `call_id` and `party_id` of the caller is also included. If the callee's client sees a `select_answer` for an answer with party ID other than the one it sent, it ends the call and informs the user the call was answered elsewhere. It does not send any events. Media can start flowing before this event is seen or even sent. Clients that implement previous versions of this specification will ignore this event and behave as they did before.",
"x-addedInMatrixVersion": "1.7",

View file

@ -1,4 +1,6 @@
---
$schema: https://json-schema.org/draft/2020-12/schema
allOf:
- $ref: core-event-schema/event.yaml
description: |-

View file

@ -1,4 +1,6 @@
---
$schema: https://json-schema.org/draft/2020-12/schema
allOf:
- $ref: core-event-schema/event.yaml

View file

@ -1,4 +1,6 @@
---
$schema: https://json-schema.org/draft/2020-12/schema
allOf:
- $ref: core-event-schema/event.yaml

View file

@ -1,4 +1,5 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"title": "Read Marker Location Event",
"description": "The current location of the user's read marker in a room. This event appears in the user's room account data for the room the marker is applicable for.",

View file

@ -1,4 +1,6 @@
---
$schema: https://json-schema.org/draft/2020-12/schema
allOf:
- $ref: core-event-schema/event.yaml
description: |-

View file

@ -1,4 +1,6 @@
---
$schema: https://json-schema.org/draft/2020-12/schema
allOf:
- $ref: core-event-schema/event.yaml
description: |-

View file

@ -1,4 +1,6 @@
---
$schema: https://json-schema.org/draft/2020-12/schema
allOf:
- $ref: core-event-schema/event.yaml

View file

@ -1,4 +1,6 @@
---
$schema: https://json-schema.org/draft/2020-12/schema
allOf:
- $ref: core-event-schema/event.yaml

View file

@ -1,4 +1,6 @@
---
$schema: https://json-schema.org/draft/2020-12/schema
allOf:
- $ref: core-event-schema/event.yaml

View file

@ -1,4 +1,6 @@
---
$schema: https://json-schema.org/draft/2020-12/schema
allOf:
- $ref: core-event-schema/event.yaml

View file

@ -1,4 +1,6 @@
---
$schema: https://json-schema.org/draft/2020-12/schema
description: |-
Required when sent as an in-room message. Indicates the
`m.key.verification.request` that this message is related to. Note that for

View file

@ -1,4 +1,6 @@
---
$schema: https://json-schema.org/draft/2020-12/schema
allOf:
- $ref: core-event-schema/event.yaml

View file

@ -1,4 +1,6 @@
---
$schema: https://json-schema.org/draft/2020-12/schema
allOf:
- $ref: core-event-schema/event.yaml

View file

@ -1,4 +1,6 @@
---
$schema: https://json-schema.org/draft/2020-12/schema
allOf:
- $ref: core-event-schema/event.yaml

View file

@ -1,4 +1,6 @@
---
$schema: https://json-schema.org/draft/2020-12/schema
allOf:
- $ref: core-event-schema/event.yaml

Some files were not shown because too many files have changed in this diff Show more