Merge remote-tracking branch 'matrix-org/master' into anoa/document_as_options

pull/977/head
Travis Ralston 6 years ago
commit 24edec67c3

@ -0,0 +1,64 @@
gendoc: &gendoc
name: Generate the docs
command: |
source /env/bin/activate
scripts/gendoc.py
genswagger: &genswagger
name: Generate the swagger
command: |
source /env/bin/activate
scripts/dump-swagger.py
buildswaggerui: &buildswaggerui
name: Build Swagger UI
command: |
ls scripts/
mkdir -p api/client-server
git clone https://github.com/matrix-org/swagger-ui swagger-ui
cp -r swagger-ui/dist/* api/client-server/
mkdir -p api/client-server/json
cp scripts/swagger/api-docs.json api/client-server/json/
wget https://raw.githubusercontent.com/matrix-org/matrix.org/master/content/swagger.css -O api/client-server/swagger.css
wget https://raw.githubusercontent.com/matrix-org/matrix.org/master/scripts/swagger-ui.patch
patch api/client-server/index.html swagger-ui.patch
version: 2
jobs:
build-docs:
docker:
- image: uhoreg/matrix-doc-build
steps:
- checkout
- run: *gendoc
- store_artifacts:
path: scripts/gen
- run:
name: "Doc build is available at:"
command: DOCS_URL="${CIRCLE_BUILD_URL}/artifacts/${CIRCLE_NODE_INDEX}/${CIRCLE_WORKING_DIRECTORY/#\~/$HOME}/scripts/gen/index.html"; echo $DOCS_URL
build-swagger:
docker:
- image: uhoreg/matrix-doc-build
steps:
- checkout
- run: *genswagger
- run: *buildswaggerui
- store_artifacts:
path: api/client-server/
- run:
name: "Swagger UI is available at:"
command: DOCS_URL="${CIRCLE_BUILD_URL}/artifacts/${CIRCLE_NODE_INDEX}/${CIRCLE_WORKING_DIRECTORY/#\~/$HOME}/api/client-server/index.html"; echo $DOCS_URL
workflows:
version: 2
build-spec:
jobs:
- build-docs
- build-swagger
notify:
webhooks:
- url: https://giles.cadair.com/circleci

3
.gitignore vendored

@ -1,7 +1,7 @@
/api/node_modules
/assets
/assets.tar.gz
/env
/env*
/scripts/gen
/scripts/continuserv/continuserv
/scripts/speculator/speculator
@ -10,3 +10,4 @@
/templating/out
*.pyc
*.swp
_rendered.rst

@ -1,16 +0,0 @@
language: go
go:
- 1.8
sudo: false
# we only need a single git commit
git:
depth: 1
# test-and-build does the installation, so tell travis to skip the
# installation step
install: true
script:
- ./scripts/test-and-build.sh

@ -69,6 +69,41 @@ For such changes, please do just open a `pull request`_.
.. _pull request: https://help.github.com/articles/about-pull-requests
Adding to the changelog
~~~~~~~~~~~~~~~~~~~~~~~
Currently only changes to the client-server API need to end up in a changelog. The
other APIs are not yet stable and therefore do not have a changelog. Adding to the
changelog can only be done after you've opened your pull request, so be sure to do
that first.
The changelog is managed by Towncrier (https://github.com/hawkowl/towncrier) in the
form of "news fragments". The news fragments for the client-server API are stored
under ``changelogs/client_server/newsfragments``.
To create a changelog entry, create a file named in the format ``prNumber.type`` in
the ``newsfragments`` directory. The ``type`` can be one of the following:
* ``new`` - Used when adding new endpoints. Please have the file contents be the
method and route being added, surrounded in RST code tags. For example: ``POST
/accounts/whoami``
* ``feature`` - Used when adding backwards-compatible changes to the API.
* ``clarification`` - Used when an area of the spec is being improved upon and does
not change or introduce any functionality.
* ``breaking`` - Used when the change is not backwards compatible.
* ``deprecation`` - Used when deprecating something
All news fragments must have a brief summary explaining the change in the contents
of the file.
Changes that do not change the spec, such as changes to the build script, formatting,
CSS, etc should not get a news fragment.
Sign off
--------

@ -41,9 +41,9 @@ specs and event schemas in this repository.
Preparation
-----------
To use the scripts, it is best to create a Python 2.x virtualenv as follows::
To use the scripts, it is best to create a Python 3.4+ virtualenv as follows::
virtualenv env
virtualenv -p python3 env
env/bin/pip install -r scripts/requirements.txt
(Benjamin Synders has contributed a script for `Nix`_ users, which can be

@ -1,4 +1,5 @@
# Copyright 2016 OpenMarket Ltd
# Copyright 2018 New Vector Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -29,8 +30,12 @@ paths:
put:
summary: Send some events to the application service.
description: |-
This API is called by the HS when the HS wants to push an event (or
batch of events) to the AS.
This API is called by the homeserver when it wants to push an event
(or batch of events) to the application service.
Note that the application service should distinguish state events
from message events via the presence of a ``state_key``, rather than
via the event type.
operationId: sendTransaction
parameters:
- in: path
@ -47,33 +52,33 @@ paths:
schema:
type: object
example: {
"events": [
{
"age": 32,
"content": {
"body": "incoming message",
"msgtype": "m.text"
},
"event_id": "$14328055551tzaee:localhost",
"origin_server_ts": 1432804485886,
"room_id": "!TmaZBKYIFrIPVGoUYp:localhost",
"type": "m.room.message",
"user_id": "@bob:localhost"
"events": [
{
"age": 32,
"content": {
"body": "incoming message",
"msgtype": "m.text"
},
"event_id": "$14328055551tzaee:localhost",
"origin_server_ts": 1432804485886,
"room_id": "!TmaZBKYIFrIPVGoUYp:localhost",
"type": "m.room.message",
"user_id": "@bob:localhost"
},
{
"age": 1984,
"content": {
"body": "another incoming message",
"msgtype": "m.text"
},
{
"age": 1984,
"content": {
"body": "another incoming message",
"msgtype": "m.text"
},
"event_id": "$1228055551ffsef:localhost",
"origin_server_ts": 1432804485886,
"room_id": "!TmaZBKYIFrIPVGoUYp:localhost",
"type": "m.room.message",
"user_id": "@bob:localhost"
}
]
}
"event_id": "$1228055551ffsef:localhost",
"origin_server_ts": 1432804485886,
"room_id": "!TmaZBKYIFrIPVGoUYp:localhost",
"type": "m.room.message",
"user_id": "@bob:localhost"
}
]
}
description: "Transaction informations"
properties:
events:
@ -88,10 +93,9 @@ paths:
description: The transaction was processed successfully.
examples:
application/json: {
}
}
schema:
type: object
"/rooms/{roomAlias}":
get:
summary: Query if a room alias should exist on the application service.
@ -119,7 +123,7 @@ paths:
before responding.
examples:
application/json: {
}
}
schema:
type: object
401:
@ -128,29 +132,29 @@ paths:
Optional error information can be included in the body of this response.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED"
}
"errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED"
}
schema:
type: object
$ref: ../client-server/definitions/errors/error.yaml
403:
description: |-
The credentials supplied by the homeserver were rejected.
examples:
application/json: {
"errcode": "M_FORBIDDEN"
}
"errcode": "COM.EXAMPLE.MYAPPSERVICE_FORBIDDEN"
}
schema:
type: object
$ref: ../client-server/definitions/errors/error.yaml
404:
description: |-
The application service indicates that this room alias does not exist.
Optional error information can be included in the body of this response.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND"
}
"errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND"
}
schema:
type: object
$ref: ../client-server/definitions/errors/error.yaml
"/users/{userId}":
get:
summary: Query if a user should exist on the application service.
@ -175,7 +179,7 @@ paths:
service MUST create the user using the client-server API.
examples:
application/json: {
}
}
schema:
type: object
401:
@ -184,26 +188,266 @@ paths:
Optional error information can be included in the body of this response.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED"
}
"errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED"
}
schema:
type: object
$ref: ../client-server/definitions/errors/error.yaml
403:
description: |-
The credentials supplied by the homeserver were rejected.
examples:
application/json: {
"errcode": "M_FORBIDDEN"
}
"errcode": "COM.EXAMPLE.MYAPPSERVICE_FORBIDDEN"
}
schema:
type: object
$ref: ../client-server/definitions/errors/error.yaml
404:
description: |-
The application service indicates that this user does not exist.
Optional error information can be included in the body of this response.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND"
}
"errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND"
}
schema:
type: object
$ref: ../client-server/definitions/errors/error.yaml
"/_matrix/app/unstable/thirdparty/protocol/{protocol}":
get:
summary: Retrieve metadata about a specific protocol that the application service supports.
description: |-
This API is called by the homeserver when it wants to present clients
with specific information about the various third party networks that
an application service supports.
operationId: getProtocolMetadata
parameters:
- in: path
name: protocol
type: string
description: The protocol ID.
required: true
x-example: "irc"
responses:
200:
description: The protocol was found and metadata returned.
schema:
$ref: definitions/protocol_metadata.yaml
401:
description: |-
The homeserver has not supplied credentials to the application service.
Optional error information can be included in the body of this response.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
403:
description: |-
The credentials supplied by the homeserver were rejected.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_FORBIDDEN"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
404:
description: No protocol was found with the given path.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
"/_matrix/app/unstable/thirdparty/user/{protocol}":
get:
summary: Retrieve the Matrix User ID of a corresponding third party user.
description: |-
This API is called by the homeserver in order to retrieve a Matrix
User ID linked to a user on the third party network, given a set of
user parameters.
operationId: queryUserByProtocol
parameters:
- in: path
name: protocol
type: string
description: The protocol ID.
required: true
x-example: irc
- in: query
name: fields...
type: string
description: |-
One or more custom fields that are passed to the application
service to help identify the user.
responses:
200:
description: The Matrix User IDs found with the given parameters.
schema:
$ref: definitions/user_batch.yaml
401:
description: |-
The homeserver has not supplied credentials to the application service.
Optional error information can be included in the body of this response.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
403:
description: |-
The credentials supplied by the homeserver were rejected.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_FORBIDDEN"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
404:
description: No users were found with the given parameters.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
"/_matrix/app/unstable/thirdparty/location/{protocol}":
get:
summary: Retreive Matrix-side portal rooms leading to a third party location.
description: |-
Retrieve a list of Matrix portal rooms that lead to the matched third party location.
operationId: queryLocationByProtocol
parameters:
- in: path
name: protocol
type: string
description: The protocol ID.
required: true
x-example: irc
- in: query
name: fields...
type: string
description: |-
One or more custom fields that are passed to the application
service to help identify the third party location.
responses:
200:
description: At least one portal room was found.
schema:
$ref: definitions/location_batch.yaml
401:
description: |-
The homeserver has not supplied credentials to the application service.
Optional error information can be included in the body of this response.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
403:
description: |-
The credentials supplied by the homeserver were rejected.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_FORBIDDEN"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
404:
description: No mappings were found with the given parameters.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
"/_matrix/app/unstable/thirdparty/location":
get:
summary: Reverse-lookup third party locations given a Matrix room alias.
description: |-
Retreive an array of third party network locations from a Matrix room
alias.
operationId: queryLocationByAlias
parameters:
- in: query
name: alias
type: string
description: The Matrix room alias to look up.
responses:
200:
description: |-
All found third party locations.
schema:
$ref: definitions/location_batch.yaml
401:
description: |-
The homeserver has not supplied credentials to the application service.
Optional error information can be included in the body of this response.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
403:
description: |-
The credentials supplied by the homeserver were rejected.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_FORBIDDEN"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
404:
description: No mappings were found with the given parameters.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
"/_matrix/app/unstable/thirdparty/user":
get:
summary: Reverse-lookup third party users given a Matrix User ID.
description: |-
Retreive an array of third party users from a Matrix User ID.
operationId: queryUserByID
parameters:
- in: query
name: userid
type: string
description: The Matrix User ID to look up.
responses:
200:
description: |-
An array of third party users.
schema:
$ref: definitions/user_batch.yaml
401:
description: |-
The homeserver has not supplied credentials to the application service.
Optional error information can be included in the body of this response.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
403:
description: |-
The credentials supplied by the homeserver were rejected.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml
404:
description: No mappings were found with the given parameters.
examples:
application/json: {
"errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND"
}
schema:
$ref: ../client-server/definitions/errors/error.yaml

@ -0,0 +1,30 @@
# Copyright 2018 New Vector Ltd
#
# 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.
properties:
alias:
description: An alias for a matrix room.
type: string
example: "#freenode_#matrix:matrix.org"
protocol:
description: The protocol ID that the third party location is a part of.
type: string
example: irc
fields:
description: Information used to identify this third party location.
type: object
example:
"network": "freenode"
"channel": "#matrix"
title: Location
type: object

@ -0,0 +1,17 @@
# Copyright 2018 New Vector Ltd
#
# 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: array
description: List of matched third party locations.
items:
$ref: location.yaml

@ -0,0 +1,79 @@
# Copyright 2018 New Vector Ltd
#
# 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.
properties:
user_fields:
description: Fields used to identify a third party user.
type: array
items:
type: string
description: Field used to identify a third party user.
example: ["network", "nickname"]
location_fields:
description: Fields used to identify a third party location.
type: array
items:
type: string
description: Field used to identify a third party location.
example: ["network", "channel"]
icon:
description: An icon representing the third party protocol.
type: string
example: "mxc://example.org/aBcDeFgH"
field_types:
title: Field Types
description: All location or user fields should have an entry here.
type: object
properties:
fieldname:
title: Field Type
description: Definition of valid values for a field.
type: object
properties:
regexp:
description: A regular expression for validation of a field's value.
type: string
placeholder:
description: An placeholder serving as a valid example of the field value.
type: string
example: {
"network": {
"regexp": "([a-z0-9]+\\.)*[a-z0-9]+",
"placeholder": "irc.example.org"
},
"nickname": {
"regexp": "[^\\s#]+",
"placeholder": "username"
},
"channel": {
"regexp": "#[^\\s]+",
"placeholder": "#foobar"
}
}
instances:
description: |-
A list of objects representing independent instances of configuration.
For instance multiple networks on IRC if multiple are bridged by the
same bridge.
type: array
items:
type: object
example: {
"desc": "Freenode",
"icon": "mxc://example.org/JkLmNoPq",
"fields": {
"network": "freenode.net",
}
}
title: Protocol
type: object

@ -0,0 +1,68 @@
# Copyright 2018 New Vector Ltd
#
# 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: Dictionary of supported third party protocols.
additionalProperties:
$ref: protocol.yaml
example: {
"irc": {
"user_fields": ["network", "nickname"],
"location_fields": ["network", "channel"],
"icon": "mxc://example.org/aBcDeFgH",
"field_types": {
"network": {
"regexp": "([a-z0-9]+\\.)*[a-z0-9]+",
"placeholder": "irc.example.org"
},
"nickname": {
"regexp": "[^\\s]+",
"placeholder": "username"
},
"channel": {
"regexp": "#[^\\s]+",
"placeholder": "#foobar"
}
},
"instances": [
{
"desc": "Freenode",
"icon": "mxc://example.org/JkLmNoPq",
"fields": {
"network": "freenode.net",
}
}
]
},
"gitter": {
"user_fields": ["username"],
"location_fields": ["room"],
"field_types": {
"username": {
"regexp": "@[^\\s]+",
"placeholder": "@username"
},
"room": {
"regexp": "[^\\s]+\\/[^\\s]+",
"placeholder": "matrix-org/matrix-doc"
}
},
"instances": [
{
"desc": "Gitter",
"icon": "mxc://example.org/zXyWvUt",
"fields": {}
}
]
}
}

@ -0,0 +1,31 @@
# Copyright 2018 New Vector Ltd
#
# 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.
# TODO: Change userid to user_id as a breaking change
properties:
userid:
description: A Matrix User ID represting a third party user.
type: string
example: "@_gitter_jim:matrix.org"
protocol:
description: The protocol ID that the third party location is a part of.
type: string
example: gitter
fields:
description: Information used to identify this third party location.
type: object
example:
"user": "jim"
title: User
type: object

@ -0,0 +1,17 @@
# Copyright 2018 New Vector Ltd
#
# 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: array
description: List of matched third party users.
items:
$ref: user.yaml

@ -43,21 +43,23 @@ except ImportError as e:
raise
def check_schema(filepath, example, schema):
example = resolve_references(filepath, example)
schema = resolve_references(filepath, schema)
resolver = jsonschema.RefResolver(filepath, schema, handlers={"file": load_file})
jsonschema.validate(example, schema, resolver=resolver)
def check_parameter(filepath, request, parameter):
schema = parameter.get("schema")
example = schema.get('example')
fileurl = "file://" + os.path.abspath(filepath)
if example and schema:
try:
print ("Checking request schema for: %r %r" % (
print("Checking request schema for: %r %r" % (
filepath, request
))
# Setting the 'id' tells jsonschema where the file is so that it
# can correctly resolve relative $ref references in the schema
schema['id'] = fileurl
resolver = jsonschema.RefResolver(filepath, schema, handlers={"file": load_yaml})
jsonschema.validate(example, schema, resolver=resolver)
check_schema(filepath, example, schema)
except Exception as e:
raise ValueError("Error validating JSON schema for %r" % (
request
@ -67,17 +69,12 @@ def check_parameter(filepath, request, parameter):
def check_response(filepath, request, code, response):
example = response.get('examples', {}).get('application/json')
schema = response.get('schema')
fileurl = "file://" + os.path.abspath(filepath)
if example and schema:
try:
print ("Checking response schema for: %r %r %r" % (
filepath, request, code
))
# Setting the 'id' tells jsonschema where the file is so that it
# can correctly resolve relative $ref references in the schema
schema['id'] = fileurl
resolver = jsonschema.RefResolver(filepath, schema, handlers={"file": load_yaml})
jsonschema.validate(example, schema, resolver=resolver)
check_schema(filepath, example, schema)
except Exception as e:
raise ValueError("Error validating JSON schema for %r %r" % (
request, code
@ -104,12 +101,39 @@ def check_swagger_file(filepath):
check_response(filepath, request, code, response)
def load_yaml(path):
if not path.startswith("file:///"):
def resolve_references(path, schema):
if isinstance(schema, dict):
# do $ref first
if '$ref' in schema:
value = schema['$ref']
path = os.path.abspath(os.path.join(os.path.dirname(path), value))
ref = load_file("file://" + path)
result = resolve_references(path, ref)
del schema['$ref']
else:
result = {}
for key, value in schema.items():
result[key] = resolve_references(path, value)
return result
elif isinstance(schema, list):
return [resolve_references(path, value) for value in schema]
else:
return schema
def load_file(path):
print("Loading reference: %s" % path)
if not path.startswith("file://"):
raise Exception("Bad ref: %s" % (path,))
path = path[len("file://"):]
with open(path, "r") as f:
return yaml.load(f)
if path.endswith(".json"):
return json.load(f)
else:
# We have to assume it's YAML because some of the YAML examples
# do not have file extensions.
return yaml.load(f)
if __name__ == '__main__':

@ -66,7 +66,7 @@ paths:
medium:
type: string
description: The medium of the third party identifier.
enum: ["email"]
enum: ["email", "msisdn"]
address:
type: string
description: The third party identifier address.
@ -129,6 +129,8 @@ paths:
"errcode": "M_THREEPID_AUTH_FAILED",
"error": "The third party credentials could not be verified by the identity server."
}
schema:
"$ref": "definitions/errors/error.yaml"
tags:
- User data
"/account/3pid/email/requestToken":
@ -141,7 +143,21 @@ paths:
validation tokens when adding an email address to an account. This API's
parameters and response is identical to that of the HS API
|/register/email/requestToken|_ endpoint.
operationId: requestTokenTo3PID
operationId: requestTokenTo3PIDEmail
responses:
200:
description: An email was sent to the given address.
"/account/3pid/msisdn/requestToken":
post:
summary: Requests a validation token be sent to the given email address for the purpose of adding a phone number to an account.
description: |-
Proxies the identity server API ``validate/msisdn/requestToken``, but
first checks that the given phone number is **not** already associated
with an account on this Home Server. This API should be used to request
validation tokens when adding a phone number to an account. This API's
parameters and response is identical to that of the HS API
|/register/msisdn/requestToken|_ endpoint.
operationId: requestTokenTo3PIDMSISDN
responses:
200:
description: An email was sent to the given address
description: An SMS message was sent to the given phone number.

@ -61,7 +61,8 @@ paths:
description: The fully qualified user ID of the user being banned.
reason:
type: string
description: The reason the user has been banned.
description: The reason the user has been banned. This will be supplied as the
``reason`` on the target's updated `m.room.member`_ event.
required: ["user_id"]
responses:
200:
@ -82,6 +83,8 @@ paths:
"errcode": "M_FORBIDDEN",
"error": "You do not have a high enough power level to ban from this room."
}
schema:
"$ref": "definitions/errors/error.yaml"
tags:
- Room membership
"/rooms/{roomId}/unban":
@ -133,5 +136,7 @@ paths:
"errcode": "M_FORBIDDEN",
"error": "You do not have a high enough power level to unban from this room."
}
schema:
"$ref": "definitions/errors/error.yaml"
tags:
- Room membership

@ -72,7 +72,7 @@ paths:
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- Media
"/download/{serverName}/{mediaId}":
@ -100,6 +100,7 @@ paths:
name: allow_remote
x-example: false
required: false
default: true
description: |
Indicates to the server that it should not attempt to fetch the media if it is deemed
remote. This is to prevent routing loops where the server contacts itself. Defaults to
@ -119,7 +120,7 @@ paths:
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- Media
"/download/{serverName}/{mediaId}/{fileName}":
@ -154,6 +155,7 @@ paths:
name: allow_remote
x-example: false
required: false
default: true
description: |
Indicates to the server that it should not attempt to fetch the media if it is deemed
remote. This is to prevent routing loops where the server contacts itself. Defaults to
@ -173,7 +175,7 @@ paths:
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- Media
"/thumbnail/{serverName}/{mediaId}":
@ -221,6 +223,7 @@ paths:
name: allow_remote
x-example: false
required: false
default: true
description: |
Indicates to the server that it should not attempt to fetch the media if it is deemed
remote. This is to prevent routing loops where the server contacts itself. Defaults to
@ -238,7 +241,7 @@ paths:
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- Media
"/preview_url":
@ -293,6 +296,47 @@ paths:
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- Media
"/config":
get:
summary: Get the configuration for the content repository.
description: |-
This endpoint allows clients to retrieve the configuration of the content
repository, such as upload limitations.
Clients SHOULD use this as a guide when using content repository endpoints.
All values are intentionally left optional. Clients SHOULD follow
the advice given in the field description when the field is not available.
**NOTE:** Both clients and server administrators should be aware that proxies
between the client and the server may affect the apparent behaviour of content
repository APIs, for example, proxies may enforce a lower upload size limit
than is advertised by the server on this endpoint.
operationId: getConfig
produces: ["application/json"]
security:
- accessToken: []
responses:
200:
description: The public content repository configuration for the matrix server.
schema:
type: object
properties:
m.upload.size:
type: number
description: |-
The maximum size an upload can be in bytes.
Clients SHOULD use this as a guide when uploading content.
If not listed or null, the size limit should be treated as unknown.
examples:
application/json: {
"m.upload.size": 50000000
}
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/errors/error.yaml"
tags:
- Media

@ -1,4 +1,5 @@
# Copyright 2016 OpenMarket Ltd
# Copyright 2018 New Vector Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -40,7 +41,7 @@ paths:
0. A default ``m.room.power_levels`` event, giving the room creator
(and not other members) permission to send state events.
1. Events set by ``presets``.
1. Events set by the ``preset``.
2. Events listed in ``initial_state``, in the order that they are
listed.
@ -49,6 +50,16 @@ paths:
4. Invite events implied by ``invite`` and ``invite_3pid``.
The available presets do the following with respect to room state:
======================== ============== ====================== ================ =========
Preset ``join_rules`` ``history_visibility`` ``guest_access`` Other
======================== ============== ====================== ================ =========
``private_chat`` ``invite`` ``shared`` ``can_join``
``trusted_private_chat`` ``invite`` ``shared`` ``can_join`` All invitees are given the same power level as the room creator.
``public_chat`` ``public`` ``shared`` ``forbidden``
======================== ============== ====================== ================ =========
operationId: createRoom
security:
- accessToken: []
@ -142,7 +153,7 @@ paths:
room. The expected format of the state events are an object
with type, state_key and content keys set.
Takes precedence over events set by ``presets``, but gets
Takes precedence over events set by ``preset``, but gets
overriden by ``name`` and ``topic`` keys.
items:
type: object
@ -150,29 +161,20 @@ paths:
properties:
type:
type: string
description: The type of event to send.
state_key:
type: string
description: The state_key of the state event. Defaults to an empty string.
content:
type: object
description: The content of the event.
required: ["type", "content"]
preset:
type: string
enum: ["private_chat", "public_chat", "trusted_private_chat"]
description: |-
Convenience parameter for setting various default state events
based on a preset. Must be either:
``private_chat`` =>
``join_rules`` is set to ``invite``.
``history_visibility`` is set to ``shared``.
``trusted_private_chat`` =>
``join_rules`` is set to ``invite``.
``history_visibility`` is set to ``shared``.
All invitees are given the same power level as the room creator.
``public_chat``: =>
``join_rules`` is set to ``public``.
``history_visibility`` is set to ``shared``.
based on a preset.
is_direct:
type: boolean
description: |-
@ -214,6 +216,8 @@ paths:
invalid: for example, the user's ``power_level`` is set below
that necessary to set the room name (``errcode`` set to
``M_INVALID_ROOM_STATE``).
schema:
"$ref": "definitions/errors/error.yaml"
tags:
- Room creation

@ -17,7 +17,9 @@ properties:
errcode:
type: string
description: An error code.
example: M_UNKNOWN
error:
type: string
description: A human-readable error message.
example: An unknown error occurred
required: ["errcode"]

@ -0,0 +1,32 @@
# Copyright 2018 New Vector Ltd
#
# 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.
$ref: error.yaml
type: object
description: The rate limit was reached for this request
properties:
errcode:
type: string
description: The M_LIMIT_EXCEEDED error code
example: M_LIMIT_EXCEEDED
error:
type: string
description: A human-readable error message.
example: Too many requests
retry_after_ms:
type: integer
description: |-
The amount of time in milliseconds the client should wait
before trying the request again.
example: 2000
required: ["errcode"]

@ -0,0 +1,105 @@
# Copyright 2018 New Vector Ltd
#
# 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: A list of the rooms on the server.
required: ["chunk"]
properties:
chunk:
title: "PublicRoomsChunks"
type: array
description: |-
A paginated chunk of public rooms.
items:
type: object
title: "PublicRoomsChunk"
required:
- room_id
- num_joined_members
- world_readable
- guest_can_join
properties:
aliases:
type: array
description: |-
Aliases of the room. May be empty.
items:
type: string
canonical_alias:
type: string
description: |-
The canonical alias of the room, if any.
name:
type: string
description: |-
The name of the room, if any.
num_joined_members:
type: number
description: |-
The number of members joined to the room.
room_id:
type: string
description: |-
The ID of the room.
topic:
type: string
description: |-
The topic of the room, if any.
world_readable:
type: boolean
description: |-
Whether the room may be viewed by guest users without joining.
guest_can_join:
type: boolean
description: |-
Whether guest users may join the room and participate in it.
If they can, they will be subject to ordinary power level
rules like any other user.
avatar_url:
type: string
description: The URL for the room's avatar, if one is set.
next_batch:
type: string
description: |-
A pagination token for the response. The absence of this token
means there are no more results to fetch and the client should
stop paginating.
prev_batch:
type: string
description: |-
A pagination token that allows fetching previous results. The
absence of this token means there are no results before this
batch, i.e. this is the first batch.
total_room_count_estimate:
type: number
description: |-
An estimate on the total number of public rooms, if the
server has an estimate.
example: {
"chunk": [
{
"aliases": ["#murrays:cheese.bar"],
"avatar_url": "mxc://bleeker.street/CHEDDARandBRIE",
"guest_can_join": false,
"name": "CHEESE",
"num_joined_members": 37,
"room_id": "!ol19s:bleecker.street",
"topic": "Tasty tasty cheese",
"world_readable": true
}
],
"next_batch": "p190q",
"prev_batch": "p1902",
"total_room_count_estimate": 115
}

@ -0,0 +1,24 @@
# Copyright 2018 New Vector Ltd
#
# 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.
title: User identifier
description: |-
Identification information for a user
type: object
properties:
type:
type: string
description: The type of identification. See `Identifier types`_ for supported values and additional property descriptions.
required:
- type
additionalProperties: true

@ -68,6 +68,8 @@ paths:
"errcode": "M_UNKNOWN",
"error": "Room alias #monkeys:matrix.org already exists."
}
schema:
"$ref": "definitions/errors/error.yaml"
tags:
- Room directory
get:
@ -118,6 +120,8 @@ paths:
"errcode": "M_NOT_FOUND",
"error": "Room alias #monkeys:matrix.org not found."
}
schema:
"$ref": "definitions/errors/error.yaml"
tags:
- Room directory
delete:

@ -93,9 +93,11 @@ paths:
examples:
application/json: {
"errcode": "M_FORBIDDEN", "error": "@cheeky_monkey:matrix.org is banned from the room"}
schema:
"$ref": "definitions/errors/error.yaml"
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- Room membership

@ -110,10 +110,12 @@ paths:
examples:
application/json: {
"errcode": "M_FORBIDDEN", "error": "You are not invited to this room."}
schema:
"$ref": "definitions/errors/error.yaml"
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- Room membership
"/join/{roomIdOrAlias}":
@ -143,6 +145,15 @@ paths:
description: The room identifier or alias to join.
required: true
x-example: "#monkeys:matrix.org"
- in: query
type: array
items:
type: string
name: server_name
description: |-
The servers to attempt to join the room through. One of the servers
must be participating in the room.
x-example: ["matrix.org", "elsewhere.ca"]
- in: body
name: third_party_signed
schema:
@ -206,9 +217,11 @@ paths:
examples:
application/json: {
"errcode": "M_FORBIDDEN", "error": "You are not invited to this room."}
schema:
"$ref": "definitions/errors/error.yaml"
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- Room membership

@ -194,7 +194,7 @@ paths:
"user_id": "@alice:example.com",
"device_id": "JLAFKJWSCS",
"algorithms": [
"m.olm.curve25519-aes-sha256",
"m.olm.v1.curve25519-aes-sha256",
"m.megolm.v1.aes-sha"
],
"keys": {
@ -247,7 +247,7 @@ paths:
description: algorithm
example: "signed_curve25519"
example:
"@alice:example.com": { "JLAFKJWSCS": "curve25519" }
"@alice:example.com": { "JLAFKJWSCS": "signed_curve25519" }
required:
- one_time_keys
responses:
@ -274,7 +274,7 @@ paths:
type: object
description: |-
One-time keys for the queried devices. A map from user ID, to a
map from ``<algorithm>:<key_id>`` to the key object.
map from devices to a map from ``<algorithm>:<key_id>`` to the key object.
additionalProperties:
type: object
additionalProperties:

@ -34,6 +34,10 @@ paths:
Kick a user from the room.
The caller must have the required power level in order to perform this operation.
Kicking a user adjusts the target member's membership state to be ``leave`` with an
optional ``reason``. Like with other membership changes, a user can directly adjust
the target member's state by making a request to ``/rooms/<room id>/state/m.room.member/<user id>``.
operationId: kick
security:
- accessToken: []
@ -59,7 +63,9 @@ paths:
description: The fully qualified user ID of the user being kicked.
reason:
type: string
description: The reason the user has been kicked.
description: |-
The reason the user has been kicked. This will be supplied as the
``reason`` on the target's updated `m.room.member`_ event.
required: ["user_id"]
responses:
200:
@ -81,5 +87,7 @@ paths:
"errcode": "M_FORBIDDEN",
"error": "You do not have a high enough power level to kick from this room."
}
schema:
"$ref": "definitions/errors/error.yaml"
tags:
- Room membership

@ -64,7 +64,7 @@ paths:
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- Room membership
"/rooms/{roomId}/forget":
@ -78,8 +78,8 @@ paths:
for this room. If all users on a homeserver forget a room, the room is
eligible for deletion from that homeserver.
If the user is currently joined to the room, they will implicitly leave
the room as part of this API call.
If the user is currently joined to the room, they must leave the room
before calling this API.
operationId: forgetRoom
security:
- accessToken: []
@ -99,9 +99,18 @@ paths:
}
schema:
type: object
400:
description: The user has not left the room
examples:
application/json: {
"errcode": "M_UNKNOWN",
"error": "User @example:matrix.org is in room !au1ba7o:matrix.org"
}
schema:
"$ref": "definitions/errors/error.yaml"
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- Room membership

@ -59,6 +59,8 @@ paths:
"errcode": "M_NOT_FOUND",
"error": "Room not found"
}
schema:
"$ref": "definitions/errors/error.yaml"
put:
summary: Sets the visibility of a room in the room directory
description: |-
@ -107,6 +109,8 @@ paths:
"errcode": "M_NOT_FOUND",
"error": "Room not found"
}
schema:
"$ref": "definitions/errors/error.yaml"
"/publicRooms":
get:
summary: Lists the public rooms on the server.
@ -140,98 +144,7 @@ paths:
200:
description: A list of the rooms on the server.
schema:
type: object
description: A list of the rooms on the server.
required: ["chunk"]
properties:
chunk:
title: "PublicRoomsChunks"
type: array
description: |-
A paginated chunk of public rooms.
items:
type: object
title: "PublicRoomsChunk"
required:
- room_id
- num_joined_members
- world_readable
- guest_can_join
properties:
aliases:
type: array
description: |-
Aliases of the room. May be empty.
items:
type: string
canonical_alias:
type: string
description: |-
The canonical alias of the room, if any.
name:
type: string
description: |-
The name of the room, if any.
num_joined_members:
type: number
description: |-
The number of members joined to the room.
room_id:
type: string
description: |-
The ID of the room.
topic:
type: string
description: |-
The topic of the room, if any.
world_readable:
type: boolean
description: |-
Whether the room may be viewed by guest users without joining.
guest_can_join:
type: boolean
description: |-
Whether guest users may join the room and participate in it.
If they can, they will be subject to ordinary power level
rules like any other user.
avatar_url:
type: string
description: The URL for the room's avatar, if one is set.
next_batch:
type: string
description: |-
A pagination token for the response. The absence of this token
means there are no more results to fetch and the client should
stop paginating.
prev_batch:
type: string
description: |-
A pagination token that allows fetching previous results. The
absence of this token means there are no results before this
batch, i.e. this is the first batch.
total_room_count_estimate:
type: number
description: |-
An estimate on the total number of public rooms, if the
server has an estimate.
examples:
application/json: {
"chunk": [
{
"aliases": ["#murrays:cheese.bar"],
"avatar_url": "mxc://bleeker.street/CHEDDARandBRIE",
"guest_can_join": false,
"name": "CHEESE",
"num_joined_members": 37,
"room_id": "!ol19s:bleecker.street",
"topic": "Tasty tasty cheese",
"world_readable": true
}
],
"next_batch": "p190q",
"prev_batch": "p1902",
"total_room_count_estimate": 115
}
$ref: "definitions/public_rooms_response.yaml"
tags:
- Room discovery
post:

@ -1,4 +1,5 @@
# Copyright 2016 OpenMarket Ltd
# Copyright 2018 New Vector Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -28,6 +29,42 @@ securityDefinitions:
$ref: definitions/security.yaml
paths:
"/login":
get:
summary: Get the supported login types to authenticate users
description: |-
Gets the homeserver's supported login types to authenticate users. Clients
should pick one of these and supply it as the ``type`` when logging in.
operationId: getLoginFlows
responses:
200:
description: The login types the homeserver supports
examples:
application/json: {
"flows": [
{"type": "m.login.password"}
]
}
schema:
type: object
properties:
flows:
type: array
description: The homeserver's supported login types
items:
type: object
title: LoginFlow
properties:
type:
description: |-
The login type. This is supplied as the ``type`` when
logging in.
type: string
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- Session management
post:
summary: Authenticates the user.
description: |-
@ -49,7 +86,10 @@ paths:
type: object
example: {
"type": "m.login.password",
"user": "cheeky_monkey",
"identifier": {
"type": "m.id.user",
"user": "cheeky_monkey"
},
"password": "ilovebananas",
"initial_device_display_name": "Jungle Phone"
}
@ -58,15 +98,18 @@ paths:
type: string
enum: ["m.login.password", "m.login.token"]
description: The login type being used.
identifier:
description: Identification information for the user.
"$ref": "definitions/user_identifier.yaml"
user:
type: string
description: The fully qualified user ID or just local part of the user ID, to log in.
description: The fully qualified user ID or just local part of the user ID, to log in. Deprecated in favour of ``identifier``.
medium:
type: string
description: When logging in using a third party identifier, the medium of the identifier. Must be 'email'.
description: When logging in using a third party identifier, the medium of the identifier. Must be 'email'. Deprecated in favour of ``identifier``.
address:
type: string
description: Third party identifier for the user.
description: Third party identifier for the user. Deprecated in favour of ``identifier``.
password:
type: string
description: |-
@ -131,15 +174,19 @@ paths:
"errcode": "M_UNKNOWN",
"error": "Bad login type."
}
schema:
"$ref": "definitions/errors/error.yaml"
403:
description: |-
The login attempt failed. For example, the password may have been incorrect.
examples:
application/json: {
"errcode": "M_FORBIDDEN"}
schema:
"$ref": "definitions/errors/error.yaml"
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- Session management

@ -107,6 +107,7 @@ paths:
items:
type: object
title: RoomEvent
"$ref": "definitions/event-schemas/schema/core-event-schema/room_event.yaml"
examples:
application/json: {
"start": "t47429-4392820_219380_26003_2265",

@ -0,0 +1,103 @@
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Client-Server OpenID API"
version: "1.0.0"
host: localhost:8008
schemes:
- https
- http
basePath: /_matrix/client/%CLIENT_MAJOR_VERSION%
consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/user/{userId}/openid/request_token":
post:
summary: Get an OpenID token object to verify the requester's identity.
description: |-
Gets an OpenID token object that the requester may supply to another
service to verify their identity in Matrix. The generated token is only
valid for exchanging for user information from the federation API for
OpenID.
The access token generated is only valid for the OpenID API. It cannot
be used to request another OpenID access token or call ``/sync``, for
example.
operationId: requestOpenIdToken
security:
- accessToken: []
parameters:
- in: path
type: string
name: userId
description: |-
The user to request and OpenID token for. Should be the user who
is authenticated for the request.
required: true
x-example: "@alice:example.com"
- in: body
name: body
description: An empty object. Reserved for future expansion.
required: true
schema:
type: object
example: {}
responses:
200:
description: |-
OpenID token information. This response is nearly compatible with the
response documented in the `OpenID 1.0 Specification <http://openid.net/specs/openid-connect-core-1_0.html#TokenResponse>`_
with the only difference being the lack of an ``id_token``. Instead,
the Matrix homeserver's name is provided.
examples:
application/json: {
"access_token": "SomeT0kenHere",
"token_type": "Bearer",
"matrix_server_name": "example.com",
"expires_in": 3600,
}
schema:
type: object
properties:
access_token:
type: string
description: |-
An access token the consumer may use to verify the identity of
the person who generated the token. This is given to the federation
API ``GET /openid/userinfo``.
token_type:
type: string
description: The string ``Bearer``.
matrix_server_name:
type: string
description: |-
The homeserver domain the consumer should use when attempting to
verify the user's identity.
expires_in:
type: int
description: |-
The number of seconds before this token expires and a new one must
be generated.
required: ['access_token', 'token_type', 'matrix_server_name', 'expires_in']
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- OpenID

@ -75,7 +75,7 @@ paths:
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- Presence
get:
@ -83,6 +83,8 @@ paths:
description: |-
Get the given user's presence state.
operationId: getPresence
security:
- accessToken: []
parameters:
- in: path
type: string
@ -121,6 +123,17 @@ paths:
description: |-
There is no presence state for this user. This user may not exist or
isn't exposing presence information to you.
schema:
"$ref": "definitions/errors/error.yaml"
403:
description: You are not allowed to see this user's presence status.
examples:
application/json: {
"errcode": "M_FORBIDDEN",
"error": "You are not allowed to see their presence"
}
schema:
"$ref": "definitions/errors/error.yaml"
tags:
- Presence
"/presence/list/{userId}":
@ -176,7 +189,7 @@ paths:
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- Presence
get:

@ -67,7 +67,7 @@ paths:
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- User data
get:
@ -141,7 +141,7 @@ paths:
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- User data
get:

@ -1,4 +1,5 @@
# Copyright 2016 OpenMarket Ltd
# Copyright 2018 New Vector Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -31,30 +32,30 @@ paths:
get:
summary: Gets the current pushers for the authenticated user
description: |-
Gets all currently active pushers for the authenticated user
Gets all currently active pushers for the authenticated user.
operationId: getPushers
security:
- accessToken: []
responses:
200:
description: The pushers for this user
description: The pushers for this user.
examples:
application/json: {
"pushers": [
{
"pushkey": "Xp/MzCt8/9DcSNE9cuiaoT5Ac55job3TdLSSmtmYl4A=",
"kind": "http",
"app_id": "face.mcapp.appy.prod",
"app_display_name": "Appy McAppface",
"device_display_name": "Alice's Phone",
"profile_tag": "xyz",
"lang": "en-US",
"data": {
"url": "https://example.com/_matrix/push/v1/notify"
}
"pushers": [
{
"pushkey": "Xp/MzCt8/9DcSNE9cuiaoT5Ac55job3TdLSSmtmYl4A=",
"kind": "http",
"app_id": "face.mcapp.appy.prod",
"app_display_name": "Appy McAppface",
"device_display_name": "Alice's Phone",
"profile_tag": "xyz",
"lang": "en-US",
"data": {
"url": "https://example.com/_matrix/push/v1/notify"
}
]
}
}
]
}
schema:
type: object
properties:
@ -70,7 +71,7 @@ paths:
pushkey:
type: string
description: |-
This is a unique identifier for this pusher. See `/set` for
This is a unique identifier for this pusher. See ``/set`` for
more detail.
Max length, 512 bytes.
kind:
@ -115,6 +116,19 @@ paths:
description: |-
Required if ``kind`` is ``http``. The URL to use to send
notifications to.
format:
type: string
description: |-
The format to use when sending notifications to the Push
Gateway.
required:
- pushkey
- app_id
- kind
- app_display_name
- device_display_name
- lang
- data
tags:
- Push notifications
"/pushers/set":
@ -130,23 +144,24 @@ paths:
parameters:
- in: body
name: pusher
description: The pusher information
description: The pusher information.
required: true
schema:
type: object
example: {
"lang": "en",
"kind": "http",
"app_display_name": "Mat Rix",
"device_display_name": "iPhone 9",
"profile_tag": "xxyyzz",
"app_id": "com.example.app.ios",
"pushkey": "APA91bHPRgkF3JUikC4ENAHEeMrd41Zxv3hVZjC9KtT8OvPVGJ-hQMRKRrZuJAEcl7B338qju59zJMjw2DELjzEvxwYv7hH5Ynpc1ODQ0aT4U4OFEeco8ohsN5PjL1iC2dNtk2BAokeMCg2ZXKqpc8FXKmhX94kIxQ",
"data": {
"url": "https://push-gateway.location.here"
},
"append": false
}
"lang": "en",
"kind": "http",
"app_display_name": "Mat Rix",
"device_display_name": "iPhone 9",
"profile_tag": "xxyyzz",
"app_id": "com.example.app.ios",
"pushkey": "APA91bHPRgkF3JUikC4ENAHEeMrd41Zxv3hVZjC9KtT8OvPVGJ-hQMRKRrZuJAEcl7B338qju59zJMjw2DELjzEvxwYv7hH5Ynpc1ODQ0aT4U4OFEeco8ohsN5PjL1iC2dNtk2BAokeMCg2ZXKqpc8FXKmhX94kIxQ",
"data": {
"url": "https://push-gateway.location.here/_matrix/push/v1/notify",
"format": "event_id_only"
},
"append": false
}
properties:
pushkey:
type: string
@ -157,11 +172,15 @@ paths:
for APNS or the Registration ID for GCM. If your notification
client has no such concept, use any unique identifier.
Max length, 512 bytes.
If the ``kind`` is ``"email"``, this is the email address to
send notifications to.
kind:
type: string
description: |-
The kind of pusher to configure. ``"http"`` makes a pusher that
sends HTTP pokes. ``null`` deletes the pusher.
sends HTTP pokes. ``"email"`` makes a pusher that emails the
user with unread notifications. ``null`` deletes the pusher.
app_id:
type: string
description: |-
@ -169,6 +188,8 @@ paths:
It is recommended that this end with the platform, such that
different platform versions get different app identifiers.
Max length, 64 chars.
If the ``kind`` is ``"email"``, this is ``"m.email"``.
app_display_name:
type: string
description: |-
@ -188,7 +209,7 @@ paths:
type: string
description: |-
The preferred language for receiving notifications (e.g. 'en'
or 'en-US')
or 'en-US').
data:
type: object
description: |-
@ -201,7 +222,17 @@ paths:
type: string
description: |-
Required if ``kind`` is ``http``. The URL to use to send
notifications to.
notifications to. MUST be an HTTPS URL with a path of
``/_matrix/push/v1/notify``.
example: "https://push-gateway.location.here/_matrix/push/v1/notify"
format:
type: string
description: |-
The format to send notifications in to Push Gateways if the
``kind`` is ``http``. The details about what fields the
homeserver should send to the push gateway are defined in the
`Push Gateway Specification`_. Currently the only format
available is 'event_id_only'.
append:
type: boolean
description: |-
@ -216,22 +247,22 @@ paths:
200:
description: The pusher was set.
examples:
application/json: {
}
application/json: {}
schema:
type: object # empty json object
type: object
description: An empty object.
400:
description: One or more of the pusher values were invalid.
examples:
application/json: {
"error": "Missing parameters: lang, data",
"errcode": "M_MISSING_PARAM"
}
"error": "Missing parameters: lang, data",
"errcode": "M_MISSING_PARAM"
}
schema:
type: object
"$ref": "definitions/errors/error.yaml"
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- Push notifications

@ -438,11 +438,11 @@ paths:
"errcode": "M_UNKNOWN"
}
schema:
type: object
"$ref": "definitions/errors/error.yaml"
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- Push notifications
"/pushrules/{scope}/{kind}/{ruleId}/enabled":

@ -76,6 +76,6 @@ paths:
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- Room participation

@ -177,6 +177,8 @@ paths:
"errcode": "M_USER_IN_USE",
"error": "Desired user ID is already taken."
}
schema:
"$ref": "definitions/errors/error.yaml"
401:
description: |-
The homeserver requires additional authentication information.
@ -185,7 +187,7 @@ paths:
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- User data
"/register/email/requestToken":
@ -194,11 +196,9 @@ paths:
description: |-
Proxies the identity server API ``validate/email/requestToken``, but
first checks that the given email address is not already associated
with an account on this Home Server. Note that, for consistency,
this API takes JSON objects, though the Identity Server API takes
``x-www-form-urlencoded`` parameters. See the Identity Server API for
with an account on this Home Server. See the Identity Server API for
further information.
operationId: requestTokenToRegister
operationId: requestTokenToRegisterEmail
parameters:
- in: body
name: body
@ -248,8 +248,73 @@ paths:
"errcode": "M_THREEPID_IN_USE",
"error": "The specified address is already in use"
}
schema:
"$ref": "definitions/errors/error.yaml"
"/register/msisdn/requestToken":
post:
summary: Requests a validation token be sent to the given phone number for the purpose of registering an account
description: |-
Proxies the identity server API ``validate/msisdn/requestToken``, but
first checks that the given phone number is not already associated
with an account on this Home Server. See the Identity Server API for
further information.
operationId: requestTokenToRegisterMSISDN
parameters:
- in: body
name: body
schema:
type: object
properties:
id_server:
type: string
description: The ID server to send the onward request to as a hostname with an appended colon and port number if the port is not the default.
example: "id.matrix.org"
client_secret:
type: string
description: Client-generated secret string used to protect this session.
example: "this_is_my_secret_string"
country:
type: string
description: |-
The two-letter uppercase ISO country code that the number in
``phone_number`` should be parsed as if it were dialled from.
phone_number:
type: string
description: The phone number.
example: "example@example.com"
send_attempt:
type: number
description: Used to distinguish protocol level retries from requests to re-send the SMS message.
example: 1
required: ["client_secret", "country", "phone_number", "send_attempt"]
responses:
200:
description: |-
An SMS message has been sent to the specified phone number.
Note that this may be an SMS message containing the validation token or it may be informing
the user of an error.
examples:
application/json: {}
schema:
type: object
400:
description: |-
Part of the request was invalid. This may include one of the following error codes:
* ``M_THREEPID_IN_USE`` : The phone number is already registered to an account on this server.
However, if the home server has the ability to send SMS message, it is recommended that the server
instead send an SMS message to the user with instructions on how to reset their password.
This prevents malicious parties from being able to determine if a given phone number
has an account on the Home Server in question.
* ``M_SERVER_NOT_TRUSTED`` : The ``id_server`` parameter refers to an ID server
that is not trusted by this Home Server.
examples:
application/json: {
"errcode": "M_THREEPID_IN_USE",
"error": "The specified address is already in use"
}
schema:
"$ref": "definitions/errors/error.yaml"
"/account/password":
post:
summary: "Changes a user's password."
@ -296,7 +361,7 @@ paths:
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- User data
"/account/password/email/requestToken":
@ -317,10 +382,32 @@ paths:
.. |/register/email/requestToken| replace:: ``/register/email/requestToken``
.. _/register/email/requestToken: #post-matrix-client-%CLIENT_MAJOR_VERSION%-register-email-requesttoken
operationId: requestTokenToResetPassword
operationId: requestTokenToResetPasswordEmail
responses:
200:
description: An email was sent to the given address
"/account/password/msisdn/requestToken":
post:
summary: Requests a validation token be sent to the given phone number for the purpose of resetting a user's password.
description: |-
Proxies the identity server API ``validate/msisdn/requestToken``, but
first checks that the given phone number **is** associated with an account
on this Home Server. This API should be used to request
validation tokens when authenticating for the
`account/password` endpoint. This API's parameters and response are
identical to that of the HS API |/register/msisdn/requestToken|_ except that
`M_THREEPID_NOT_FOUND` may be returned if no account matching the
given email address could be found. The server may instead send an
SMS message to the given address prompting the user to create an account.
`M_THREEPID_IN_USE` may not be returned.
.. |/register/msisdn/requestToken| replace:: ``/register/msisdn/requestToken``
.. _/register/msisdn/requestToken: #post-matrix-client-%CLIENT_MAJOR_VERSION%-register-email-requesttoken
operationId: requestTokenToResetPasswordMSISDN
responses:
200:
description: An SMS message was sent to the given phone number.
"/account/deactivate":
post:
summary: "Deactivate a user's account."
@ -363,7 +450,7 @@ paths:
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- User data
"/register/available":
@ -420,9 +507,11 @@ paths:
"errcode": "M_USER_IN_USE",
"error": "Desired user ID is already taken."
}
schema:
"$ref": "definitions/errors/error.yaml"
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- User data

@ -74,7 +74,7 @@ paths:
properties:
room_events:
type: object
title: "Room Events"
title: Room Events Criteria
description: Mapping of category name to search criteria.
properties:
search_term:
@ -103,7 +103,7 @@ paths:
The order in which to search for results.
By default, this is ``"rank"``.
event_context:
title: "Event Context"
title: Include Event Context
type: object
description: |-
Configures whether any context for the events
@ -169,13 +169,13 @@ paths:
properties:
search_categories:
type: object
title: Categories
title: Result Categories
description: Describes which categories to search in and
their criteria.
properties:
room_events:
type: object
title: Room Event Results
title: Result Room Events
description: Mapping of category name to search criteria.
properties:
count:
@ -227,6 +227,9 @@ paths:
description: |-
The historic profile information of the
users that sent the events returned.
The ``string`` key is the user ID for which
the profile belongs to.
additionalProperties:
type: object
title: User Profile
@ -260,15 +263,24 @@ paths:
The current state for every room in the results.
This is included if the request had the
``include_state`` key set with a value of ``true``.
The ``string`` key is the room ID for which the ``State
Event`` array belongs to.
additionalProperties:
type: array
title: Room State
items:
type: object
"$ref": "definitions/event-schemas/schema/core-event-schema/state_event.yaml"
groups:
type: object
title: Groups
description: Any groups that were requested.
description: |-
Any groups that were requested.
The outer ``string`` key is the group key requested (eg: ``room_id``
or ``sender``). The inner ``string`` key is the grouped value (eg:
a room's ID or a user's ID).
additionalProperties:
type: object
title: Group Key
@ -355,6 +367,6 @@ paths:
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- Search

@ -253,6 +253,14 @@ paths:
description: |-
Information on end-to-end device updates, as specified in
|device_lists_sync|_.
device_one_time_keys_count:
title: One-time keys count
type: object
additionalProperties:
type: integer
description: |-
Information on end-to-end encryption keys, as specified
in |device_lists_sync|_.
examples:
application/json: {
"next_batch": "s72595_4483_1934",

@ -1,4 +1,5 @@
# Copyright 2016 OpenMarket Ltd
# Copyright 2018 New Vector Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -64,8 +65,9 @@ paths:
examples:
application/json: {
"tags": {
"work": {"order": "1"},
"pinned": {}
"m.favourite": {},
"u.Work": {"order": "1"},
"u.Customers": {}
}
}
tags:

@ -0,0 +1,208 @@
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Client-Server Third Party Lookup API"
version: "1.0.0"
host: localhost:8008
schemes:
- https
- http
basePath: /_matrix/client/%CLIENT_MAJOR_VERSION%
consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/thirdparty/protocols":
get:
summary: Retrieve metadata about all protocols that a homeserver supports.
description: |-
Fetches the overall metadata about protocols supported by the
homeserver. Includes both the available protocols and all fields
required for queries against each protocol.
operationId: getProtocols
security:
- accessToken: []
responses:
200:
description: The protocols supported by the homeserver.
schema:
$ref: ../application-service/definitions/protocol_metadata.yaml
"/thirdparty/protocol/{protocol}":
get:
summary: Retrieve metadata about a specific protocol that the homeserver supports.
description: |-
Fetches the metadata from the homeserver about a particular third party protocol.
operationId: getProtocolMetadata
security:
- accessToken: []
parameters:
- in: path
name: protocol
type: string
description: |-
The name of the protocol.
required: true
x-example: "irc"
responses:
200:
description: The protocol was found and metadata returned.
schema:
$ref: ../application-service/definitions/protocol.yaml
404:
description: The protocol is unknown.
examples:
application/json: {
"errcode": "M_NOT_FOUND"
}
schema:
$ref: definitions/errors/error.yaml
"/thirdparty/location/{protocol}":
get:
summary: Retreive Matrix-side portals rooms leading to a third party location.
description: |-
Requesting this endpoint with a valid protocol name results in a list
of successful mapping results in a JSON array. Each result contains
objects to represent the Matrix room or rooms that represent a portal
to this third party network. Each has the Matrix room alias string,
an identifier for the particular third party network protocol, and an
object containing the network-specific fields that comprise this
identifier. It should attempt to canonicalise the identifier as much
as reasonably possible given the network type.
operationId: queryLocationByProtocol
security:
- accessToken: []
parameters:
- in: path
name: protocol
type: string
description: The protocol used to communicate to the third party network.
required: true
x-example: irc
- in: query
name: searchFields
type: string
description: |-
One or more custom fields to help identify the third party
location.
responses:
200:
description: At least one portal room was found.
schema:
$ref: ../application-service/definitions/location_batch.yaml
404:
description: No portal rooms were found.
examples:
application/json: {
"errcode": "M_NOT_FOUND"
}
schema:
$ref: definitions/errors/error.yaml
"/thirdparty/user/{protocol}":
get:
summary: Retrieve the Matrix User ID of a corresponding third party user.
description: |-
Retrieve a Matrix User ID linked to a user on the third party service, given
a set of user parameters.
operationId: queryUserByProtocol
security:
- accessToken: []
parameters:
- in: path
name: protocol
type: string
description: |-
The name of the protocol.
required: true
x-example: irc
- in: query
name: fields...
type: string
description: |-
One or more custom fields that are passed to the AS to help identify the user.
responses:
200:
description: The Matrix User IDs found with the given parameters.
schema:
$ref: ../application-service/definitions/user_batch.yaml
404:
description: The Matrix User ID was not found
examples:
application/json: {
"errcode": "M_NOT_FOUND"
}
schema:
$ref: definitions/errors/error.yaml
"/thirdparty/location":
get:
summary: Reverse-lookup third party locations given a Matrix room alias.
description: |-
Retreive an array of third party network locations from a Matrix room
alias.
operationId: queryLocationByAlias
security:
- accessToken: []
parameters:
- in: query
name: alias
type: string
description: The Matrix room alias to look up.
required: true
x-example: "#matrix:matrix.org"
responses:
200:
description: |-
All found third party locations.
schema:
$ref: ../application-service/definitions/location_batch.yaml
404:
description: The Matrix room alias was not found
examples:
application/json: {
"errcode": "M_NOT_FOUND"
}
schema:
$ref: definitions/errors/error.yaml
"/thirdparty/user":
get:
summary: Reverse-lookup third party users given a Matrix User ID.
description: |-
Retreive an array of third party users from a Matrix User ID.
operationId: queryUserByID
security:
- accessToken: []
parameters:
- in: query
name: userid
type: string
description: The Matrix User ID to look up.
required: true
x-example: "@bob:matrix.org"
responses:
200:
description: |-
An array of third party users.
schema:
$ref: ../application-service/definitions/user_batch.yaml
404:
description: The Matrix User ID was not found
examples:
application/json: {
"errcode": "M_NOT_FOUND"
}
schema:
$ref: definitions/errors/error.yaml

@ -126,9 +126,11 @@ paths:
examples:
application/json: {
"errcode": "M_FORBIDDEN", "error": "@cheeky_monkey:matrix.org is banned from the room"}
schema:
"$ref": "definitions/errors/error.yaml"
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- Room membership

@ -82,6 +82,6 @@ paths:
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- Room participation

@ -95,6 +95,6 @@ paths:
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- User data

@ -73,6 +73,6 @@ paths:
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- VOIP

@ -65,7 +65,7 @@ paths:
"error": "Unrecognised access token."
}
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/error.yaml"
403:
description:
The appservice cannot masquerade as the user or has not registered them.
@ -75,10 +75,10 @@ paths:
"error": "Application service has not registered this user."
}
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/error.yaml"
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"$ref": "definitions/errors/rate_limited.yaml"
tags:
- User data

@ -0,0 +1,179 @@
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Identity Service Establishing Associations API"
version: "1.0.0"
host: localhost:8090
schemes:
- https
- http
basePath: /_matrix/identity/api/v1
produces:
- application/json
paths:
"/3pid/getValidated3pid":
get:
summary: Check whether ownership of a 3pid was validated.
description: A client can check whether ownership of a 3pid was validated
operationId: getValidated3pid
parameters:
- in: query
type: string
name: sid
description: The Session ID generated by the ``requestToken`` call.
required: true
x-example: 1234
- in: query
type: string
name: client_secret
description: The client secret passed to the ``requestToken`` call.
required: true
x-example: monkeys_are_GREAT
responses:
200:
description: Validation information for the session.
examples:
application/json: {
"medium": "email",
"validated_at": 1457622739026,
"address": "louise@bobs.burgers"
}
schema:
type: object
properties:
medium:
type: string
description: The medium type of the 3pid.
address:
type: string
description: The address of the 3pid being looked up.
validated_at:
type: integer
description: Timestamp indicating the time that the 3pid was validated.
400:
description: |-
The session has not been validated.
If the session has not been validated, then ``errcode`` will be
``M_SESSION_NOT_VALIDATED``. If the session has timed out, then
``errcode`` will be ``M_SESSION_EXPIRED``.
examples:
application/json: {
"errcode": "M_SESSION_NOT_VALIDATED",
"error": "This validation session has not yet been completed"
}
404:
description: The Session ID or client secret were not found
examples:
application/json: {
"errcode": "M_NO_VALID_SESSION",
"error": "No valid session was found matching that sid and client secret"
}
"/bind":
post:
summary: Publish an association between a session and a Matrix user ID.
description: |-
Publish an association between a session and a Matrix user ID.
Future calls to ``/lookup`` for any of the session\'s 3pids will return
this association.
Note: for backwards compatibility with older versions of this
specification, the parameters may also be specified as
``application/x-form-www-urlencoded`` data. However, this usage is
deprecated.
operationId: bind
parameters:
- in: body
name: body
schema:
type: object
example: {
"sid": "1234",
"client_secret": "monkeys_are_GREAT",
"mxid": "@ears:matrix.org"
}
properties:
sid:
type: string
description: The Session ID generated by the ``requestToken`` call.
client_secret:
type: string
description: The client secret passed to the ``requestToken`` call.
mxid:
type: string
description: The Matrix user ID to associate with the 3pids.
required: ["sid", "client_secret", "mxid"]
responses:
200:
description: The association was published.
examples:
application/json: {
"address": "louise@bobs.burgers",
"medium": "email",
"mxid": "@ears:matrix.org",
"not_before": 1428825849161,
"not_after": 4582425849161,
"ts": 1428825849161,
"signatures": {
"matrix.org": {
"ed25519:0": "ENiU2YORYUJgE6WBMitU0mppbQjidDLanAusj8XS2nVRHPu+0t42OKA/r6zV6i2MzUbNQ3c3MiLScJuSsOiVDQ"
}
}
}
schema:
type: object
properties:
address:
type: string
description: The 3pid address of the user being looked up.
medium:
type: string
description: The medium type of the 3pid.
mxid:
type: string
description: The Matrix user ID associated with the 3pid.
not_before:
type: integer
description: A unix timestamp before which the association is not known to be valid.
not_after:
type: integer
description: A unix timestamp after which the association is not known to be valid.
ts:
type: integer
description: The unix timestamp at which the association was verified.
signatures:
type: object
description: The signatures of the verifying identity services which show that the association should be trusted, if you trust the verifying identity services.
400:
description: |-
The association was not published.
If the session has not been validated, then ``errcode`` will be
``M_SESSION_NOT_VALIDATED``. If the session has timed out, then
``errcode`` will be ``M_SESSION_EXPIRED``.
examples:
application/json: {
"errcode": "M_SESSION_NOT_VALIDATED",
"error": "This validation session has not yet been completed"
}
404:
description: The Session ID or client secret were not found
examples:
application/json: {
"errcode": "M_NO_VALID_SESSION",
"error": "No valid session was found matching that sid and client secret"
}

@ -0,0 +1,197 @@
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Identity Service Email Associations API"
version: "1.0.0"
host: localhost:8090
schemes:
- https
- http
basePath: /_matrix/identity/api/v1
produces:
- application/json
paths:
"/validate/email/requestToken":
post:
summary: Request a token for validating an email address.
description: |-
Create a session for validating an email address.
The identity service will send an email containing a token. If that
token is presented to the identity service in the future, it indicates
that that user was able to read the email for that email address, and
so we validate ownership of the email address.
Note that Home Servers offer APIs that proxy this API, adding
additional behaviour on top, for example,
``/register/email/requestToken`` is designed specifically for use when
registering an account and therefore will inform the user if the email
address given is already registered on the server.
Note: for backwards compatibility with older versions of this
specification, the parameters may also be specified as
``application/x-form-www-urlencoded`` data. However, this usage is
deprecated.
operationId: emailRequestToken
parameters:
- in: body
name: body
schema:
type: object
example: {
"client_secret": "monkeys_are_GREAT",
"email": "foo@example.com",
"send_attempt": 1
}
properties:
client_secret:
type: string
description: A unique string used to identify the validation attempt
email:
type: string
description: The email address to validate.
send_attempt:
type: integer
description: |-
Optional. If specified, the server will only send an email if
the ``send_attempt`` is a number greater than the most recent
one which it has seen (or if it has never seen one), scoped
to that ``email`` + ``client_secret`` pair. This is to avoid
repeatedly sending the same email in the case of request
retries between the POSTing user and the identity
service. The client should increment this value if they
desire a new email (e.g. a reminder) to be sent.
next_link:
type: string
description: |-
Optional. When the validation is completed, the identity
service will redirect the user to this URL.
required: ["client_secret", "email"]
responses:
200:
description:
Session created.
examples:
application/json: {
"sid": "1234"
}
schema:
type: object
properties:
sid:
type: string
description: The session ID.
400:
description: |
An error ocurred. Some possible errors are:
- ``M_INVALID_EMAIL``: The email address provided was invalid.
- ``M_EMAIL_SEND_ERROR``: The validation email could not be sent.
"/validate/email/submitToken":
post:
summary: Validate ownership of an email address.
description: |-
Validate ownership of an email address.
If the three parameters are consistent with a set generated by a
``requestToken`` call, ownership of the email address is considered to
have been validated. This does not publish any information publicly, or
associate the email address with any Matrix user ID. Specifically,
calls to ``/lookup`` will not show a binding.
Note: for backwards compatibility with older versions of this
specification, the parameters may also be specified as
``application/x-form-www-urlencoded`` data. However, this usage is
deprecated.
operationId: emailSubmitTokenPost
parameters:
- in: body
name: body
schema:
type: object
example: {
"sid": "1234",
"client_secret": "monkeys_are_GREAT",
"token": "atoken"
}
properties:
sid:
type: string
description: The session ID, generated by the ``requestToken`` call.
client_secret:
type: string
description: The client secret that was supplied to the ``requestToken`` call.
token:
type: string
description: The token generated by the ``requestToken`` call and emailed to the user.
required: ["sid", "client_secret", "token"]
responses:
200:
description:
The success of the validation.
examples:
application/json: {
"success": true
}
schema:
type: object
properties:
success:
type: boolean
description: Whether the validation was successful or not.
get:
summary: Validate ownership of an email address.
description: |-
Validate ownership of an email address.
If the three parameters are consistent with a set generated by a
``requestToken`` call, ownership of the email address is considered to
have been validated. This does not publish any information publicly, or
associate the email address with any Matrix user ID. Specifically,
calls to ``/lookup`` will not show a binding.
Note that, in contrast with the POST version, this endpoint will be
used by end-users, and so the response should be human-readable.
operationId: emailSubmitTokenGet
parameters:
- in: query
type: string
name: sid
required: true
description: The session ID, generated by the ``requestToken`` call.
x-example: 1234
- in: query
type: string
name: client_secret
required: true
description: The client secret that was supplied to the ``requestToken`` call.
x-example: monkeys_are_GREAT
- in: query
type: string
name: token
required: true
description: The token generated by the ``requestToken`` call and emailed to the user.
x-example: atoken
responses:
"200":
description: Email address is validated.
"3xx":
description: |-
Email address is validated, and the ``next_link`` parameter was
provided to the ``requestToken`` call. The user must be redirected
to the URL provided by the ``next_link`` parameter.
"4xx":
description:
Validation failed.

@ -0,0 +1,90 @@
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Identity Service Ephemeral Invitation Signing API"
version: "1.0.0"
host: localhost:8090
schemes:
- https
- http
basePath: /_matrix/identity/api/v1
produces:
- application/json
paths:
"/sign-ed25519":
post:
summary: Sign invitation details
description: |-
Sign invitation details.
The identity server will look up ``token`` which was stored in a call
to ``store-invite``, and fetch the sender of the invite.
operationId: blindlySignStuff
parameters:
- in: body
name: body
schema:
type: object
example: {
"mxid": "@foo:bar.com",
"token": "sometoken",
"private_key": "base64encodedkey"
}
properties:
mxid:
type: string
description: The Matrix user ID of the user accepting the invitation.
token:
type: string
description: Token from the call to ``store-invite``
private_key:
type: string
description: The private key, encoded as `Unpadded base64`_.
required: ["mxid", "token", "private_key"]
responses:
200:
description: The signedjson of the mxid, sender, and token.
schema:
type: object
properties:
mxid:
type: string
description: The Matrix user ID of the user accepting the invitation.
sender:
type: string
description: The Matrix user ID of the user who sent the invitation.
signatures:
type: object
description: The signature of the mxid, sender, and token.
token:
type: string
description: The token for the invitation.
examples:
application/json: {
"mxid": "@foo:bar.com",
"sender": "@baz:bar.com",
"signatures": {
"my.id.server": {
"ed25519:0": "def987"
}
},
"token": "abc123"
}
404:
description: Token was not found.
example: {
"errcode": "M_UNRECOGNIZED",
"error": "Didn't recognize token"
}

@ -0,0 +1,203 @@
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Identity Service Phone Number Associations API"
version: "1.0.0"
host: localhost:8090
schemes:
- https
- http
basePath: /_matrix/identity/api/v1
produces:
- application/json
paths:
"/validate/msisdn/requestToken":
post:
summary: Request a token for validating a phone number.
description: |-
Create a session for validating a phone number.
The identity service will send an SMS message containing a token. If
that token is presented to the identity service in the future, it
indicates that that user was able to read the SMS for that phone
number, and so we validate ownership of the phone number.
Note that Home Servers offer APIs that proxy this API, adding
additional behaviour on top, for example,
``/register/msisdn/requestToken`` is designed specifically for use when
registering an account and therefore will inform the user if the phone
number given is already registered on the server.
Note: for backwards compatibility with older versions of this
specification, the parameters may also be specified as
``application/x-form-www-urlencoded`` data. However, this usage is
deprecated.
operationId: msisdnRequestToken
parameters:
- in: body
name: body
schema:
type: object
example: {
"client_secret": "monkeys_are_GREAT",
"country": "GB",
"phone_number": "07700900001",
"send_attempt": 1
}
properties:
client_secret:
type: string
description: A unique string used to identify the validation attempt.
country:
type: string
description: |-
The two-letter uppercase ISO country code that the number in
``phone_number`` should be parsed as if it were dialled from.
phone_number:
type: string
description: The phone number to validate.
send_attempt:
type: integer
description: |-
Optional. If specified, the server will only send an SMS if
the ``send_attempt`` is a number greater than the most recent
one which it has seen (or if it has never seen one), scoped
to that ``country`` + ``phone_number`` + ``client_secret``
triple. This is to avoid repeatedly sending the same SMS in
the case of request retries between the POSTing user and the
identity service. The client should increment this value if
they desire a new SMS (e.g. a reminder) to be sent.
next_link:
type: string
description: |-
Optional. When the validation is completed, the identity
service will redirect the user to this URL.
required: ["client_secret", "country", "phone_number"]
responses:
200:
description:
Session created.
examples:
application/json: {
"sid": "1234"
}
schema:
type: object
properties:
sid:
type: string
description: The session ID.
400:
description: |
An error ocurred. Some possible errors are:
- ``M_INVALID_ADDRESS``: The phone number provided was invalid.
- ``M_SEND_ERROR``: The validation SMS could not be sent.
"/validate/msisdn/submitToken":
post:
summary: Validate ownership of a phone number.
description: |-
Validate ownership of a phone number.
If the three parameters are consistent with a set generated by a
``requestToken`` call, ownership of the phone number is considered to
have been validated. This does not publish any information publicly, or
associate the phone number address with any Matrix user
ID. Specifically, calls to ``/lookup`` will not show a binding.
Note: for backwards compatibility with older versions of this
specification, the parameters may also be specified as
``application/x-form-www-urlencoded`` data. However, this usage is
deprecated.
operationId: msisdnSubmitTokenPost
parameters:
- in: body
name: body
schema:
type: object
example: {
"sid": "1234",
"client_secret": "monkeys_are_GREAT",
"token": "atoken"
}
properties:
sid:
type: string
description: The session ID, generated by the ``requestToken`` call.
client_secret:
type: string
description: The client secret that was supplied to the ``requestToken`` call.
token:
type: string
description: The token generated by the ``requestToken`` call and sent to the user.
required: ["sid", "client_secret", "token"]
responses:
200:
description:
The success of the validation.
examples:
application/json: {
"success": true
}
schema:
type: object
properties:
success:
type: boolean
description: Whether the validation was successful or not.
get:
summary: Validate ownership of a phone number.
description: |-
Validate ownership of a phone number.
If the three parameters are consistent with a set generated by a
``requestToken`` call, ownership of the phone number address is
considered to have been validated. This does not publish any
information publicly, or associate the phone number with any Matrix
user ID. Specifically, calls to ``/lookup`` will not show a binding.
Note that, in contrast with the POST version, this endpoint will be
used by end-users, and so the response should be human-readable.
operationId: msisdnSubmitTokenGet
parameters:
- in: query
type: string
name: sid
required: true
description: The session ID, generated by the ``requestToken`` call.
x-example: 1234
- in: query
type: string
name: client_secret
required: true
description: The client secret that was supplied to the ``requestToken`` call.
x-example: monkeys_are_GREAT
- in: query
type: string
name: token
required: true
description: The token generated by the ``requestToken`` call and sent to the user.
x-example: atoken
responses:
"200":
description: Phone number is validated.
"3xx":
description: |-
Phone number address is validated, and the ``next_link`` parameter
was provided to the ``requestToken`` call. The user must be
redirected to the URL provided by the ``next_link`` parameter.
"4xx":
description:
Validation failed.

@ -0,0 +1,114 @@
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Identity Service Store Invitations API"
version: "1.0.0"
host: localhost:8090
schemes:
- https
- http
basePath: /_matrix/identity/api/v1
produces:
- application/json
paths:
"/store-invite":
post:
summary: Store pending invitations to a user\'s 3pid.
description: |-
Store pending invitations to a user\'s 3pid.
In addition to the request parameters specified below, an arbitrary
number of other parameters may also be specified. These may be used in
the invite message generation described below.
The service will generate a random token and an ephemeral key used for
accepting the invite.
The service also generates a ``display_name`` for the inviter, which is
a redacted version of ``address`` which does not leak the full contents
of the ``address``.
The service records persistently all of the above information.
It also generates an email containing all of this data, sent to the
``address`` parameter, notifying them of the invitation.
Also, the generated ephemeral public key will be listed as valid on
requests to ``/_matrix/identity/api/v1/pubkey/ephemeral/isvalid``.
operationId: storeInvite
parameters:
- in: body
name: body
schema:
type: object
example: {
"medium": "email",
"address": "foo@bar.baz",
"room_id": "!something:example.tld",
"sender": "@bob:example.com"
}
properties:
medium:
type: string
description: The literal string ``email``.
address:
type: string
description: The email address of the invited user.
room_id:
type: string
description: The Matrix room ID to which the user is invited
sender:
type: string
description: The Matrix user ID of the inviting user
required: ["medium", "address", "room_id", "sender"]
responses:
200:
description: The invitation was stored.
schema:
type: object
properties:
token:
type: string
description: The generated token.
public_keys:
type: array
description: A list of [server\'s long-term public key, generated ephemeral public key].
items:
type: string
display_name:
type: string
description: The generated (redacted) display_name.
example:
application/json: {
"token": "sometoken",
"public_keys": [
"serverpublickey",
"ephemeralpublickey"
],
"display_name": "f...@b..."
}
400:
description: |
An error has occured.
If the 3pid is already bound to a Matrix user ID, the error code
will be ``M_THREEPID_IN_USE``. If the medium is unsupported, the
error code will be ``M_UNRECOGNIZED``.
examples:
application/json: {
"errcode": "M_THREEPID_IN_USE",
"error": "Binding already known",
"mxid": mxid
}

@ -0,0 +1,45 @@
# OpenAPI Extensions
For some functionality that is not directly provided by the OpenAPI v2
specification, some extensions have been added that are to be consistent
across the specification. The defined extensions are listed below. Extensions
should not break parsers, however if extra functionality is required, aware
parsers should be able to take advantage of the added syntax.
## Extensible Query Parameters
<!-- TODO: Remove and change instances to 'explode' after OpenAPI/Swagger v3 update -->
If a unknown amount of query parameters can be added to a request, the `name`
must be `fields...`, with the trailing ellipses representing the possibility
of more fields.
Example:
```
- in: query
name: fields...
type: string
```
## Using oneOf to provide type alternatives
<!-- TODO: Remove this section after upgrading to OpenAPI v3 -->
`oneOf` (available in JSON Schema and Swagger/OpenAPI v3 but not in v2)
is used in cases when a simpler type specification as a list of types
doesn't work, as in the following example:
```
properties:
old: # compliant with old Swagger
type:
- string
- object # Cannot specify a schema here
new: # uses oneOf extension
oneOf:
- type: string
- type: object
title: CustomSchemaForTheWin
properties:
...
```

@ -1,4 +1,5 @@
# Copyright 2016 OpenMarket Ltd
# Copyright 2018 New Vector Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -19,7 +20,7 @@ host: localhost:8008
schemes:
- https
- http
basePath: /_matrix/push/%CLIENT_MAJOR_VERSION%
basePath: /_matrix/push/v1
consumes:
- application/json
produces:
@ -38,14 +39,14 @@ paths:
Notifications about a particular event will normally cause the user to be
alerted in some way. It is therefore necessary to perform duplicate
suppression for such notifications using the `event_id` field to avoid
suppression for such notifications using the ``event_id`` field to avoid
retries of this HTTP API causing duplicate alerts. The operation of
updating counts of unread notifications should be idempotent and
therefore do not require duplicate suppression.
Notifications are sent to the URL configured when the pusher is
created. This means that the HTTP path may be different depending on the
push gateway.
Notifications are sent to the URL configured when the pusher is created.
This means that the HTTP path may be different depending on the push
gateway.
operationId: notify
parameters:
- in: body
@ -55,36 +56,36 @@ paths:
schema:
type: object
example: {
"notification": {
"id": "$3957tyerfgewrf384",
"room_id": "!slw48wfj34rtnrf:example.com",
"type": "m.room.message",
"sender": "@exampleuser:matrix.org",
"sender_display_name": "Major Tom",
"room_name": "Mission Control",
"room_alias": "#exampleroom:matrix.org",
"prio": "high",
"content": {
"msgtype": "m.text",
"body": "I'm floating in a most peculiar way."
},
"counts": {
"unread" : 2,
"missed_calls": 1
},
"devices": [
{
"app_id": "org.matrix.matrixConsole.ios",
"pushkey": "V2h5IG9uIGVhcnRoIGRpZCB5b3UgZGVjb2RlIHRoaXM/",
"pushkey_ts": 12345678,
"data" : {},
"tweaks": {
"sound": "bing"
}
"notification": {
"id": "$3957tyerfgewrf384",
"room_id": "!slw48wfj34rtnrf:example.com",
"type": "m.room.message",
"sender": "@exampleuser:matrix.org",
"sender_display_name": "Major Tom",
"room_name": "Mission Control",
"room_alias": "#exampleroom:matrix.org",
"prio": "high",
"content": {
"msgtype": "m.text",
"body": "I'm floating in a most peculiar way."
},
"counts": {
"unread" : 2,
"missed_calls": 1
},
"devices": [
{
"app_id": "org.matrix.matrixConsole.ios",
"pushkey": "V2h5IG9uIGVhcnRoIGRpZCB5b3UgZGVjb2RlIHRoaXM/",
"pushkey_ts": 12345678,
"data" : {},
"tweaks": {
"sound": "bing"
}
]
}
}
]
}
}
required: ["notification"]
properties:
notification:
@ -111,14 +112,10 @@ paths:
type: string
description: |-
The type of the event as in the event's ``type`` field.
Required if the notification relates to a specific
Matrix event.
sender:
type: string
description: |-
The sender of the event as in the corresponding event field.
Required if the notification relates to a specific
Matrix event.
sender_display_name:
type: string
description: |-
@ -148,15 +145,16 @@ paths:
type: object
title: EventContent
description: |-
The ``content`` field from the event, if present. If the
event had no content field, this field is omitted.
The ``content`` field from the event, if present. The pusher
may omit this if the event had no content or for any other
reason.
counts:
type: object
title: Counts
description: |-
This is a dictionary of the current number of unacknowledged
communications for the recipient user. Counts whose value is
zero are omitted.
zero should be omitted.
properties:
unread:
type: integer
@ -180,10 +178,10 @@ paths:
app_id:
type: string
description: |-
The app_id given when the pusher was created.
The ``app_id`` given when the pusher was created.
pushkey:
type: string
description: The pushkey given when the pusher was created.
description: The ``pushkey`` given when the pusher was created.
pushkey_ts:
type: integer
description: |-
@ -202,13 +200,14 @@ paths:
description: |-
A dictionary of customisations made to the way this
notification is to be presented. These are added by push rules.
required: ['app_id', 'pushkey']
responses:
200:
description: A list of rejected push keys.
examples:
application/json: {
"rejected": [ "V2h5IG9uIGVhcnRoIGRpZCB5b3UgZGVjb2RlIHRoaXM/" ]
}
"rejected": [ "V2h5IG9uIGVhcnRoIGRpZCB5b3UgZGVjb2RlIHRoaXM/" ]
}
schema:
type: object # empty json object
properties:
@ -222,7 +221,8 @@ paths:
pushkeys and remove the associated pushers. It may not
necessarily be the notification in the request that failed:
it could be that a previous notification to the same pushkey
failed.
failed. May be empty.
items:
type: string
description: A pushkey
description: A pushkey that has been rejected.
required: ['rejected']

@ -0,0 +1,148 @@
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Federation Events API"
version: "1.0.0"
host: localhost:8448
schemes:
- https
basePath: /_matrix/federation/v1
consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/backfill/{roomId}":
get:
summary: Retrieves the events which precede the given event
description: |-
Retrieves a sliding-window history of previous PDUs that occurred in the given room.
Starting from the PDU ID(s) given in the ``v`` argument, the PDUs that preceded it
are retrieved, up to the total number given by the ``limit``.
operationId: backfillRoom
security:
- signedRequest: []
parameters:
- in: path
name: roomId
type: string
description: The room ID to backfill.
required: true
x-example: "!SomeRoom:matrix.org"
- in: query
name: v
type: array
items:
type: string
description: The event IDs to backfill from.
required: true
x-example: ["$abc123:matrix.org"]
- in: query
name: limit
type: integer
description: The maximum number of PDUs to retrieve, including the given events.
required: true
x-example: 2
responses:
200:
description: |-
A transaction containing the PDUs that preceded the given event(s), including the given
event(s), up to the given limit.
schema:
$ref: "definitions/transaction.yaml"
# Override the example to show the response of the request a bit better
examples:
application/json: {
"$ref": "examples/transaction.json",
"pdus": [
{
"$ref": "pdu.json",
"room_id": "!SomeRoom:matrix.org",
"event_id": "$abc123:matrix.org"
},
{
"$ref": "pdu.json",
"room_id": "!SomeRoom:matrix.org"
},
]
}
"/get_missing_events/{roomId}":
post:
summary: Retrieves events that the sender is missing
description: |-
Retrieves previous events that the sender is missing. This is done by doing a breadth-first
walk of the ``prev_events`` for the ``latest_events``, ignoring any events in ``earliest_events``
and stopping at the ``limit``.
operationId: getMissingPreviousEvents
security:
- signedRequest: []
parameters:
- in: path
name: roomId
type: string
description: The room ID to search in.
required: true
x-example: "!SomeRoom:matrix.org"
- in: body
name: body
schema:
type: object
properties:
limit:
type: integer
description: The maximum number of events to retrieve. Defaults to 10.
example: 10
min_depth:
type: integer
description: The minimum depth of events to retrieve. Defaults to 0.
example: 0
earliest_events:
type: array
description: |-
The latest events that the sender already has. These are skipped when retrieving
the previous events of ``latest_events``.
items:
type: string
example: ["$missing_event:domain.com"]
latest_events:
type: array
description: The events to retrieve the previous events for.
items:
type: string
example: ["$event_that_has_the_missing_event_as_a_previous_event:domain.com"]
required: ['earliest_events', 'latest_events']
responses:
200:
description: |-
The previous events for ``latest_events``, excluding any ``earliest_events``, up to the
provided ``limit``.
schema:
type: object
properties:
events:
type: array
description: The missing events.
items:
$ref: definitions/pdu.yaml
required: ['events']
examples:
application/json: {
"events": [
{"$ref": "examples/pdu.json"}
]
}

@ -0,0 +1,28 @@
# Copyright 2018 New Vector Ltd
#
# 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: Ephemeral Data Unit
description: An ephemeral data unit.
example:
$ref: "../examples/edu.json"
properties:
edu_type:
type: string
description: The type of ephemeral message.
example: "m.presence"
content:
type: object
description: The content of the ephemeral message.
required: ['edu_type', 'content']

@ -0,0 +1,82 @@
# Copyright 2018 New Vector Ltd
#
# 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: Receipt EDU
description: |-
An EDU representing receipt updates for users of the sending homeserver.
When receiving receipts, the server should only update entries that are
listed in the EDU. Receipts previously received that do not appear in the
EDU should not be removed or otherwise manipulated.
allOf:
- $ref: ../edu.yaml
- type: object
properties:
edu_type:
type: enum
enum: ['m.receipt']
description: The string ``m.receipt``
example: "m.receipt"
content:
type: object
description: |-
Receipts for a particular room. The string key is the room ID for
which the receipts under it belong.
additionalProperties:
type: object
title: Room Receipts
properties:
# We strongly define the receipt type to help spec future ones later
# on. At that point, m.read can become optional (maybe).
"m.read":
type: object
description: Read receipts for users in the room.
title: User Read Receipt
properties:
event_ids:
type: array
description: |-
The extremity event IDs that the user has read up to.
minItems: 1
maxItems: 1
items:
type: string
example: ['$read_this_event:matrix.org']
data:
type: object
description: Metadata for the read receipt.
title: Read Receipt Metadata
properties:
ts:
type: integer
format: int64
description: |-
A POSIX timestamp in milliseconds for when the user read
the event specified in the read receipt.
example: 1533358089009
required: ['ts']
required: ['event_ids', 'data']
required: ['m.read']
example: {
"!some_room:domain.com": {
"m.read": {
"@john:matrix.org": {
"event_ids": ["$read_this_event:matrix.org"],
"data": {
"ts": 1533358089009
}
}
}
}
}

@ -0,0 +1,45 @@
# Copyright 2018 New Vector Ltd
#
# 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: Typing Notification EDU
description: A typing notification EDU for a user in a room.
allOf:
- $ref: ../edu.yaml
- type: object
properties:
edu_type:
type: string
description: The string ``m.typing``
example: "m.typing"
content:
type: object
description: The typing notification.
title: Typing Notification
properties:
room_id:
type: string
description: |-
The room where the user's typing status has been updated.
example: "!somewhere:matrix.org"
user_id:
type: string
description: |-
The user ID that has had their typing status changed.
example: "@john:matrix.org"
typing:
type: boolean
description: Whether the user is typing in the room or not.
example: true
required: ['room_id', 'user_id', 'typing']

@ -0,0 +1,87 @@
# Copyright 2018 New Vector Ltd
#
# 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: Invite Event
description: An invite event
allOf:
- $ref: "pdu.yaml"
- type: object
properties:
# Note: we override a bunch of parameters to change their descriptions
sender:
type: string
# TODO: Verify/clarify this - it doesn't seem right, given this is a 'regular' invite
description: |-
The matrix ID of the user who sent the original ``m.room.third_party_invite``.
example: "@someone:example.org"
origin:
type: string
description: The name of the inviting homeserver.
example: "matrix.org"
origin_server_ts:
type: integer
format: int64
description: A timestamp added by the inviting homeserver.
example: 1234567890
type:
type: string
description: The value ``m.room.member``.
example: "m.room.member"
state_key:
type: string
description: The user ID of the invited member.
example: "@joe:elsewhere.com"
content:
type: object
title: Membership Event Content
description: |-
The content of the event, matching what is available in the
`Client-Server API`_. Must include a ``membership`` of ``invite``.
example: {"membership": "invite"}
properties:
membership:
type: string
description: The value ``invite``.
example: "invite"
required: ['membership']
auth_events:
type: array
description: |-
An event reference list containing the authorization events that would
allow the member to be invited to the room.
items:
type: array
maxItems: 2
minItems: 2
items:
- type: string
title: Event ID
example: "$abc123:matrix.org"
- type: object
title: Event Hash
example: {
"sha256": "abase64encodedsha256hashshouldbe43byteslong"
}
properties:
sha256:
type: string
description: The event hash.
example: abase64encodedsha256hashshouldbe43byteslong
required: ['sha256']
redacts:
type: string
description: Not used.
required:
# Every other field is already flagged as required by the $ref
- state_key

@ -0,0 +1,110 @@
# Copyright 2018 New Vector Ltd
#
# 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: Server Keys
description: Server keys
example:
$ref: "../examples/server_key.json"
properties:
server_name:
type: string
description: DNS name of the homeserver.
required: true
example: "example.org"
verify_keys:
type: object
description: |-
Public keys of the homeserver for verifying digital signatures.
The object's key is the algorithm and version combined (``ed25519`` being the
algorithm and ``abc123`` being the version in the example below). Together,
this forms the Key ID. The version must have characters matching the regular
expression ``[a-zA-Z0-9_]``.
required: true
additionalProperties:
type: object
title: Verify Key
example: {
"ed25519:abc123": {
"key": "VGhpcyBzaG91bGQgYmUgYSByZWFsIGVkMjU1MTkgcGF5bG9hZA"
}
}
properties:
key:
type: string
description: The `Unpadded Base64`_ encoded key.
required: true
example: "VGhpcyBzaG91bGQgYmUgYSByZWFsIGVkMjU1MTkgcGF5bG9hZA"
old_verify_keys:
type: object
description: |-
The public keys that the server used to use and when it stopped using them.
The object's key is the algorithm and version combined (``ed25519`` being the
algorithm and ``0ldK3y`` being the version in the example below). Together,
this forms the Key ID. The version must have characters matching the regular
expression ``[a-zA-Z0-9_]``.
additionalProperties:
type: object
title: Old Verify Key
example: {
"ed25519:0ldK3y": {
"expired_ts": 1532645052628,
"key": "VGhpcyBzaG91bGQgYmUgeW91ciBvbGQga2V5J3MgZWQyNTUxOSBwYXlsb2FkLg"
}
}
properties:
expired_ts:
type: integer
format: int64
description: POSIX timestamp in milliseconds for when this key expired.
required: true
example: 1532645052628
key:
type: string
description: The `Unpadded Base64`_ encoded key.
required: true
example: "VGhpcyBzaG91bGQgYmUgeW91ciBvbGQga2V5J3MgZWQyNTUxOSBwYXlsb2FkLg"
signatures:
type: object
description: Digital signatures for this object signed using the ``verify_keys``.
additionalProperties:
type: object
title: Signed Server
example: {
"example.org": {
"ad25519:abc123": "VGhpcyBzaG91bGQgYWN0dWFsbHkgYmUgYSBzaWduYXR1cmU"
}
}
additionalProperties:
type: string
name: Encoded Signature Verification Key
tls_fingerprints:
type: array
description: Hashes of X.509 TLS certificates used by this server.
items:
type: object
title: TLS Fingerprint
properties:
sha256:
type: string
description: The `Unpadded Base64`_ encoded fingerprint.
example: "VGhpcyBpcyBoYXNoIHdoaWNoIHNob3VsZCBiZSBieXRlcw"
valid_until_ts:
type: integer
format: int64
description: |-
POSIX timestamp when the list of valid keys should be refreshed. Keys used beyond this
timestamp are no longer valid.
example: 1052262000000

@ -0,0 +1,27 @@
# Copyright 2018 New Vector Ltd
#
# 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: Server keys
example: {
"server_keys": [{
$ref: "../examples/server_key_notary_signed.json"
}]
}
properties:
server_keys:
type: array
title: Server Keys
description: The queried server's keys, signed by the notary server.
items:
$ref: "keys.yaml"

@ -0,0 +1,52 @@
# Copyright 2018 New Vector Ltd
#
# 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)
example:
$ref: "../examples/pdu.json"
allOf:
- $ref: "unsigned_pdu.yaml"
- type: object
properties:
hashes:
type: object
title: Event Hash
description: Hashes of the PDU, following the algorithm specified in `Signing Events`_.
example: {
"sha256": "thishashcoversallfieldsincasethisisredacted"
}
properties:
sha256:
type: string
description: The hash.
example: thishashcoversallfieldsincasthisisredacted
required: ['sha256']
signatures:
type: object
description: |-
Signatures for the PDU, following the algorithm specified in `Signing Events`_.
example: {
"example.com": {
"ed25519:key_version:": "these86bytesofbase64signaturecoveressentialfieldsincludinghashessocancheckredactedpdus"
}
}
additionalProperties:
type: object
title: Server Signatures
additionalProperties:
type: string
required:
- hashes
- signatures

@ -0,0 +1,19 @@
# Copyright 2018 New Vector Ltd
#
# 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.
signedRequest:
type: apiKey
description: |-
The ``Authorization`` header defined in the `Authentication`_ section.
name: Authorization
in: header

@ -0,0 +1,37 @@
# Copyright 2018 New Vector Ltd
#
# 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: Transaction
description: Transaction
example:
$ref: "../examples/transaction.json"
properties:
origin:
type: string
description: |-
The ``server_name`` of the homeserver sending this transaction.
example: "example.org"
origin_server_ts:
type: integer
format: int64
description: |-
POSIX timestamp in milliseconds on originating homeserver when this
transaction started.
example: 1532991320875
pdus:
type: array
description: List of persistent updates to rooms.
items:
$ref: "pdu.yaml"
required: ['origin', 'origin_server_ts', 'pdus']

@ -0,0 +1,152 @@
# Copyright 2018 New Vector Ltd
#
# 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: Unsigned Persistent Data Unit
description: An unsigned persistent data unit (event)
example:
$ref: "../examples/unsigned_pdu.json"
properties:
event_id:
type: string
description: The event ID for the PDU.
example: "$a4ecee13e2accdadf56c1025:example.com"
room_id:
type: string
description: Room identifier.
example: "!abc123:matrix.org"
sender:
type: string
description: The ID of the user sending the event.
example: "@someone:matrix.org"
origin:
type: string
description: The ``server_name`` of the homeserver that created this event.
example: "matrix.org"
origin_server_ts:
type: integer
format: int64
description: Timestamp in milliseconds on origin homeserver when this event was created.
example: 1234567890
type:
type: string
description: Event type
example: "m.room.message"
state_key:
type: string
description: |-
If this key is present, the event is a state event, and it will replace previous events
with the same ``type`` and ``state_key`` in the room state.
example: "my_key"
content:
type: object
description: The content of the event.
example: {"key": "value"}
prev_events:
type: array
description: |-
Event IDs and hashes of the most recent events in the room that the homeserver was aware
of when it made this event.
items:
type: array
maxItems: 2
minItems: 2
items:
- type: string
title: Event ID
example: "$abc123:matrix.org"
- type: object
title: Event Hash
example: {
"sha256": "abase64encodedsha256hashshouldbe43byteslong"
}
properties:
sha256:
type: string
description: The event hash.
example: abase64encodedsha256hashshouldbe43byteslong
required: ['sha256']
depth:
type: integer
description: The maximum depth of the ``prev_events``, plus one.
example: 12
auth_events:
type: array
description: |-
An event reference list containing the authorization events that would
allow this event to be in the room.
items:
type: array
maxItems: 2
minItems: 2
items:
- type: string
title: Event ID
example: "$abc123:matrix.org"
- type: object
title: Event Hash
example: {
"sha256": "abase64encodedsha256hashshouldbe43byteslong"
}
properties:
sha256:
type: string
description: The event hash.
example: abase64encodedsha256hashshouldbe43byteslong
required: ['sha256']
redacts:
type: string
description: For redaction events, the ID of the event being redacted.
example: "$def456:matrix.org"
unsigned:
type: object
title: Example Unsigned Data
description: |-
Additional data added by the origin server but not covered by the ``signatures``. More
keys than those defined here may be used.
example: {"key": "value"}
properties:
age:
type: integer
description: The number of milliseconds that have passed since this message was sent.
example: 4612
replaces_state:
type: string
description: The event ID of the state event this event replaces.
example: "$state_event:domain.com"
prev_sender:
type: string
description: The sender of the replaced state event.
example: "@someone:domain.com"
prev_content:
type: object
description: The content of the replaced state event.
example: {
"membership": "join",
"displayname": "Bob"
}
redacted_because:
type: string
description: A reason for why the event was redacted.
example: "Inappropriate content"
required:
- event_id
- room_id
- sender
- origin
- origin_server_ts
- type
- content
- prev_events
- depth
- auth_events

@ -1,68 +0,0 @@
# Copyright 2017 Kamax.io
#
# 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.
swagger: '2.0'
info:
title: "Matrix Federation Query Directory API"
version: "1.0.0"
host: localhost:8448
schemes:
- https
basePath: /_matrix/federation/v1
produces:
- application/json
paths:
"/query/directory":
get:
summary: Retrieve the room ID and list of resident homeservers for a room
alias.
description: Retrieve the room ID and list of resident homeservers for a Room
alias.
parameters:
- in: query
name: room_alias
type: string
description: Room alias
required: true
x-example: "#room_alias:example.org"
responses:
200:
description: The corresponding room ID and list of known resident
homeservers for the room.
schema:
type: object
properties:
room_id:
type: string
description: The room ID mapped to the queried room alias.
x-example: "!roomid1234:example.org"
servers:
type: array
description: An array of server names that are likely to hold
then given room. This list may or may not include the server
answering the query.
items:
type: string
required:
- "room_id"
- "servers"
examples:
application/json: {
"room_id": "!roomid1234:example.org",
"servers": [
"example.org",
"example.com",
"another.example.com:8449",
]
}

@ -0,0 +1,180 @@
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Federation Event Authorization API"
version: "1.0.0"
host: localhost:8448
schemes:
- https
basePath: /_matrix/federation/v1
consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/event_auth/{roomId}/{eventId}":
get:
summary: Get the auth chain for a given event
description: |-
Retrieves the complete auth chain for a given event.
operationId: getEventAuth
security:
- signedRequest: []
parameters:
- in: path
name: roomId
type: string
description: The room ID to get the auth chain for.
required: true
x-example: "!abc123:matrix.org"
- in: path
name: eventId
type: string
description: The event ID to get the auth chain of.
required: true
x-example: "$helloworld:domain.com"
responses:
200:
description: The auth chain for the event.
schema:
type: object
properties:
auth_chain:
type: array
description: |-
The full set of authorization events that make up the state of
the room, and their authorization events, recursively.
items:
$ref: "definitions/pdu.yaml"
example: [{"$ref": "examples/pdu.json"}]
required: ['auth_chain']
"/query_auth/{roomId}/{eventId}":
post:
summary: Compare auth chains with the receiving server
description: |-
Compares the auth chain provided with what the receiving server has for the
room ID and event ID combination.
The auth difference can be calculated in two parts, where the "remote auth"
is the auth chain provided by the sending server and the "local auth" is the
auth chain the receiving server has. With those lists, the algorithm works
bottom-up after sorting each chain by depth then by event ID. The differences
are then discovered and returned as the response to this API call.
operationId: compareEventAuth
security:
- signedRequest: []
parameters:
- in: path
name: roomId
type: string
description: The room ID to compare the auth chain in.
required: true
x-example: "!abc123:matrix.org"
- in: path
name: eventId
type: string
description: The event ID to compare the auth chain of.
required: true
x-example: "$helloworld:domain.com"
- in: body
name: body
schema:
type: object
properties:
auth_chain:
type: array
description: The auth chain (the "remote auth").
items:
$ref: "definitions/pdu.yaml"
example: [{"$ref": "examples/pdu.json"}]
missing:
type: array
description: |-
A list of event IDs that the sender thinks the receiver is missing.
items:
type: string
example: []
rejects:
type: object
description: |-
The set of events that the sending server has rejected from the provided
auth chain.
The ``string`` key is the event ID that was rejected.
additionalProperties:
type: object
title: Rejection Reason
properties:
reason:
type: enum
enum: ['auth_error', 'replaced', 'not_ancestor']
description: |-
The reason for the event being rejected.
required: ['reason']
example: {
"$some_event:domain.com": {
"reason": "auth_error"
}
}
required: ['auth_chain']
responses:
200:
description: The auth chain differences, as determined by the receiver.
schema:
type: object
properties:
auth_chain:
type: array
description: |-
The auth chain the receiver has, and used to determine the auth
chain differences (the "local auth").
items:
$ref: "definitions/pdu.yaml"
example: [{"$ref": "examples/pdu.json"}]
missing:
type: array
description: |-
The list of event IDs that the receiver believes it is missing,
after comparing the "remote auth" and "local auth" chains.
items:
type: string
example: ["$a_missing_event:domain.com"]
rejects:
type: object
description: |-
The set of events that the receiving server has rejected from the
auth chain, not including events that the sending server is missing
as determined from the difference algorithm.
The ``string`` key is the event ID that was rejected.
additionalProperties:
type: object
title: Rejection Reason
properties:
reason:
type: enum
enum: ['auth_error', 'replaced', 'not_ancestor']
description: |-
The reason for the event being rejected.
required: ['reason']
example: {
"$some_event:domain.com": {
"reason": "auth_error"
}
}
required: ['auth_chain', 'missing', 'rejects']

@ -0,0 +1,139 @@
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Federation Events API"
version: "1.0.0"
host: localhost:8448
schemes:
- https
basePath: /_matrix/federation/v1
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/state/{roomId}":
get:
summary: Get all the state of a given room
description: |-
Retrieves a snapshot of a room's state at a given event.
operationId: getRoomState
security:
- signedRequest: []
parameters:
- in: path
name: roomId
type: string
description: The room ID to get state for.
required: true
x-example: "!abc123:matrix.org"
- in: query
name: event_id
type: string
description: An event ID in the room to retrieve the state at.
required: true
x-example: "$helloworld:matrix.org"
responses:
200:
description: |-
The fully resolved state for the room, including the authorization
chain for the events.
schema:
type: object
properties:
auth_chain:
type: array
description: |-
The full set of authorization events that make up the state
of the room, and their authorization events, recursively.
items:
$ref: "definitions/pdu.yaml"
example: [{"$ref": "examples/pdu.json"}]
pdus:
type: array
description: |-
The fully resolved state of the room at the given event.
items:
$ref: "definitions/pdu.yaml"
example: [{"$ref": "examples/pdu.json"}]
required: ['auth_chain', 'pdus']
"/state_ids/{roomId}":
get:
summary: Get all the state event IDs of a given room
description: |-
Retrieves a snapshot of a room's state at a given event, in the form of
event IDs. This performs the same function as calling ``/state/{roomId}``,
however this returns just the event IDs rather than the full events.
operationId: getRoomStateIds
security:
- signedRequest: []
parameters:
- in: path
name: roomId
type: string
description: The room ID to get state for.
required: true
x-example: "!abc123:matrix.org"
- in: query
name: event_id
type: string
description: An event ID in the room to retrieve the state at.
required: true
x-example: "$helloworld:matrix.org"
responses:
200:
description: |-
The fully resolved state for the room, including the authorization
chain for the events.
schema:
type: object
properties:
auth_chain_ids:
type: array
description: |-
The full set of authorization events that make up the state
of the room, and their authorization events, recursively.
items:
type: string
example: ["$an_event:domain.com"]
pdu_ids:
type: array
description: |-
The fully resolved state of the room at the given event.
items:
type: string
example: ["$an_event:domain.com"]
required: ['auth_chain_ids', 'pdu_ids']
"/event/{eventId}":
get:
summary: Get a single event
description: |-
Retrieves a single event.
operationId: getEvent
security:
- signedRequest: []
parameters:
- in: path
name: eventId
type: string
description: The event ID to get.
required: true
x-example: "$abc123:matrix.org"
responses:
200:
description: A transaction containing a single PDU which is the event requested.
schema:
$ref: "definitions/transaction.yaml"

@ -0,0 +1,6 @@
{
"edu_type": "m.presence",
"content": {
"key": "value"
}
}

@ -0,0 +1,11 @@
{
"$ref": "unsigned_pdu.json",
"hashes": {
"sha256": "thishashcoversallfieldsincasethisisredacted"
},
"signatures": {
"example.com": {
"ed25519:key_version:": "these86bytesofbase64signaturecoveressentialfieldsincludinghashessocancheckredactedpdus"
}
}
}

@ -0,0 +1,23 @@
{
"server_name": "example.org",
"verify_keys": {
"ed25519:abc123": {
"key": "VGhpcyBzaG91bGQgYmUgYSByZWFsIGVkMjU1MTkgcGF5bG9hZA"
}
},
"old_verify_keys": {
"ed25519:0ldk3y": {
"expired_ts": 1532645052628,
"key": "VGhpcyBzaG91bGQgYmUgeW91ciBvbGQga2V5J3MgZWQyNTUxOSBwYXlsb2FkLg"
}
},
"signatures": {
"example.org": {
"ed25519:auto2": "VGhpcyBzaG91bGQgYWN0dWFsbHkgYmUgYSBzaWduYXR1cmU"
}
},
"tls_fingerprints": [{
"sha256": "VGhpcyBpcyBoYXNoIHdoaWNoIHNob3VsZCBiZSBieXRlcw"
}],
"valid_until_ts": 1652262000000
}

@ -0,0 +1,11 @@
{
"$ref": "server_key.json",
"signatures": {
"example.org": {
"ed25519:abc123": "VGhpcyBzaG91bGQgYWN0dWFsbHkgYmUgYSBzaWduYXR1cmU"
},
"notary.server.com": {
"ed25519:010203": "VGhpcyBpcyBhbm90aGVyIHNpZ25hdHVyZQ"
}
}
}

@ -0,0 +1,5 @@
{
"origin": "matrix.org",
"origin_server_ts": 1234567890,
"pdus": [{"$ref": "pdu.json"}]
}

@ -0,0 +1,27 @@
{
"room_id": "!UcYsUzyxTGDxLBEvLy:example.org",
"sender": "@alice:example.com",
"origin": "example.com",
"event_id": "$a4ecee13e2accdadf56c1025:example.com",
"origin_server_ts": 1404838188000,
"depth": 12,
"auth_events": [
[
"$af232176:example.org",
{"sha256": "abase64encodedsha256hashshouldbe43byteslong"}
]
],
"type": "m.room.message",
"prev_events": [
[
"$af232176:example.org",
{"sha256": "abase64encodedsha256hashshouldbe43byteslong"}
]
],
"content": {
"key": "value"
},
"unsigned": {
"age": 4612
}
}

@ -0,0 +1,213 @@
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Federation Invite User To Room API"
version: "1.0.0"
host: localhost:8448
schemes:
- https
basePath: /_matrix/federation/v1
consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/invite/{roomId}/{eventId}":
put:
summary: Invites a remote user to a room
description: |-
Invites a remote user to a room. Once the event has been signed by both the inviting
homeserver and the invited homeserver, it can be sent to all of the servers in the
room by the inviting homeserver.
operationId: sendInvite
security:
- signedRequest: []
parameters:
- in: path
name: roomId
type: string
description: The room ID that the user is being invited to.
required: true
x-example: "!abc123:matrix.org"
- in: path
name: eventId
type: string
description: The event ID for the invite event, generated by the inviting server.
required: true
x-example: "$abc123:example.org"
- in: body
name: body
type: object
required: true
schema:
allOf:
- $ref: "definitions/invite_event.yaml"
- type: object
properties:
unsigned:
type: object
title: Unsigned Event Content
description: |-
Information included alongside the event that is not signed. May include more
than what is listed here.
properties:
invite_room_state:
type: array
description: |-
An optional list of simplified events to help the receiver of the invite
identify the room. The recommended events to include are the join rules,
canonical alias, avatar, and name of the room.
items:
type: object
title: Invite Room State Event
properties:
type:
type: string
description: The type of event.
example: "m.room.join_rules"
state_key:
type: string
description: The state key for the event. May be an empty string.
example: ""
content:
type: object
description: The content for the event.
sender:
type: string
description: The sender of the event.
example: "@someone:matrix.org"
required: ['type', 'state_key', 'content', 'sender']
example: [
{
"type": "m.room.join_rules",
"sender": "@someone:matrix.org",
"state_key": "",
"content": {
"join_rule": "public"
}
}
]
example: {
"$ref": "examples/pdu.json",
"type": "m.room.member",
"state_key": "@joe:elsewhere.com",
"unsigned": {
"invite_room_state": [
{
"type": "m.room.join_rules",
"sender": "@someone:matrix.org",
"state_key": "",
"content": {
"join_rule": "public"
}
},
{
"type": "m.room.name",
"sender": "@someone:matrix.org",
"state_key": "",
"content": {
"name": "Cool New Room"
}
}
]
},
"content": {
"membership": "invite"
},
"signatures": {
"example.com": {
"ed25519:key_version": "SomeSignatureHere"
},
}
}
responses:
200:
description: |-
The event with the invited server's signature added. All other fields of the events
should remain untouched.
schema:
type: array
minItems: 2
maxItems: 2
items:
- type: integer
description: The value ``200``.
example: 200
- type: object
description: An object containing the signed invite event.
title: Event Container
properties:
event:
$ref: "definitions/invite_event.yaml"
required: ['event']
examples:
application/json: [
200,
{
"event": {
"$ref": "examples/pdu.json",
"type": "m.room.member",
"state_key": "@someone:example.org",
"unsigned": {
"invite_room_state": [
{
"type": "m.room.join_rules",
"sender": "@someone:matrix.org",
"state_key": "",
"content": {
"join_rule": "public"
}
},
{
"type": "m.room.name",
"sender": "@someone:matrix.org",
"state_key": "",
"content": {
"name": "Cool New Room"
}
}
]
},
"content": {
"membership": "invite"
},
"signatures": {
"example.com": {
"ed25519:key_version": "SomeSignatureHere"
},
"elsewhere.com": {
"ed25519:k3y_versi0n": "SomeOtherSignatureHere"
}
}
}
}
]
403:
description: |-
The invite is not allowed. This could be for a number of reasons, including:
* The sender is not allowed to send invites to the target user/homeserver.
* The homeserver does not permit anyone to invite its users.
* The homeserver refuses to participate in the room.
schema:
$ref: "../client-server/definitions/errors/error.yaml"
examples:
application/json: {
"errcode": "M_FORBIDDEN",
"error": "User cannot invite the target user."
}

@ -0,0 +1,293 @@
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Federation Join Room API"
version: "1.0.0"
host: localhost:8448
schemes:
- https
basePath: /_matrix/federation/v1
consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/make_join/{roomId}/{userId}":
get:
summary: Get information required to make a join event for a room
description: |-
Asks the receiving server to return information that the sending
server will need to prepare a join event to get into the room.
operationId: makeJoin
security:
- signedRequest: []
parameters:
- in: path
name: roomId
type: string
description: The room ID that is about to be joined.
required: true
x-example: "!abc123:matrix.org"
- in: path
name: userId
type: string
description: The user ID the join event will be for.
required: true
x-example: "@someone:example.org"
responses:
200:
description: |-
An unsigned event that the server may now use as a template
for the rest of the `Joining Rooms`_ handshake.
schema:
allOf:
- $ref: "definitions/unsigned_pdu.yaml"
- type: object
properties:
# Note: we override a bunch of parameters to change their descriptions
sender:
type: string
description: The user ID of the joining member.
example: "@someone:example.org"
origin:
type: string
description: The name of the resident homeserver.
example: "matrix.org"
origin_server_ts:
type: integer
format: int64
description: A timestamp added by the resident homeserver.
example: 1234567890
type:
type: string
description: The value ``m.room.member``.
example: "m.room.member"
state_key:
type: string
description: The user ID of the joining member.
example: "@someone:example.org"
content:
type: object
title: Membership Event Content
description: The content of the event.
example: {"membership": "join"}
properties:
membership:
type: string
description: The value ``join``.
example: "join"
required: ['membership']
depth:
type: integer
description: This field must be present but is ignored; it may be 0.
example: 12
auth_events:
type: array
description: |-
An event reference list containing the authorization events that would
allow the member to join the room. This should normally be the
``m.room.create``, ``m.room.power_levels``, and ``m.room.join_rules``
events.
items:
type: array
maxItems: 2
minItems: 2
items:
- type: string
title: Event ID
example: "$abc123:matrix.org"
- type: object
title: Event Hash
example: {
"sha256": "abase64encodedsha256hashshouldbe43byteslong"
}
properties:
sha256:
type: string
description: The event hash.
example: abase64encodedsha256hashshouldbe43byteslong
required: ['sha256']
redacts:
type: string
description: Not used.
required:
# Every other field is already flagged as required by the $ref
- state_key
examples:
application/json: {
"$ref": "examples/unsigned_pdu.json",
"type": "m.room.member",
"state_key": "@someone:example.org",
"content": {
"membership": "join"
},
"auth_events": [
["$room_cre4te_3vent:matrix.org", {"sha256": "abase64encodedsha256hashshouldbe43byteslong"}],
["$room_j0in_rul3s_3vent:matrix.org", {"sha256": "abase64encodedsha256hashshouldbe43byteslong"}],
["$room_p0wer_l3vels_3vent:matrix.org", {"sha256": "abase64encodedsha256hashshouldbe43byteslong"}]
]
}
"/send_join/{roomId}/{eventId}":
put:
summary: Submit a signed join event to a resident server
description: |-
Submits a signed join event to the resident server for it
to accept it into the room's graph.
operationId: sendJoin
security:
- signedRequest: []
parameters:
- in: path
name: roomId
type: string
description: The room ID that is about to be joined.
required: true
x-example: "!abc123:matrix.org"
- in: path
name: eventId
type: string
description: The event ID for the join event.
required: true
x-example: "$abc123:example.org"
- in: body
name: body
type: object
required: true
schema:
allOf:
- $ref: "definitions/pdu.yaml"
- type: object
properties:
# Note: we override a bunch of parameters to change their descriptions
sender:
type: string
description: The user ID of the joining member.
example: "@someone:example.org"
origin:
type: string
description: The name of the joining homeserver.
example: "matrix.org"
origin_server_ts:
type: integer
format: int64
description: A timestamp added by the joining homeserver.
example: 1234567890
type:
type: string
description: The value ``m.room.member``.
example: "m.room.member"
state_key:
type: string
description: The user ID of the joining member.
example: "@someone:example.org"
content:
type: object
title: Membership Event Content
description: The content of the event.
example: {"membership": "join"}
properties:
membership:
type: string
description: The value ``join``.
example: "join"
required: ['membership']
depth:
type: integer
description: This field must be present but is ignored; it may be 0.
example: 12
auth_events:
type: array
description: |-
An event reference list containing the authorization events that would
allow the member to join the room.
items:
type: array
maxItems: 2
minItems: 2
items:
- type: string
title: Event ID
example: "$abc123:matrix.org"
- type: object
title: Event Hash
example: {
"sha256": "abase64encodedsha256hashshouldbe43byteslong"
}
properties:
sha256:
type: string
description: The event hash.
example: abase64encodedsha256hashshouldbe43byteslong
required: ['sha256']
redacts:
type: string
description: Not used.
required:
# Every other field is already flagged as required by the $ref
- state_key
example: {
"$ref": "examples/pdu.json",
"type": "m.room.member",
"state_key": "@someone:example.org",
"content": {
"membership": "join"
}
}
responses:
200:
description: |-
The full state for the room, having accepted the join event.
schema:
type: array
minItems: 2
maxItems: 2
items:
- type: integer
description: The value ``200``.
example: 200
- type: object
title: Room State
description: The state for the room.
properties:
origin:
type: string
description: The resident server's DNS name.
auth_chain:
type: array
description: The auth chain.
items:
type: object
schema:
$ref: "definitions/pdu.yaml"
state:
type: array
description: The room state.
items:
type: object
schema:
$ref: "definitions/pdu.yaml"
required: ["auth_chain", "state", "origin"]
examples:
application/json: [
200,
{
"origin": "matrix.org",
"auth_chain": [{"$ref": "examples/pdu.json"}],
"state": [{"$ref": "examples/pdu.json"}]
}
]

@ -0,0 +1,131 @@
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Federation Key Exchange API"
version: "1.0.0"
host: localhost:8448
schemes:
- https
basePath: /_matrix/key/v2
consumes:
- application/json
produces:
- application/json
paths:
"/query/{serverName}/{keyId}":
get:
summary: Query for another server's keys
description: |-
Query for another server's keys. The receiving (notary) server must
sign the keys returned by the queried server.
operationId: perspectivesKeyQuery
parameters:
- in: path
name: serverName
type: string
description: The server's DNS name to query
required: true
x-example: matrix.org
- in: path
name: keyId
type: string
description: |-
**Deprecated**. Servers should not use this parameter and instead
opt to return all keys, not just the requested one. The key ID to
look up.
required: false
x-example: "ed25519:abc123"
- in: query
name: minimum_valid_until_ts
type: integer
format: int64
description: |-
A millisecond POSIX timestamp in milliseconds indicating when the returned
certificates will need to be valid until to be useful to the requesting server.
If not supplied, the current time as determined by the notary server is used.
required: false
x-example: 1234567890
responses:
200:
description: |-
The keys for the server, or an empty array if the server could not be reached
and no cached keys were available.
schema:
$ref: "definitions/keys_query_response.yaml"
"/query":
post:
summary: Query for several server's keys
description: |-
Query for keys from multiple servers in a batch format. The receiving (notary)
server must sign the keys returned by the queried servers.
operationId: bulkPerspectivesKeyQuery
parameters:
- in: body
name: body
schema:
type: object
example: {
"server_keys": {
"example.org": {
"ed25519:abc123": {
"minimum_valid_until_ts": 1234567890
}
}
}
}
properties:
server_keys:
type: object
description: |-
The query criteria. The outer ``string`` key on the object is the
server name (eg: ``matrix.org``). The inner ``string`` key is the
Key ID to query for the particular server. If no key IDs are given
to be queried, the notary server should query for all keys. If no
servers are given, the notary server must return an empty ``server_keys``
array in the response.
The notary server may return multiple keys regardless of the Key IDs
given.
additionalProperties:
type: object
name: ServerName
description: The server names to query.
additionalProperties:
type: object
title: Query Criteria
description: The server key IDs to query.
properties:
minimum_valid_until_ts:
type: integer
format: int64
description: |-
A millisecond POSIX timestamp in milliseconds indicating when
the returned certificates will need to be valid until to be
useful to the requesting server.
If not supplied, the current time as determined by the notary
server is used.
example: 1234567890
required: ['server_keys']
responses:
200:
description: |-
The keys for the queried servers, signed by the notary server. Servers which
are offline and have no cached keys will not be included in the result. This
may result in an empty array.
schema:
$ref: "definitions/keys_query_response.yaml"

@ -0,0 +1,61 @@
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Federation Key Exchange API"
version: "1.0.0"
host: localhost:8448
schemes:
- https
basePath: /_matrix/key/v2
produces:
- application/json
paths:
"/server/{keyId}":
get:
summary: Get the homeserver's public key(s)
description: |-
Gets the homeserver's published TLS fingerprints and signing keys.
The homeserver may have any number of active keys and may have a
number of old keys.
Intermediate notary servers should cache a response for half of its
lifetime to avoid serving a stale response. Originating servers should
avoid returning responses that expire in less than an hour to avoid
repeated reqests for a certificate that is about to expire. Requesting
servers should limit how frequently they query for certificates to
avoid flooding a server with requests.
If the server fails to respond to this request, intermediate notary
servers should continue to return the last response they received
from the server so that the signatures of old events can still be
checked.
operationId: getServerKey
parameters:
- in: path
name: keyId
type: string
description: |-
**Deprecated**. Servers should not use this parameter and instead
opt to return all keys, not just the requested one. The key ID to
look up.
required: false
x-example: "ed25519:abc123"
deprecated: true
responses:
200:
description: The homeserver's keys
schema:
$ref: "definitions/keys.yaml"

@ -0,0 +1,274 @@
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Federation Leave Room API"
version: "1.0.0"
host: localhost:8448
schemes:
- https
basePath: /_matrix/federation/v1
consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/make_leave/{roomId}/{userId}":
get:
summary: Get information required to make a leave event for a room
description: |-
Asks the receiving server to return information that the sending
server will need to prepare a leave event to get out of the room.
operationId: makeLeave
security:
- signedRequest: []
parameters:
- in: path
name: roomId
type: string
description: The room ID that is about to be left.
required: true
x-example: "!abc123:matrix.org"
- in: path
name: userId
type: string
description: The user ID the leave event will be for.
required: true
x-example: "@someone:example.org"
responses:
200:
description: |-
An unsigned event that the sending server may use as a template
for when it calls ``/send_leave``.
schema:
allOf:
- $ref: "definitions/unsigned_pdu.yaml"
- type: object
properties:
# Note: we override a bunch of parameters to change their descriptions
sender:
type: string
description: The user ID of the leaving member.
example: "@someone:example.org"
origin:
type: string
description: The name of the resident homeserver.
example: "matrix.org"
origin_server_ts:
type: integer
format: int64
description: A timestamp added by the resident homeserver.
example: 1234567890
type:
type: string
description: The value ``m.room.member``.
example: "m.room.member"
state_key:
type: string
description: The user ID of the leaving member.
example: "@someone:example.org"
content:
type: object
title: Membership Event Content
description: The content of the event.
example: {"membership": "leave"}
properties:
membership:
type: string
description: The value ``leave``.
example: "leave"
required: ['membership']
auth_events:
type: array
description: |-
An event reference list containing the authorization events that would
allow the member to leave the room. This should normally be the
``m.room.create``, ``m.room.power_levels``, and ``m.room.join_rules``
events.
items:
type: array
maxItems: 2
minItems: 2
items:
- type: string
title: Event ID
example: "$abc123:matrix.org"
- type: object
title: Event Hash
example: {
"sha256": "abase64encodedsha256hashshouldbe43byteslong"
}
properties:
sha256:
type: string
description: The event hash.
example: abase64encodedsha256hashshouldbe43byteslong
required: ['sha256']
redacts:
type: string
description: Not used.
required:
# Every other field is already flagged as required by the $ref
- state_key
examples:
application/json: {
"$ref": "examples/unsigned_pdu.json",
"type": "m.room.member",
"state_key": "@someone:example.org",
"content": {
"membership": "leave"
},
"auth_events": [
["$room_cre4te_3vent:matrix.org", {"sha256": "abase64encodedsha256hashshouldbe43byteslong"}],
["$room_j0in_rul3s_3vent:matrix.org", {"sha256": "abase64encodedsha256hashshouldbe43byteslong"}],
["$room_p0wer_l3vels_3vent:matrix.org", {"sha256": "abase64encodedsha256hashshouldbe43byteslong"}]
]
}
403:
description: |-
The request is not authorized. This could mean that the user is not in the room.
schema:
$ref: "../client-server/definitions/errors/error.yaml"
examples:
application/json: {
"errcode": "M_FORBIDDEN",
"error": "User is not in the room."
}
"/send_leave/{roomId}/{eventId}":
put:
summary: Submit a signed leave event to a resident server
description: |-
Submits a signed leave event to the resident server for it
to accept it into the room's graph.
operationId: sendLeave
security:
- signedRequest: []
parameters:
- in: path
name: roomId
type: string
description: The room ID that is about to be left.
required: true
x-example: "!abc123:matrix.org"
- in: path
name: eventId
type: string
description: The event ID for the leave event.
required: true
x-example: "$abc123:example.org"
- in: body
name: body
type: object
required: true
schema:
allOf:
- $ref: "definitions/pdu.yaml"
- type: object
properties:
# Note: we override a bunch of parameters to change their descriptions
sender:
type: string
description: The user ID of the leaving member.
example: "@someone:example.org"
origin:
type: string
description: The name of the leaving homeserver.
example: "matrix.org"
origin_server_ts:
type: integer
format: int64
description: A timestamp added by the leaving homeserver.
example: 1234567890
type:
type: string
description: The value ``m.room.member``.
example: "m.room.member"
state_key:
type: string
description: The user ID of the leaving member.
example: "@someone:example.org"
content:
type: object
title: Membership Event Content
description: The content of the event.
example: {"membership": "leave"}
properties:
membership:
type: string
description: The value ``leave``.
example: "leave"
required: ['membership']
depth:
type: integer
description: This field must be present but is ignored; it may be 0.
example: 12
auth_events:
type: array
description: |-
An event reference list containing the authorization events that would
allow the member to leave the room.
items:
type: array
maxItems: 2
minItems: 2
items:
- type: string
title: Event ID
example: "$abc123:matrix.org"
- type: object
title: Event Hash
example: {
"sha256": "abase64encodedsha256hashshouldbe43byteslong"
}
properties:
sha256:
type: string
description: The event hash.
example: abase64encodedsha256hashshouldbe43byteslong
required: ['sha256']
redacts:
type: string
description: Not used.
required:
# Every other field is already flagged as required by the $ref
- state_key
example: {
"$ref": "examples/pdu.json",
"type": "m.room.member",
"state_key": "@someone:example.org",
"content": {
"membership": "leave"
}
}
responses:
200:
description: |-
An empty response to indicate the event was accepted into the graph by
the receiving homeserver.
schema:
type: array
minItems: 2
maxItems: 2
items:
- type: integer
description: The value ``200``.
example: 200
- type: object
title: Empty Object
description: An empty object.
examples:
application/json: [200, {}]

@ -0,0 +1,63 @@
# Copyright 2017 Kamax.io
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Federation OpenID API"
version: "1.0.0"
host: localhost:8448
schemes:
- https
basePath: /_matrix/federation/v1
produces:
- application/json
paths:
"/openid/userinfo":
get:
summary: Exchange an OpenID token for user information
description: |-
Exchanges an OpenID access token for information about the user
who generated the token. Currently this only exposes the Matrix
User ID of the owner.
operationId: exchangeOpenIdToken
parameters:
- in: path
name: access_token
type: string
description: |-
The OpenID access token to get information about the owner for.
required: true
x-example: SomeT0kenHere
responses:
200:
description: |-
Information about the user who generated the OpenID access token.
schema:
type: object
properties:
sub:
type: string
description: The Matrix User ID who generated the token.
example: "@alice:example.com"
required: ['sub']
401:
description: The token was not recognized or has expired.
schema:
$ref: "../client-server/definitions/errors/error.yaml"
examples:
application/json: {
"errcode": "M_UNKNOWN_TOKEN",
"error": "Access token unknown or expired"
}

@ -0,0 +1,56 @@
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Federation Public Rooms API"
version: "1.0.0"
host: localhost:8448
schemes:
- https
basePath: /_matrix/federation/v1
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/publicRooms":
get:
summary: Get all the public rooms for a homeserver
description: |-
Gets all the public rooms for the homeserver. This should not return
rooms that are listed on another homeserver's directory, just those
listed on the receiving homeserver's directory.
operationId: getPublicRooms
security:
- signedRequest: []
parameters:
- in: query
name: limit
type: integer
description: |-
The maximum number of rooms to return. Defaults to 0 (no limit).
x-example: 10
- in: query
name: since
type: string
description: |-
A pagination token from a previous call to this endpoint to fetch more
rooms.
x-example: "GetMoreRoomsTokenHere"
responses:
200:
description: The public room list for the homeserver.
schema:
$ref: "../client-server/definitions/public_rooms_response.yaml"

@ -0,0 +1,175 @@
# Copyright 2017 Kamax.io
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Federation Query API"
version: "1.0.0"
host: localhost:8448
schemes:
- https
basePath: /_matrix/federation/v1
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/query/{queryType}":
get:
summary: Query for information
description: |-
Performs a single query request on the receiving homeserver. The query string
arguments are dependent on which type of query is being made. Known query types
are specified as their own endpoints as an extension to this definition.
operationId: queryInfo
security:
- signedRequest: []
parameters:
- in: path
name: queryType
type: string
description: The type of query to make
required: true
x-example: profile
responses:
200:
description: |-
The query response. The schema varies depending on the query being made.
"/query/directory":
get:
summary: Query for the room ID and resident homeservers for a room alias
description: |-
Performs a query to get the mapped room ID and list of resident homeservers in
the room for a given room alias. Homeservers should only query room aliases
that belong to the target server (identified by the DNS Name in the alias).
Servers may wish to cache the response to this query to avoid requesting the
information too often.
operationId: queryRoomDirectory
security:
- signedRequest: []
parameters:
- in: query
name: room_alias
type: string
description: The room alias to query.
required: true
x-example: "#room_alias:example.org"
responses:
200:
description: |-
The corresponding room ID and list of known resident homeservers for the room.
schema:
type: object
properties:
room_id:
type: string
description: The room ID mapped to the queried room alias.
x-example: "!roomid1234:example.org"
servers:
type: array
description: |-
An array of server names that are likely to hold the given room. This
list may or may not include the server answering the query.
items:
type: string
required:
- "room_id"
- "servers"
examples:
application/json: {
"room_id": "!roomid1234:example.org",
"servers": [
"example.org",
"example.com",
"another.example.com:8449",
]
}
404:
description: The room alias was not found.
schema:
$ref: "../client-server/definitions/errors/error.yaml"
examples:
application/json: {
"errcode": "M_NOT_FOUND",
"error": "Room alias not found."
}
"/query/profile":
get:
summary: Query for profile information about a given user
description: |-
Performs a query to get profile information, such as a display name or avatar,
for a given user. Homeservers should only query profiles for users that belong
to the target server (identified by the DNS Name in the user ID).
Servers may wish to cache the response to this query to avoid requesting the
information too often.
operationId: queryProfile
security:
- signedRequest: []
parameters:
- in: query
name: user_id
type: string
description: The user ID to query.
required: true
x-example: "@someone:example.org"
- in: query
name: field
type: enum
enum: ['displayname', 'avatar_url']
description: |-
The field to query. If specified, the server will only return the given field
in the response. If not specified, the server will return the full profile for
the user.
responses:
200:
description: |-
The profile for the user. If a ``field`` is specified in the request, only the
matching field should be included in the response. If no ``field`` was specified,
the response should include the fields of the user's profile that can be made
public, such as the display name and avatar.
If the user does not have a particular field set on their profile, the server
should exclude it from the response body or give it the value ``null``.
schema:
type: object
properties:
displayname:
type: string
description: |-
The display name of the user. May be omitted if the user does not have a
display name set.
x-example: "John Doe"
avatar_url:
type: string
description: |-
The avatar URL for the user's avatar. May be omitted if the user does not
have an avatar set.
x-example: "mxc://matrix.org/MyC00lAvatar"
examples:
application/json: {
"displayname": "John Doe",
"avatar_url": "mxc://matrix.org/MyC00lAvatar"
}
404:
description: The user does not exist or does not have a profile.
schema:
$ref: "../client-server/definitions/errors/error.yaml"
examples:
application/json: {
"errcode": "M_NOT_FOUND",
"error": "User does not exist."
}

@ -0,0 +1,196 @@
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Federation Third Party Invites API"
version: "1.0.0"
host: localhost:8448
schemes:
- https
basePath: /_matrix/federation/v1
consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/exchange_third_party_invite/{roomId}":
put:
summary: Request a server to auth a third party invite event
description: |-
The receiving server will verify the partial ``m.room.member`` event
given in the request body. If valid, the receiving server will issue
an invite as per the `Inviting to a room`_ section before returning a
response to this request.
operationId: exchangeThirdPartyInvite
security:
- signedRequest: []
parameters:
- in: path
name: roomId
type: string
description: The room ID to exchange a third party invite in
required: true
x-example: "!abc123:matrix.org"
- in: body
name: body
type: object
description: A partial ``m.room.member`` event
required: true
schema:
type: object
properties:
type:
type: string
description: The event type. Must be ``m.room.member``
example: "m.room.member"
room_id:
type: string
description: |-
The room ID the event is for. Must match the ID given in
the path.
example: "!abc123:matrix.org"
sender:
type: string
description: |-
The user ID of the user who sent the original ``m.room.third_party_invite``
event.
example: "@joe:matrix.org"
state_key:
type: string
description: The user ID of the invited user
example: "@someone:example.org"
content:
type: object
description: The event content
title: Event Content
properties:
membership:
type: string
description: The membership state. Must be ``invite``
example: invite
third_party_invite:
type: object
description: The third party invite
properties:
display_name:
type: string
description: |-
A name which can be displayed to represent the user instead of their
third party identifier.
example: "alice"
signed:
type: object
description: |-
A block of content which has been signed, which servers can use to
verify the event.
properties:
signatures:
type: object
description: The server signatures for this event.
additionalProperties:
type: object
title: Server Signatures
additionalProperties:
type: string
example: {
"magic.forest": {
"ed25519:3": "fQpGIW1Snz+pwLZu6sTy2aHy/DYWWTspTJRPyNp0PKkymfIsNffysMl6ObMMFdIJhk6g6pwlIqZ54rxo8SLmAg"
}
}
mxid:
type: string
description: The invited matrix user ID
example: "@alice:localhost"
token:
type: string
description: The token used to verify the event
example: abc123
required: ['signatures', 'mxid', 'token']
example: {
"mxid": "@alice:localhost",
"token": "abc123",
"signatures": {
"magic.forest": {
"ed25519:3": "fQpGIW1Snz+pwLZu6sTy2aHy/DYWWTspTJRPyNp0PKkymfIsNffysMl6ObMMFdIJhk6g6pwlIqZ54rxo8SLmAg"
}
}
}
required: ['display_name', 'signed']
example: {
"display_name": "alice",
"signed": {
"mxid": "@alice:localhost",
"token": "abc123",
"signatures": {
"magic.forest": {
"ed25519:3": "fQpGIW1Snz+pwLZu6sTy2aHy/DYWWTspTJRPyNp0PKkymfIsNffysMl6ObMMFdIJhk6g6pwlIqZ54rxo8SLmAg"
}
}
}
}
required: ['membership', 'third_party_invite']
example: {
"membership": "invite",
"third_party_invite": {
"display_name": "alice",
"signed": {
"mxid": "@alice:localhost",
"token": "abc123",
"signatures": {
"magic.forest": {
"ed25519:3": "fQpGIW1Snz+pwLZu6sTy2aHy/DYWWTspTJRPyNp0PKkymfIsNffysMl6ObMMFdIJhk6g6pwlIqZ54rxo8SLmAg"
}
}
}
}
}
required:
- type
- room_id
- sender
- state_key
- content
example: {
"type": "m.room.member",
"room_id": "!abc123:matrix.org",
"sender": "@joe:matrix.org",
"state_key": "@someone:example.org",
"content": {
"membership": "invite",
"third_party_invite": {
"display_name": "alice",
"signed": {
"mxid": "@alice:localhost",
"token": "abc123",
"signatures": {
"magic.forest": {
"ed25519:3": "fQpGIW1Snz+pwLZu6sTy2aHy/DYWWTspTJRPyNp0PKkymfIsNffysMl6ObMMFdIJhk6g6pwlIqZ54rxo8SLmAg"
}
}
}
}
}
}
responses:
200:
description: The invite has been issued successfully.
examples:
application/json: {}
schema:
type: object
description: An empty object
example: {}

@ -0,0 +1,116 @@
# Copyright 2018 New Vector Ltd
#
# 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.
swagger: '2.0'
info:
title: "Matrix Federation Transaction API"
version: "1.0.0"
host: localhost:8448
schemes:
- https
basePath: /_matrix/federation/v1
consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/send/{txnId}":
put:
summary: Send a transaction
description: |-
Push messages representing live activity to another server. The destination name
will be set to that of the receiving server itself. Each embedded PDU in the
transaction body will be processed.
The sending server must wait and retry for a 200 OK response before sending a
transaction with a different ``txnId`` to the receiving server.
operationId: sendTransaction
security:
- signedRequest: []
parameters:
- in: path
name: txnId
type: string
description: |-
The transaction ID.
required: true
x-example: S0meTransacti0nId
- in: body
name: body
type: object
required: true
schema:
allOf:
- $ref: "definitions/transaction.yaml"
- type: object
properties:
edus:
type: array
description: |-
List of ephemeral messages. May be omitted if there are no ephemeral
messages to be sent.
items:
$ref: "definitions/edu.yaml"
example: {
"$ref": "examples/transaction.json",
"edus": [{"$ref": "edu.json"}] # Relative to the examples directory
}
responses:
200:
description: |-
The result of processing the transaction. The server is to use this response even in
the event of one or more PDUs failing to be processed.
schema:
type: array
minItems: 2
maxItems: 2
items:
- type: integer
description: The value ``200``.
example: 200
- type: object
title: PDU Processing Results
description: The results for the processing of each PDU in the transaction.
properties:
pdus:
type: object
description: |-
The PDUs from the original transaction. The string key represents the ID of the
PDU (event) that was processed.
additionalProperties:
type: object
title: PDU Processing Result
description: Information about how the PDU was handled.
properties:
error:
type: string
description: |-
A human readable description about what went wrong in processing this PDU.
If no error is present, the PDU can be considered successfully handled.
example: "You are not allowed to send a message to this room."
required: ['pdus']
examples:
application/json: [
200,
{
"pdus": {
"$successful_event:domain.com": {},
"$failed_event:example.org": {
"error": "You are not allowed to send a message to this room."
}
}
}
]

@ -0,0 +1,55 @@
<!-- Note: This is a markdown file so the build script's RST processing doesn't grab it -->
# Changelogs
[Towncrier](https://github.com/hawkowl/towncrier) is used to manage the changelog and
keep it up to date. Because of this, updating a changelog is really easy.
## How to update a changelog when releasing an API
1. Ensure you're in your Python 3 virtual environment
2. `cd` your way to the API you're releasing (eg: `cd changelogs/client_server`)
3. Run `towncrier --version "r0.4.0" --name "client-server" --yes` substituting the
variables as approprite. Note that `--name` is required although the value is ignored.
4. Commit the changes and finish the release process.
## How to prepare a changelog for a new API
For this example, we're going to pretend that the `server_server` API doesn't exist.
1. Create the file `changelogs/server_server.rst`
2. Create the folder `changelogs/server_server`
3. In the new folder, create a `pyproject.toml` file with these contents:
```toml
[tool.towncrier]
filename = "../server_server.rst"
directory = "newsfragments"
issue_format = "`#{issue} <https://github.com/matrix-org/matrix-doc/issues/{issue}>`_"
title_format = "{version}"
[[tool.towncrier.type]]
directory = "breaking"
name = "Breaking Changes"
showcontent = true
[[tool.towncrier.type]]
directory = "deprecation"
name = "Deprecations"
showcontent = true
[[tool.towncrier.type]]
directory = "new"
name = "New Endpoints"
showcontent = true
[[tool.towncrier.type]]
directory = "feature"
name = "Backwards Compatible Changes"
showcontent = true
[[tool.towncrier.type]]
directory = "clarification"
name = "Spec Clarifications"
showcontent = true
```
4. Create a `.gitignore` in `changelogs/server_server/newsfragments` with the contents `!.gitignore`

@ -1,62 +1,3 @@
Unreleased changes
==================
- Changes to the API which will be backwards-compatible for clients:
- New endpoints:
- ``POST /user_directory/search``
(`#1096 <https://github.com/matrix-org/matrix-doc/pull/1096>`_).
- ``GET /rooms/{roomId}/event/{eventId}``
(`#1110 <https://github.com/matrix-org/matrix-doc/pull/1110>`_).
- ``POST /delete_devices``
(`#1239 <https://github.com/matrix-org/matrix-doc/pull/1239>`_).
- Sticker messages:
- Add sticker message event definition.
(`#1158 <https://github.com/matrix-org/matrix-doc/pull/1158>`_).
- Spec clarifications:
- Update ``ImageInfo`` and ``ThumbnailInfo`` dimension schema descriptions
to clarify that they relate to intended display size, as opposed to the
intrinsic size of the image file.
(`#1158 <https://github.com/matrix-org/matrix-doc/pull/1158>`_).
- Mark ``home_server`` return field for ``/login`` and ``/register``
endpoints as deprecated
(`#1097 <https://github.com/matrix-org/matrix-doc/pull/1097>`_).
- Fix response format of ``/keys/changes`` endpoint
(`#1106 <https://github.com/matrix-org/matrix-doc/pull/1106>`_).
- Clarify default values for some fields on the /search API
(`#1109 <https://github.com/matrix-org/matrix-doc/pull/1109>`_).
- Fix the representation of ``m.presence`` events
(`#1137 <https://github.com/matrix-org/matrix-doc/pull/1137>`_).
- Clarify that ``m.tag`` ordering is done with numbers, not strings
(`#1139 <https://github.com/matrix-org/matrix-doc/pull/1139>`_).
- Clarify that ``/account/whoami`` should consider application services
(`#1152 <https://github.com/matrix-org/matrix-doc/pull/1152>`_).
- Mark ``GET /rooms/{roomId}/members`` as requiring authentication
(`#1245 <https://github.com/matrix-org/matrix-doc/pull/1244>`_).
- Changes to the API which will be backwards-compatible for clients:
- Add 'token' parameter to /keys/query endpoint
(`#1104 <https://github.com/matrix-org/matrix-doc/pull/1104>`_).
- Add the room visibility options for the room directory
(`#1141 <https://github.com/matrix-org/matrix-doc/pull/1141>`_).
- Add spec for ignoring users
(`#1142 <https://github.com/matrix-org/matrix-doc/pull/1142>`_).
- Add the ``/register/available`` endpoint for username availability
(`#1151 <https://github.com/matrix-org/matrix-doc/pull/1151>`_).
- Add ``allow_remote`` to the content repo to avoid routing loops
(`#1265 <https://github.com/matrix-org/matrix-doc/pull/1265>`_).
- Add report content API
(`#1264 <https://github.com/matrix-org/matrix-doc/pull/1264>`_).
- Document ``/logout/all`` endpoint
(`#1263 <https://github.com/matrix-org/matrix-doc/pull/1263>`_).
- Document `highlights` field in /search response
(`#1274 <https://github.com/matrix-org/matrix-doc/pull/1274>`_).
r0.3.0
======

@ -0,0 +1 @@
``POST /user_directory/search``

@ -0,0 +1 @@
Mark ``home_server`` return field for ``/login`` and ``/register`` endpoints as deprecated

@ -0,0 +1 @@
Add ``token`` parameter to the ``/keys/query`` endpoint

@ -0,0 +1 @@
Fix response format of ``/keys/changes`` endpoint

@ -0,0 +1 @@
Clarify default values for some fields on the ``/search`` API

@ -0,0 +1 @@
``GET /rooms/{roomId}/event/{eventId}``

@ -0,0 +1 @@
Fix the representation of ``m.presence`` events

@ -0,0 +1 @@
Clarify that ``m.tag`` ordering is done with numbers, not strings

@ -0,0 +1 @@
Add the room visibility options for the room directory

@ -0,0 +1 @@
Add the ``/register/available`` endpoint for username availability

@ -0,0 +1 @@
Clarify that ``/account/whoami`` should consider application services

@ -0,0 +1,3 @@
Update ``ImageInfo`` and ``ThumbnailInfo`` dimension schema descriptions
to clarify that they relate to intended display size, as opposed to the
intrinsic size of the image file.

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

Loading…
Cancel
Save