From d6018843784068e15bc178c1a804d4cca9bc4066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= Date: Mon, 30 Mar 2026 17:58:24 +0200 Subject: [PATCH 1/3] Clarify string formats of event endpoints and schemas MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Commaille --- data/api/client-server/definitions/client_event.yaml | 5 +++-- .../definitions/client_event_without_room_id.yaml | 4 ++++ data/api/client-server/definitions/m.relates_to.yaml | 2 ++ data/api/client-server/message_pagination.yaml | 2 ++ data/api/client-server/old_sync.yaml | 4 ++++ data/api/client-server/redaction.yaml | 10 ++++++++-- data/api/client-server/relations.yaml | 4 ++++ data/api/client-server/room_event_by_timestamp.yaml | 4 ++++ data/api/client-server/room_initial_sync.yaml | 4 ++++ data/api/client-server/room_send.yaml | 4 ++++ data/api/client-server/room_state.yaml | 4 ++++ data/api/client-server/rooms.yaml | 12 ++++++++++++ data/api/client-server/sync.yaml | 2 ++ .../schema/components/signed_third_party_invite.yaml | 11 +++++++---- .../schema/core-event-schema/room_event.yaml | 2 ++ .../schema/core-event-schema/stripped_state.yaml | 2 ++ .../schema/core-event-schema/sync_room_event.yaml | 4 ++++ .../event-schemas/schema/m.room.canonical_alias.yaml | 4 ++++ data/event-schemas/schema/m.room.create.yaml | 8 ++++++++ data/event-schemas/schema/m.room.join_rules.yaml | 2 ++ data/event-schemas/schema/m.room.member.yaml | 4 ++++ data/event-schemas/schema/m.room.redaction.yaml | 4 ++++ data/string-formats.yaml | 5 +++++ 23 files changed, 99 insertions(+), 8 deletions(-) diff --git a/data/api/client-server/definitions/client_event.yaml b/data/api/client-server/definitions/client_event.yaml index d9606676..88b0b96f 100644 --- a/data/api/client-server/definitions/client_event.yaml +++ b/data/api/client-server/definitions/client_event.yaml @@ -24,8 +24,9 @@ allOf: room_id: description: The ID of the room associated with this event. type: string + format: mx-room-id + pattern: "^!" example: '!jEsUZKDJdhlrceRyVU:example.org' - unsigned: properties: redacted_because: @@ -43,6 +44,6 @@ allOf: "unsigned": { "age": 1257, } - } + } required: - room_id diff --git a/data/api/client-server/definitions/client_event_without_room_id.yaml b/data/api/client-server/definitions/client_event_without_room_id.yaml index b12611a2..fcdf32ea 100644 --- a/data/api/client-server/definitions/client_event_without_room_id.yaml +++ b/data/api/client-server/definitions/client_event_without_room_id.yaml @@ -28,6 +28,8 @@ properties: event_id: description: The globally unique identifier for this event. type: string + format: mx-event-id + pattern: "^\\$" example: '$26RqwJMLw-yds1GAH_QxjHRC1Da9oasK0e5VLnck_45' type: description: The type of the event. @@ -47,6 +49,8 @@ properties: sender: description: Contains the fully-qualified ID of the user who sent this event. type: string + format: mx-user-id + pattern: "^@" example: "@example:example.org" origin_server_ts: description: |- diff --git a/data/api/client-server/definitions/m.relates_to.yaml b/data/api/client-server/definitions/m.relates_to.yaml index 401c8bb9..e1259c02 100644 --- a/data/api/client-server/definitions/m.relates_to.yaml +++ b/data/api/client-server/definitions/m.relates_to.yaml @@ -39,5 +39,7 @@ properties: such. event_id: type: string + format: mx-event-id + pattern: "^\\$" description: The event ID of the event that this event relates to. required: ['rel_type', 'event_id'] diff --git a/data/api/client-server/message_pagination.yaml b/data/api/client-server/message_pagination.yaml index 4d5c94e1..c26f461d 100644 --- a/data/api/client-server/message_pagination.yaml +++ b/data/api/client-server/message_pagination.yaml @@ -37,6 +37,8 @@ paths: example: "!636q39766251:example.com" schema: type: string + format: mx-room-id + pattern: "^!" - in: query name: from x-changedInMatrixVersion: diff --git a/data/api/client-server/old_sync.yaml b/data/api/client-server/old_sync.yaml index 1f97341a..b07c73f1 100644 --- a/data/api/client-server/old_sync.yaml +++ b/data/api/client-server/old_sync.yaml @@ -148,6 +148,8 @@ paths: properties: room_id: type: string + format: mx-room-id + pattern: "^!" description: The ID of this room. membership: type: string @@ -337,6 +339,8 @@ paths: example: $asfDuShaf7Gafaw:matrix.org schema: type: string + format: mx-event-id + pattern: "^\\$" responses: "200": description: The full event. diff --git a/data/api/client-server/redaction.yaml b/data/api/client-server/redaction.yaml index 53f45bc5..0e9ff7f9 100644 --- a/data/api/client-server/redaction.yaml +++ b/data/api/client-server/redaction.yaml @@ -43,13 +43,17 @@ paths: example: "!637q39766251:example.com" schema: type: string + format: mx-room-id + pattern: "^!" - in: path name: eventId - description: The ID of the event to redact + description: The ID of the event to redact. required: true - example: bai2b1i9:matrix.org + example: $bai2b1i9:matrix.org schema: type: string + format: mx-event-id + pattern: "^\\$" - in: path name: txnId description: |- @@ -82,6 +86,8 @@ paths: properties: event_id: type: string + format: mx-event-id + pattern: "^\\$" description: A unique identifier for the event. examples: response: diff --git a/data/api/client-server/relations.yaml b/data/api/client-server/relations.yaml index c4b0228c..c59c5cb0 100644 --- a/data/api/client-server/relations.yaml +++ b/data/api/client-server/relations.yaml @@ -233,6 +233,8 @@ components: example: "!636q39766251:matrix.org" schema: type: string + format: mx-room-id + pattern: "^!" eventId: in: path name: eventId @@ -241,6 +243,8 @@ components: example: $asfDuShaf7Gafaw schema: type: string + format: mx-event-id + pattern: "^\\$" from: in: query name: from diff --git a/data/api/client-server/room_event_by_timestamp.yaml b/data/api/client-server/room_event_by_timestamp.yaml index 1ab52cb9..c47c301e 100644 --- a/data/api/client-server/room_event_by_timestamp.yaml +++ b/data/api/client-server/room_event_by_timestamp.yaml @@ -56,6 +56,8 @@ paths: example: "!636q39766251:matrix.org" schema: type: string + format: mx-room-id + pattern: "^!" - in: query name: ts description: |- @@ -86,6 +88,8 @@ paths: properties: event_id: type: string + format: mx-event-id + pattern: "^\\$" description: The ID of the event found origin_server_ts: type: integer diff --git a/data/api/client-server/room_initial_sync.yaml b/data/api/client-server/room_initial_sync.yaml index e9ad7a63..b9ab45ec 100644 --- a/data/api/client-server/room_initial_sync.yaml +++ b/data/api/client-server/room_initial_sync.yaml @@ -27,6 +27,8 @@ paths: example: "!636q39766251:example.com" schema: type: string + format: mx-room-id + pattern: "^!" responses: "200": description: The current state of the room @@ -38,6 +40,8 @@ paths: properties: room_id: type: string + format: mx-room-id + pattern: "^!" description: The ID of this room. membership: type: string diff --git a/data/api/client-server/room_send.yaml b/data/api/client-server/room_send.yaml index 7393d440..a9e35ba5 100644 --- a/data/api/client-server/room_send.yaml +++ b/data/api/client-server/room_send.yaml @@ -49,6 +49,8 @@ paths: example: "!636q39766251:example.com" schema: type: string + format: mx-room-id + pattern: "^!" - in: path name: eventType description: The type of event to send. @@ -86,6 +88,8 @@ paths: properties: event_id: type: string + format: mx-event-id + pattern: "^\\$" description: A unique identifier for the event. required: - event_id diff --git a/data/api/client-server/room_state.yaml b/data/api/client-server/room_state.yaml index 015f8f9d..d2b14bfe 100644 --- a/data/api/client-server/room_state.yaml +++ b/data/api/client-server/room_state.yaml @@ -49,6 +49,8 @@ paths: example: "!636q39766251:example.com" schema: type: string + format: mx-room-id + pattern: "^!" - in: path name: eventType description: The type of event to send. @@ -86,6 +88,8 @@ paths: properties: event_id: type: string + format: mx-event-id + pattern: "^\\$" description: A unique identifier for the event. required: - event_id diff --git a/data/api/client-server/rooms.yaml b/data/api/client-server/rooms.yaml index 3716b6a4..d4c080de 100644 --- a/data/api/client-server/rooms.yaml +++ b/data/api/client-server/rooms.yaml @@ -34,6 +34,8 @@ paths: example: "!636q39766251:matrix.org" schema: type: string + format: mx-room-id + pattern: "^!" - in: path name: eventId description: The event ID to get. @@ -41,6 +43,8 @@ paths: example: $asfDuShaf7Gafaw:matrix.org schema: type: string + format: mx-event-id + pattern: "^\\$" responses: "200": description: The full event. @@ -89,6 +93,8 @@ paths: example: "!636q39766251:example.com" schema: type: string + format: mx-room-id + pattern: "^!" - in: path name: eventType description: The type of state to look up. @@ -158,6 +164,8 @@ paths: example: "!636q39766251:example.com" schema: type: string + format: mx-room-id + pattern: "^!" responses: "200": description: The current state of the room @@ -211,6 +219,8 @@ paths: example: "!636q39766251:example.com" schema: type: string + format: mx-room-id + pattern: "^!" - in: query name: at description: |- @@ -305,6 +315,8 @@ paths: example: "!636q39766251:example.com" schema: type: string + format: mx-room-id + pattern: "^!" security: - accessTokenQuery: [] - accessTokenBearer: [] diff --git a/data/api/client-server/sync.yaml b/data/api/client-server/sync.yaml index 8186dde5..c7791940 100644 --- a/data/api/client-server/sync.yaml +++ b/data/api/client-server/sync.yaml @@ -209,6 +209,8 @@ paths: field may be omitted. items: type: string + format: mx-user-id + pattern: "^@" m.joined_member_count: type: integer description: |- diff --git a/data/event-schemas/schema/components/signed_third_party_invite.yaml b/data/event-schemas/schema/components/signed_third_party_invite.yaml index b231c978..9e9ba81e 100644 --- a/data/event-schemas/schema/components/signed_third_party_invite.yaml +++ b/data/event-schemas/schema/components/signed_third_party_invite.yaml @@ -20,10 +20,13 @@ properties: The signatures are calculated using the process described at [Signing JSON](/appendices/#signing-json). type: object - additionalProperties: - type: object - additionalProperties: - type: string + patternProperties: + "": + x-pattern-format: mx-server-name + type: object + additionalProperties: + type: string + format: mx-unpadded-base64 example: { "magic.forest": { "ed25519:3": "fQpGIW1Snz+pwLZu6sTy2aHy/DYWWTspTJRPyNp0PKkymfIsNffysMl6ObMMFdIJhk6g6pwlIqZ54rxo8SLmAg" diff --git a/data/event-schemas/schema/core-event-schema/room_event.yaml b/data/event-schemas/schema/core-event-schema/room_event.yaml index 2df24e61..921c577f 100644 --- a/data/event-schemas/schema/core-event-schema/room_event.yaml +++ b/data/event-schemas/schema/core-event-schema/room_event.yaml @@ -11,5 +11,7 @@ allOf: The ID of the room associated with this event. Will not be present on events that arrive through `/sync`, despite being required everywhere else. type: string + format: mx-room-id + pattern: "^!" required: - room_id diff --git a/data/event-schemas/schema/core-event-schema/stripped_state.yaml b/data/event-schemas/schema/core-event-schema/stripped_state.yaml index 6493d35b..e27ba9f1 100644 --- a/data/event-schemas/schema/core-event-schema/stripped_state.yaml +++ b/data/event-schemas/schema/core-event-schema/stripped_state.yaml @@ -39,6 +39,8 @@ properties: sender: description: The `sender` for the event. type: string + format: mx-user-id + pattern: "^@" required: - type - state_key diff --git a/data/event-schemas/schema/core-event-schema/sync_room_event.yaml b/data/event-schemas/schema/core-event-schema/sync_room_event.yaml index 2e3c0f65..bf36d18f 100644 --- a/data/event-schemas/schema/core-event-schema/sync_room_event.yaml +++ b/data/event-schemas/schema/core-event-schema/sync_room_event.yaml @@ -29,9 +29,13 @@ allOf: event_id: description: The globally unique event identifier. type: string + format: mx-event-id + pattern: "^\\$" sender: description: Contains the fully-qualified ID of the user who sent this event. type: string + format: mx-user-id + pattern: "^@" origin_server_ts: description: Timestamp in milliseconds on originating homeserver when this event was sent. diff --git a/data/event-schemas/schema/m.room.canonical_alias.yaml b/data/event-schemas/schema/m.room.canonical_alias.yaml index f505693a..ef67179c 100644 --- a/data/event-schemas/schema/m.room.canonical_alias.yaml +++ b/data/event-schemas/schema/m.room.canonical_alias.yaml @@ -16,6 +16,8 @@ properties: The canonical alias for the room. If not present, null, or empty the room should be considered to have no canonical alias. type: string + format: mx-room-alias + pattern: "^#" alt_aliases: description: | Alternative aliases the room advertises. This list can have aliases @@ -23,6 +25,8 @@ properties: type: array items: type: string + format: mx-room-alias + pattern: "^#" type: object state_key: description: A zero-length string. diff --git a/data/event-schemas/schema/m.room.create.yaml b/data/event-schemas/schema/m.room.create.yaml index ed25d6d0..da8ca68e 100644 --- a/data/event-schemas/schema/m.room.create.yaml +++ b/data/event-schemas/schema/m.room.create.yaml @@ -12,6 +12,8 @@ properties: The `user_id` of the room creator. **Required** for, and only present in, room versions 1 - 10. Starting with room version 11 the event `sender` should be used instead. type: string + format: mx-user-id + pattern: "^@" m.federate: description: Whether users on other servers can join this room. Defaults to `true` if key does not exist. type: boolean @@ -32,9 +34,13 @@ properties: properties: room_id: type: string + format: mx-room-id + pattern: "^!" description: The ID of the old room. event_id: type: string + format: mx-event-id + pattern: "^\\$" deprecated: true x-changedInMatrixVersion: "1.16": |- @@ -51,6 +57,8 @@ properties: type: array items: type: string + format: mx-user-id + pattern: "^@" description: Additional user ID to consider a creator of the room, if supported by the room version. x-addedInMatrixVersion: "1.16" description: |- diff --git a/data/event-schemas/schema/m.room.join_rules.yaml b/data/event-schemas/schema/m.room.join_rules.yaml index 1bec90fc..b87e5b28 100644 --- a/data/event-schemas/schema/m.room.join_rules.yaml +++ b/data/event-schemas/schema/m.room.join_rules.yaml @@ -55,6 +55,8 @@ properties: enum: ['m.room_membership'] room_id: type: string + format: mx-room-id + pattern: "^!" description: |- Required if `type` is `m.room_membership`. The room ID to check the user's membership against. If the user is joined to this room, they diff --git a/data/event-schemas/schema/m.room.member.yaml b/data/event-schemas/schema/m.room.member.yaml index 75510d51..aa52fae0 100644 --- a/data/event-schemas/schema/m.room.member.yaml +++ b/data/event-schemas/schema/m.room.member.yaml @@ -76,6 +76,8 @@ properties: join_authorised_via_users_server: x-addedInMatrixVersion: "1.2" type: string + format: mx-user-id + pattern: "^@" description: |- Usually found on `join` events, this field is used to denote which homeserver (through representation of a user with sufficient power level) authorised the user's join. More @@ -127,6 +129,8 @@ properties: `join`, the user ID sending the event does not need to match the user ID in the `state_key`, unlike other events. Regular authorisation rules still apply. type: string + format: mx-user-id + pattern: "^@" type: enum: - m.room.member diff --git a/data/event-schemas/schema/m.room.redaction.yaml b/data/event-schemas/schema/m.room.redaction.yaml index 06ad8602..de6150eb 100644 --- a/data/event-schemas/schema/m.room.redaction.yaml +++ b/data/event-schemas/schema/m.room.redaction.yaml @@ -10,6 +10,8 @@ properties: redacts: description: The event ID that was redacted. Required for, and present starting in, room version 11. type: string + format: mx-event-id + pattern: "^\\$" reason: description: 'The reason for the redaction, if any.' type: string @@ -17,6 +19,8 @@ properties: redacts: description: Required for, and only present in, room versions 1 - 10. The event ID that was redacted. type: string + format: mx-event-id + pattern: "^\\$" type: enum: - m.room.redaction diff --git a/data/string-formats.yaml b/data/string-formats.yaml index fca325b9..9d41c402 100644 --- a/data/string-formats.yaml +++ b/data/string-formats.yaml @@ -66,6 +66,11 @@ mx-mxc-uri: url: client-server-api#matrix-content-mxc-uris # regex: "^mxc:\\/\\/" +mx-unpadded-base64: + title: Unpadded Base64 + url: appendices#unpadded-base64 + # no regex + uri: title: URI url: https://datatracker.ietf.org/doc/html/rfc3986 From a69e6184d0a55d10c9c679e01b7ad7ce26986280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= Date: Mon, 30 Mar 2026 17:59:32 +0200 Subject: [PATCH 2/3] Fix links to endpoints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Commaille --- content/client-server-api/_index.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/content/client-server-api/_index.md b/content/client-server-api/_index.md index 410a1f25..df67ffc5 100644 --- a/content/client-server-api/_index.md +++ b/content/client-server-api/_index.md @@ -3347,8 +3347,8 @@ 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 `from`/`to` -parameter to the [`/rooms//messages`](/client-server-api/#get_matrixclientv3roomsroomidmessages) API to retrieve earlier -messages. +parameter to the [`/rooms/{roomId}/messages`](#get_matrixclientv3roomsroomidmessages) +API to retrieve earlier messages. For example, a `/sync` request might return a range of four events `E2`, `E3`, `E4` and `E5` within a given room, omitting two prior events @@ -3367,7 +3367,8 @@ response to the previous call as the `since` parameter. The client should also pass a `timeout` parameter. The server will then hold open the HTTP connection for a short period of time waiting for new events, returning early if an event occurs. Only the `/sync` API (and the -deprecated `/events` API) support long-polling in this way. +deprecated [`/events`](#get_matrixclientv3events) API) support +long-polling in this way. Continuing the example above, an incremental sync might report a single new event `E6`. The response can be visualised as: @@ -3387,7 +3388,7 @@ containing only the most recent message events. A state "delta" is also returned, summarising any state changes in the omitted part of the timeline. The client may therefore end up with "gaps" in its knowledge of the message timeline. The client can fill these gaps using the -[`/rooms//messages`](/client-server-api/#get_matrixclientv3roomsroomidmessages) API. +[`/rooms/{roomId}/messages`](#get_matrixclientv3roomsroomidmessages) API. Continuing our example, suppose we make a third `/sync` request asking for events since the last sync, by passing the `next_batch` token `x-y-z` as @@ -3410,7 +3411,7 @@ The limited response includes a state delta which describes how the state of the room changes over the gap. This delta explains how to build the state prior to returned timeline (i.e. at `E7`) from the state the client knows (i.e. at `E6`). To close the gap, the client should make a request to -[`/rooms//messages`](/client-server-api/#get_matrixclientv3roomsroomidmessages) +[`/rooms/{roomId}/messages`](#get_matrixclientv3roomsroomidmessages) with the query parameters `from=x-y-z` and `to=d-e-f`. {{% boxes/warning %}} From 37b1b8eebedf625b966b9652f5e5a9fd756efbfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= Date: Mon, 30 Mar 2026 18:02:27 +0200 Subject: [PATCH 3/3] Add changelog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Commaille --- changelogs/client_server/newsfragments/2349.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2349.clarification diff --git a/changelogs/client_server/newsfragments/2349.clarification b/changelogs/client_server/newsfragments/2349.clarification new file mode 100644 index 00000000..bdcce777 --- /dev/null +++ b/changelogs/client_server/newsfragments/2349.clarification @@ -0,0 +1 @@ +Clarify formats of string types.