Merge branch 'master' of github.com:matrix-org/matrix-doc into erikj/search_yet_agian

pull/169/head
Erik Johnston 9 years ago
commit 46fd0b252c

@ -0,0 +1,105 @@
swagger: '2.0'
info:
title: "Matrix Client-Server Client Config API"
version: "1.0.0"
host: localhost:8008
schemes:
- https
- http
basePath: /_matrix/client/v2_alpha
consumes:
- application/json
produces:
- application/json
securityDefinitions:
accessToken:
type: apiKey
description: The user_id or application service access_token
name: access_token
in: query
paths:
"/user/{userId}/account_data/{type}":
put:
summary: Set some account_data for the user.
description: |-
Set some account_data for the client. This config is only visible to the user
that set the account_data. The config will be synced to clients in the
top-level ``account_data``.
security:
- accessToken: []
parameters:
- in: path
type: string
name: userId
required: true
description: |-
The id of the user to set account_data for. The access token must be
authorized to make requests for this user id.
x-example: "@alice:example.com"
- in: path
type: string
name: type
required: true
description: |-
The event type of the account_data to set. Custom types should be
namespaced to avoid clashes.
x-example: "org.example.custom.config"
- in: body
name: content
required: true
description: |-
The content of the account_data
schema:
type: object
example: |-
{"custom_account_data_key": "custom_config_value"}
responses:
200:
description:
The account_data was successfully added.
"/user/{userId}/rooms/{roomId}/account_data/{type}":
put:
summary: Set some account_data for the user.
description: |-
Set some account_data for the client on a given room. This config is only
visible to the user that set the account_data. The config will be synced to
clients in the per-room ``account_data``.
security:
- accessToken: []
parameters:
- in: path
type: string
name: userId
required: true
description: |-
The id of the user to set account_data for. The access token must be
authorized to make requests for this user id.
x-example: "@alice:example.com"
- in: path
type: string
name: roomId
required: true
description: |-
The id of the room to set account_data on.
x-example: "!726s6s6q:example.com"
- in: path
type: string
name: type
required: true
description: |-
The event type of the account_data to set. Custom types should be
namespaced to avoid clashes.
x-example: "org.example.custom.room.config"
- in: body
name: content
required: true
description: |-
The content of the account_data
schema:
type: object
example: |-
{"custom_account_data_key": "custom_account_data_value"}
responses:
200:
description:
The account_data was successfully added.

@ -0,0 +1,157 @@
swagger: '2.0'
info:
title: "Matrix Client-Server v1 Account Administrative Contact API"
version: "1.0.0"
host: localhost:8008
schemes:
- https
- http
basePath: /_matrix/client/v2_alpha
consumes:
- application/json
produces:
- application/json
securityDefinitions:
accessToken:
type: apiKey
description: The user_id or application service access_token
name: access_token
in: query
paths:
"/account/password":
post:
summary: Changes a user's password.
description: |-
This API endpoint uses the User-Interactive Authentication API.
An access token should be submitted to this endpoint if the client has
an active session.
The Home Server may change the flows available depending on whether a
valid access token is provided.
security:
- accessToken: []
parameters:
- in: body
name: body
schema:
type: object
example: |-
{
"new_password": "ihatebananas"
}
properties:
new_password:
type: string
description: The new password for the account.
required: ["new_password"]
responses:
200:
description: The password has been changed.
examples:
application/json: "{}"
schema:
type: object
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"/account/3pid":
get:
summary: Gets a list of a user's third party identifiers.
description: |-
Gets a list of the third party identifiers that the homeserver has
associated with the user's account.
This is *not* the same as the list of third party identifiers bound to
the user's Matrix ID in Identity Servers.
Identifiers in this list may be used by the Home Server as, for example,
identifiers that it will accept to reset the user's account password.
security:
- accessToken: []
responses:
200:
description: The lookup was successful.
examples:
application/json: |-
{
"threepids": [
{
"medium": "email",
"address": "monkey@banana.island"
}
]
}
schema:
type: object
properties:
threepids:
type: array
items:
type: object
title: Third party identifier
properties:
medium:
type: string
description: The medium of the third party identifier.
enum: ["email"]
address:
type: string
description: The third party identifier address.
post:
summary: Adds contact information to the user's account.
description: Adds contact information to the user's account.
security:
- accessToken: []
parameters:
- in: body
name: body
schema:
type: object
properties:
threePidCreds:
title: "ThreePidCredentials"
type: object
description: The third party credentials to associate with the account.
properties:
client_secret:
type: string
description: The client secret used in the session with the Identity Server.
id_server:
type: string
description: The Identity Server to use.
sid:
type: string
description: The session identifier given by the Identity Server.
required: ["client_secret", "id_server", "sid"]
bind:
type: boolean
description: |-
Whether the home server should also bind this third party
identifier to the account's Matrix ID with the passed identity
server. Default: ``false``.
x-example: true
required: ["threePidCreds"]
example: |-
{
"threePidCreds": {
"id_server": "matrix.org",
"sid": "abc123987",
"client_secret": "d0n'tT3ll"
},
"bind": false
}
responses:
200:
description: The addition was successful.
examples:
application/json: "{}"
schema:
type: object
403:
description: The credentials could not be verified with the identity server.
examples:
application/json: |-
{
"errcode": "M_THREEPID_AUTH_FAILED",
"error": "The third party credentials could not be verified by the identity server."
}

@ -1,50 +0,0 @@
{
"apiVersion": "1.0.0",
"swaggerVersion": "1.2",
"apis": [
{
"path": "-login",
"description": "Login operations"
},
{
"path": "-registration",
"description": "Registration operations"
},
{
"path": "-rooms",
"description": "Room operations"
},
{
"path": "-profile",
"description": "Profile operations"
},
{
"path": "-presence",
"description": "Presence operations"
},
{
"path": "-events",
"description": "Event operations"
},
{
"path": "-directory",
"description": "Directory operations"
},
{
"path": "-content",
"description": "Content repository operations"
}
],
"authorizations": {
"token": {
"scopes": []
}
},
"info": {
"title": "Matrix Client-Server API Reference",
"description": "This contains the client-server API for the reference implementation of the home server",
"termsOfServiceUrl": "http://matrix.org",
"license": "Apache 2.0",
"licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
}

@ -1,119 +0,0 @@
{
"apiVersion": "1.0.0",
"swaggerVersion": "1.2",
"basePath": "http://localhost:8008/_matrix",
"resourcePath": "/media/v1/",
"apis": [
{
"path": "/media/v1/upload",
"operations": [
{
"method": "POST",
"summary": "Upload some content to the content repository.",
"type": "ContentUploadResponse",
"nickname": "upload_content",
"parameters": [
{
"name": "body",
"description": "The file to upload.",
"required": true,
"type": "file",
"paramType": "body"
}
]
}
]
},
{
"path": "/media/v1/download/{serverName}/{mediaId}",
"operations": [
{
"method": "GET",
"summary": "Get the content stored at this address.",
"type": "file",
"nickname": "download_content",
"parameters": [
{
"name": "serverName",
"description": "The serverName from the mxc://<serverName>/<mediaId> URI (the authority component).",
"required": true,
"type": "string",
"paramType": "path"
},
{
"name": "mediaId",
"description": "The mediaId from the mxc://<serverName>/<mediaId> URI (the path component).",
"required": true,
"type": "string",
"paramType": "path"
}
]
}
]
},
{
"path": "/media/v1/thumbnail/{serverName}/{mediaId}",
"operations": [
{
"method": "GET",
"summary": "Get a thumbnail of the content stored at this address.",
"type": "file",
"nickname": "thumbnail_content",
"parameters": [
{
"name": "serverName",
"description": "The serverName from the mxc://<serverName>/<mediaId> URI (the authority component).",
"required": true,
"type": "string",
"paramType": "path"
},
{
"name": "mediaId",
"description": "The mediaId from the mxc://<serverName>/<mediaId> URI (the path component).",
"required": true,
"type": "string",
"paramType": "path"
},
{
"name": "width",
"description": "The desired width of the thumbnail.",
"required": false,
"type": "integer",
"paramType": "query"
},
{
"name": "height",
"description": "The desired height of the thumbnail.",
"required": false,
"type": "integer",
"paramType": "query"
},
{
"name": "method",
"description": "The desired resizing method.",
"enum": [
"crop",
"scale"
],
"required": false,
"type": "string",
"paramType": "query"
}
]
}
]
}
],
"models": {
"ContentUploadResponse": {
"id": "ContentUploadResponse",
"properties": {
"content_uri": {
"type": "string",
"description": "The mxc:// URI where this content is stored. This is of the form 'mxc://{serverName}/{mediaId}'",
"required": true
}
}
}
}
}

@ -1,101 +0,0 @@
{
"apiVersion": "1.0.0",
"swaggerVersion": "1.2",
"basePath": "http://localhost:8008/_matrix/client/api/v1",
"resourcePath": "/directory",
"produces": [
"application/json"
],
"apis": [
{
"path": "/directory/room/{roomAlias}",
"operations": [
{
"method": "GET",
"summary": "Get the room ID corresponding to this room alias.",
"notes": "Volatile: This API is likely to change.",
"type": "DirectoryResponse",
"nickname": "get_room_id_for_alias",
"parameters": [
{
"name": "roomAlias",
"description": "The room alias.",
"required": true,
"type": "string",
"paramType": "path"
}
]
},
{
"method": "PUT",
"summary": "Create a new mapping from room alias to room ID.",
"notes": "Volatile: This API is likely to change.",
"type": "void",
"nickname": "add_room_alias",
"parameters": [
{
"name": "roomAlias",
"description": "The room alias to set.",
"required": true,
"type": "string",
"paramType": "path"
},
{
"name": "body",
"description": "The room ID to set.",
"required": true,
"type": "RoomAliasRequest",
"paramType": "body"
}
]
},
{
"method": "DELETE",
"summary": "Removes a mapping of room alias to room ID.",
"notes": "Only privileged users can perform this action.",
"type": "void",
"nickname": "remove_room_alias",
"parameters": [
{
"name": "roomAlias",
"description": "The room alias to remove.",
"required": true,
"type": "string",
"paramType": "path"
}
]
}
]
}
],
"models": {
"DirectoryResponse": {
"id": "DirectoryResponse",
"properties": {
"room_id": {
"type": "string",
"description": "The fully-qualified room ID.",
"required": true
},
"servers": {
"type": "array",
"items": {
"$ref": "string"
},
"description": "A list of servers that know about this room.",
"required": true
}
}
},
"RoomAliasRequest": {
"id": "RoomAliasRequest",
"properties": {
"room_id": {
"type": "string",
"description": "The room ID to map the alias to.",
"required": true
}
}
}
}
}

@ -1,247 +0,0 @@
{
"apiVersion": "1.0.0",
"swaggerVersion": "1.2",
"basePath": "http://localhost:8008/_matrix/client/api/v1",
"resourcePath": "/events",
"produces": [
"application/json"
],
"apis": [
{
"path": "/events",
"operations": [
{
"method": "GET",
"summary": "Listen on the event stream",
"notes": "This can only be done by the logged in user. This will block until an event is received, or until the timeout is reached.",
"type": "PaginationChunk",
"nickname": "get_event_stream",
"parameters": [
{
"name": "from",
"description": "The token to stream from.",
"required": false,
"type": "string",
"paramType": "query"
},
{
"name": "timeout",
"description": "The maximum time in milliseconds to wait for an event.",
"required": false,
"type": "integer",
"paramType": "query"
}
]
}
],
"responseMessages": [
{
"code": 400,
"message": "Bad pagination token."
}
]
},
{
"path": "/events/{eventId}",
"operations": [
{
"method": "GET",
"summary": "Get information about a single event.",
"notes": "Get information about a single event.",
"type": "Event",
"nickname": "get_event",
"parameters": [
{
"name": "eventId",
"description": "The event ID to get.",
"required": true,
"type": "string",
"paramType": "path"
}
],
"responseMessages": [
{
"code": 404,
"message": "Event not found."
}
]
}
]
},
{
"path": "/initialSync",
"operations": [
{
"method": "GET",
"summary": "Get this user's current state.",
"notes": "Get this user's current state.",
"type": "InitialSyncResponse",
"nickname": "initial_sync",
"parameters": [
{
"name": "limit",
"description": "The maximum number of messages to return for each room.",
"type": "integer",
"paramType": "query",
"required": false
}
]
}
]
},
{
"path": "/publicRooms",
"operations": [
{
"method": "GET",
"summary": "Get a list of publicly visible rooms.",
"type": "PublicRoomsPaginationChunk",
"nickname": "get_public_room_list"
}
]
}
],
"models": {
"PaginationChunk": {
"id": "PaginationChunk",
"properties": {
"start": {
"type": "string",
"description": "A token which correlates to the first value in \"chunk\" for paginating.",
"required": true
},
"end": {
"type": "string",
"description": "A token which correlates to the last value in \"chunk\" for paginating.",
"required": true
},
"chunk": {
"type": "array",
"description": "An array of events.",
"required": true,
"items": {
"$ref": "Event"
}
}
}
},
"Event": {
"id": "Event",
"properties": {
"event_id": {
"type": "string",
"description": "An ID which uniquely identifies this event.",
"required": true
},
"room_id": {
"type": "string",
"description": "The room in which this event occurred.",
"required": true
}
}
},
"PublicRoomInfo": {
"id": "PublicRoomInfo",
"properties": {
"aliases": {
"type": "array",
"description": "A list of room aliases for this room.",
"items": {
"$ref": "string"
}
},
"name": {
"type": "string",
"description": "The name of the room, as given by the m.room.name state event."
},
"room_id": {
"type": "string",
"description": "The room ID for this public room.",
"required": true
},
"topic": {
"type": "string",
"description": "The topic of this room, as given by the m.room.topic state event."
}
}
},
"PublicRoomsPaginationChunk": {
"id": "PublicRoomsPaginationChunk",
"properties": {
"start": {
"type": "string",
"description": "A token which correlates to the first value in \"chunk\" for paginating.",
"required": true
},
"end": {
"type": "string",
"description": "A token which correlates to the last value in \"chunk\" for paginating.",
"required": true
},
"chunk": {
"type": "array",
"description": "A list of public room data.",
"required": true,
"items": {
"$ref": "PublicRoomInfo"
}
}
}
},
"InitialSyncResponse": {
"id": "InitialSyncResponse",
"properties": {
"end": {
"type": "string",
"description": "A streaming token which can be used with /events to continue from this snapshot of data.",
"required": true
},
"presence": {
"type": "array",
"description": "A list of presence events.",
"items": {
"$ref": "Event"
},
"required": false
},
"rooms": {
"type": "array",
"description": "A list of initial sync room data.",
"required": false,
"items": {
"$ref": "InitialSyncRoomData"
}
}
}
},
"InitialSyncRoomData": {
"id": "InitialSyncRoomData",
"properties": {
"membership": {
"type": "string",
"description": "This user's membership state in this room.",
"required": true
},
"room_id": {
"type": "string",
"description": "The ID of this room.",
"required": true
},
"messages": {
"type": "PaginationChunk",
"description": "The most recent messages for this room, governed by the limit parameter.",
"required": false
},
"state": {
"type": "array",
"description": "A list of state events representing the current state of the room.",
"required": false,
"items": {
"$ref": "Event"
}
}
}
}
}
}

@ -1,120 +0,0 @@
{
"apiVersion": "1.0.0",
"apis": [
{
"operations": [
{
"method": "GET",
"nickname": "get_login_info",
"notes": "All login stages MUST be mentioned if there is >1 login type.",
"summary": "Get the login mechanism to use when logging in.",
"type": "LoginFlows"
},
{
"method": "POST",
"nickname": "submit_login",
"notes": "If this is part of a multi-stage login, there MUST be a 'session' key.",
"parameters": [
{
"description": "A login submission",
"name": "body",
"paramType": "body",
"required": true,
"type": "LoginSubmission"
}
],
"responseMessages": [
{
"code": 400,
"message": "Bad login type"
},
{
"code": 400,
"message": "Missing JSON keys"
}
],
"summary": "Submit a login action.",
"type": "LoginResult"
}
],
"path": "/login"
}
],
"basePath": "http://localhost:8008/_matrix/client/api/v1",
"consumes": [
"application/json"
],
"models": {
"LoginFlows": {
"id": "LoginFlows",
"properties": {
"flows": {
"description": "A list of valid login flows.",
"type": "array",
"items": {
"$ref": "LoginInfo"
}
}
}
},
"LoginInfo": {
"id": "LoginInfo",
"properties": {
"stages": {
"description": "Multi-stage login only: An array of all the login types required to login.",
"items": {
"$ref": "string"
},
"type": "array"
},
"type": {
"description": "The login type that must be used when logging in.",
"type": "string"
}
}
},
"LoginResult": {
"id": "LoginResult",
"properties": {
"access_token": {
"description": "The access token for this user's login if this is the final stage of the login process.",
"type": "string"
},
"user_id": {
"description": "The user's fully-qualified user ID.",
"type": "string"
},
"next": {
"description": "Multi-stage login only: The next login type to submit.",
"type": "string"
},
"session": {
"description": "Multi-stage login only: The session token to send when submitting the next login type.",
"type": "string"
}
}
},
"LoginSubmission": {
"id": "LoginSubmission",
"properties": {
"type": {
"description": "The type of login being submitted.",
"type": "string"
},
"session": {
"description": "Multi-stage login only: The session token from an earlier login stage.",
"type": "string"
},
"_login_type_defined_keys_": {
"description": "Keys as defined by the specified login type, e.g. \"user\", \"password\""
}
}
}
},
"produces": [
"application/json"
],
"resourcePath": "/login",
"swaggerVersion": "1.2"
}

@ -1,164 +0,0 @@
{
"apiVersion": "1.0.0",
"swaggerVersion": "1.2",
"basePath": "http://localhost:8008/_matrix/client/api/v1",
"resourcePath": "/presence",
"produces": [
"application/json"
],
"consumes": [
"application/json"
],
"apis": [
{
"path": "/presence/{userId}/status",
"operations": [
{
"method": "PUT",
"summary": "Update this user's presence state.",
"notes": "This can only be done by the logged in user.",
"type": "void",
"nickname": "update_presence",
"parameters": [
{
"name": "body",
"description": "The new presence state",
"required": true,
"type": "PresenceUpdate",
"paramType": "body"
},
{
"name": "userId",
"description": "The user whose presence to set.",
"required": true,
"type": "string",
"paramType": "path"
}
]
},
{
"method": "GET",
"summary": "Get this user's presence state.",
"notes": "Get this user's presence state.",
"type": "PresenceUpdate",
"nickname": "get_presence",
"parameters": [
{
"name": "userId",
"description": "The user whose presence to get.",
"required": true,
"type": "string",
"paramType": "path"
}
]
}
]
},
{
"path": "/presence/list/{userId}",
"operations": [
{
"method": "GET",
"summary": "Retrieve a list of presences for all of this user's friends.",
"notes": "",
"type": "array",
"items": {
"$ref": "Presence"
},
"nickname": "get_presence_list",
"parameters": [
{
"name": "userId",
"description": "The user whose presence list to get.",
"required": true,
"type": "string",
"paramType": "path"
}
]
},
{
"method": "POST",
"summary": "Add or remove users from this presence list.",
"notes": "Add or remove users from this presence list.",
"type": "void",
"nickname": "modify_presence_list",
"parameters": [
{
"name": "userId",
"description": "The user whose presence list is being modified.",
"required": true,
"type": "string",
"paramType": "path"
},
{
"name": "body",
"description": "The modifications to make to this presence list.",
"required": true,
"type": "PresenceListModifications",
"paramType": "body"
}
]
}
]
}
],
"models": {
"PresenceUpdate": {
"id": "PresenceUpdate",
"properties": {
"presence": {
"type": "string",
"description": "Enum: The presence state.",
"enum": [
"offline",
"unavailable",
"online",
"free_for_chat"
]
},
"status_msg": {
"type": "string",
"description": "The user-defined message associated with this presence state."
}
},
"subTypes": [
"Presence"
]
},
"Presence": {
"id": "Presence",
"properties": {
"last_active_ago": {
"type": "integer",
"format": "int64",
"description": "The last time this user performed an action on their home server."
},
"user_id": {
"type": "string",
"description": "The fully qualified user ID"
}
}
},
"PresenceListModifications": {
"id": "PresenceListModifications",
"properties": {
"invite": {
"type": "array",
"description": "A list of user IDs to add to the list.",
"items": {
"type": "string",
"description": "A fully qualified user ID."
}
},
"drop": {
"type": "array",
"description": "A list of user IDs to remove from the list.",
"items": {
"type": "string",
"description": "A fully qualified user ID."
}
}
}
}
}
}

@ -1,122 +0,0 @@
{
"apiVersion": "1.0.0",
"swaggerVersion": "1.2",
"basePath": "http://localhost:8008/_matrix/client/api/v1",
"resourcePath": "/profile",
"produces": [
"application/json"
],
"consumes": [
"application/json"
],
"apis": [
{
"path": "/profile/{userId}/displayname",
"operations": [
{
"method": "PUT",
"summary": "Set a display name.",
"notes": "This can only be done by the logged in user.",
"type": "void",
"nickname": "set_display_name",
"parameters": [
{
"name": "body",
"description": "The new display name for this user.",
"required": true,
"type": "DisplayName",
"paramType": "body"
},
{
"name": "userId",
"description": "The user whose display name to set.",
"required": true,
"type": "string",
"paramType": "path"
}
]
},
{
"method": "GET",
"summary": "Get a display name.",
"notes": "This can be done by anyone.",
"type": "DisplayName",
"nickname": "get_display_name",
"parameters": [
{
"name": "userId",
"description": "The user whose display name to get.",
"required": true,
"type": "string",
"paramType": "path"
}
]
}
]
},
{
"path": "/profile/{userId}/avatar_url",
"operations": [
{
"method": "PUT",
"summary": "Set an avatar URL.",
"notes": "This can only be done by the logged in user.",
"type": "void",
"nickname": "set_avatar_url",
"parameters": [
{
"name": "body",
"description": "The new avatar url for this user.",
"required": true,
"type": "AvatarUrl",
"paramType": "body"
},
{
"name": "userId",
"description": "The user whose avatar url to set.",
"required": true,
"type": "string",
"paramType": "path"
}
]
},
{
"method": "GET",
"summary": "Get an avatar url.",
"notes": "This can be done by anyone.",
"type": "AvatarUrl",
"nickname": "get_avatar_url",
"parameters": [
{
"name": "userId",
"description": "The user whose avatar url to get.",
"required": true,
"type": "string",
"paramType": "path"
}
]
}
]
}
],
"models": {
"DisplayName": {
"id": "DisplayName",
"properties": {
"displayname": {
"type": "string",
"description": "The textual display name"
}
}
},
"AvatarUrl": {
"id": "AvatarUrl",
"properties": {
"avatar_url": {
"type": "string",
"description": "A url to an image representing an avatar."
}
}
}
}
}

@ -1,120 +0,0 @@
{
"apiVersion": "1.0.0",
"apis": [
{
"operations": [
{
"method": "GET",
"nickname": "get_registration_info",
"notes": "All login stages MUST be mentioned if there is >1 login type.",
"summary": "Get the login mechanism to use when registering.",
"type": "RegistrationFlows"
},
{
"method": "POST",
"nickname": "submit_registration",
"notes": "If this is part of a multi-stage registration, there MUST be a 'session' key.",
"parameters": [
{
"description": "A registration submission",
"name": "body",
"paramType": "body",
"required": true,
"type": "RegistrationSubmission"
}
],
"responseMessages": [
{
"code": 400,
"message": "Bad login type"
},
{
"code": 400,
"message": "Missing JSON keys"
}
],
"summary": "Submit a registration action.",
"type": "RegistrationResult"
}
],
"path": "/register"
}
],
"basePath": "http://localhost:8008/_matrix/client/api/v1",
"consumes": [
"application/json"
],
"models": {
"RegistrationFlows": {
"id": "RegistrationFlows",
"properties": {
"flows": {
"description": "A list of valid registration flows.",
"type": "array",
"items": {
"$ref": "RegistrationInfo"
}
}
}
},
"RegistrationInfo": {
"id": "RegistrationInfo",
"properties": {
"stages": {
"description": "Multi-stage registration only: An array of all the login types required to registration.",
"items": {
"$ref": "string"
},
"type": "array"
},
"type": {
"description": "The first login type that must be used when logging in.",
"type": "string"
}
}
},
"RegistrationResult": {
"id": "RegistrationResult",
"properties": {
"access_token": {
"description": "The access token for this user's registration if this is the final stage of the registration process.",
"type": "string"
},
"user_id": {
"description": "The user's fully-qualified user ID.",
"type": "string"
},
"next": {
"description": "Multi-stage registration only: The next registration type to submit.",
"type": "string"
},
"session": {
"description": "Multi-stage registration only: The session token to send when submitting the next registration type.",
"type": "string"
}
}
},
"RegistrationSubmission": {
"id": "RegistrationSubmission",
"properties": {
"type": {
"description": "The type of registration being submitted.",
"type": "string"
},
"session": {
"description": "Multi-stage registration only: The session token from an earlier registration stage.",
"type": "string"
},
"_registration_type_defined_keys_": {
"description": "Keys as defined by the specified registration type, e.g. \"user\", \"password\""
}
}
}
},
"produces": [
"application/json"
],
"resourcePath": "/register",
"swaggerVersion": "1.2"
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,76 @@
swagger: '2.0'
info:
title: "Matrix Client-Server v1 Room Banning API"
version: "1.0.0"
host: localhost:8008
schemes:
- https
- http
basePath: /_matrix/client/api/v1
consumes:
- application/json
produces:
- application/json
securityDefinitions:
accessToken:
type: apiKey
description: The user_id or application service access_token
name: access_token
in: query
paths:
"/rooms/{roomId}/ban":
post:
summary: Ban a user in the room.
description: |-
Ban a user in the room. If the user is currently in the room, also kick them.
When a user is banned from a room, they may not join it until they are unbanned.
The caller must have the required power level in order to perform this operation.
security:
- accessToken: []
parameters:
- in: path
type: string
name: roomId
description: The room identifier (not alias) from which the user should be banned.
required: true
x-example: "!e42d8c:matrix.org"
- in: body
name: body
required: true
schema:
type: object
example: |-
{
"reason": "Telling unfunny jokes",
"user_id": "@cheeky_monkey:matrix.org"
}
properties:
user_id:
type: string
description: The fully qualified user ID of the user being banned.
reason:
type: string
description: The reason the user has been banned.
required: ["user_id"]
responses:
200:
description: The user has been kicked and banned from the room.
examples:
application/json: |-
{}
schema:
type: object
403:
description: |-
You do not have permission to ban the user from the room. A meaningful ``errcode`` and description error text will be returned. Example reasons for rejections are:
- The banner is not currently in the room.
- The banner's power level is insufficient to ban users from the room.
examples:
application/json: |-
{
"errcode": "M_FORBIDDEN",
"error": "You do not have a high enough power level to ban from this room."
}

@ -0,0 +1,53 @@
{
"type": "object",
"title": "Event",
"properties": {
"content": {
"type": "object",
"title": "EventContent",
"description": "The content of this event. The fields in this object will vary depending on the type of event."
},
"origin_server_ts": {
"type": "integer",
"format": "int64",
"description": "Timestamp in milliseconds on originating homeserver when this event was sent."
},
"sender": {
"type": "string",
"description": "The MXID of the user who sent this event."
},
"state_key": {
"type": "string",
"description": "Optional. This key will only be present for state events. A unique key which defines the overwriting semantics for this piece of room state."
},
"type": {
"type": "string",
"description": "The type of event."
},
"unsigned": {
"type": "object",
"title": "Unsigned",
"description": "Information about this event which was not sent by the originating homeserver",
"properties": {
"age": {
"type": "integer",
"format": "int64",
"description": "Time in milliseconds since the event was sent."
},
"prev_content": {
"title": "EventContent",
"type": "object",
"description": "Optional. The previous ``content`` for this state. This will be present only for state events appearing in the ``timeline``. If this is not a state event, or there is no previous content, this key will be missing."
},
"replaces_state": {
"type": "string",
"description": "Optional. The event_id of the previous event for this state. This will be present only for state events appearing in the ``timeline``. If this is not a state event, or there is no previous content, this key will be missing."
},
"transaction_id": {
"type": "string",
"description": "Optional. The transaction ID set when this message was sent. This key will only be present for message events sent by the device calling this API."
}
}
}
}
}

@ -5,8 +5,8 @@
"type": "array", "type": "array",
"description": "List of events", "description": "List of events",
"items": { "items": {
"title": "Event", "type": "object",
"type": "object" "allOf": [{"$ref": "event.json" }]
} }
} }
} }

@ -1,6 +1,6 @@
{ {
"type": "object", "type": "object",
"allOf": [{"$ref": "definitions/event_filter.json"}], "allOf": [{"$ref": "event_filter.json"}],
"properties": { "properties": {
"rooms": { "rooms": {
"type": "array", "type": "array",

@ -7,24 +7,24 @@
"state": { "state": {
"description": "description":
"The state events to include for rooms.", "The state events to include for rooms.",
"allOf": [{"$ref": "definitions/room_event_filter.json"}] "allOf": [{"$ref": "room_event_filter.json"}]
}, },
"timeline": { "timeline": {
"description": "description":
"The message and state update events to include for rooms.", "The message and state update events to include for rooms.",
"allOf": [{"$ref": "definitions/room_event_filter.json"}] "allOf": [{"$ref": "room_event_filter.json"}]
}, },
"ephemeral": { "ephemeral": {
"description": "description":
"The events that aren't recorded in the room history, e.g. typing and receipts, to include for rooms.", "The events that aren't recorded in the room history, e.g. typing and receipts, to include for rooms.",
"allOf": [{"$ref": "definitions/room_event_filter.json"}] "allOf": [{"$ref": "room_event_filter.json"}]
} }
} }
}, },
"presence": { "presence": {
"description": "description":
"The presence updates to include.", "The presence updates to include.",
"allOf": [{"$ref": "definitions/event_filter.json"}] "allOf": [{"$ref": "event_filter.json"}]
}, },
"event_format": { "event_format": {
"description": "description":

@ -0,0 +1,14 @@
{
"type": "object",
"allOf": [{"$ref":"event_batch.json"}],
"properties": {
"limited": {
"type": "boolean",
"description": "True if the number of events returned was limited by the ``limit`` on the filter"
},
"prev_batch": {
"type": "string",
"description": "If the batch was limited then this is a token that can be supplied to the server to retrieve earlier events"
}
}
}

@ -29,6 +29,7 @@ paths:
name: roomAlias name: roomAlias
description: The room alias to set. description: The room alias to set.
required: true required: true
x-example: "#monkeys:matrix.org"
- in: body - in: body
name: roomInfo name: roomInfo
description: Information about this room alias. description: Information about this room alias.
@ -39,11 +40,18 @@ paths:
room_id: room_id:
type: string type: string
description: The room ID to set. description: The room ID to set.
example: |-
{
"room_id": "!abnjk1jdasj98:capuchins.com"
}
responses: responses:
200: 200:
description: The mapping was created. description: The mapping was created.
examples:
application/json: |-
{}
schema: schema:
type: object # empty json object type: object
get: get:
summary: Get the room ID corresponding to this room alias. summary: Get the room ID corresponding to this room alias.
parameters: parameters:
@ -52,6 +60,7 @@ paths:
name: roomAlias name: roomAlias
description: The room alias. description: The room alias.
required: true required: true
x-example: "#monkeys:matrix.org"
responses: responses:
200: 200:
description: The room ID and other information for this alias. description: The room ID and other information for this alias.
@ -67,10 +76,38 @@ paths:
items: items:
type: string type: string
description: A server which is aware of this room ID. description: A server which is aware of this room ID.
examples:
application/json: |-
{
"room_id": "!abnjk1jdasj98:capuchins.com",
"servers": [
"capuchins.com",
"matrix.org",
"another.com"
]
}
404: 404:
description: There is no mapped room ID for this room alias. description: There is no mapped room ID for this room alias.
examples:
application/json: |-
{
"errcode": "M_NOT_FOUND",
"error": "Room ID !abnjk1jdasj98:capuchins.com not found."
}
409:
description: A room alias with that name already exists.
examples:
application/json: |-
{
"errcode": "M_UNKNOWN",
"error": "Room alias #monkeys:matrix.org already exists."
}
delete: delete:
summary: Remove a mapping of room alias to room ID. summary: Remove a mapping of room alias to room ID.
description: |-
Remove a mapping of room alias to room ID.
Servers may choose to implement additional access control checks here, for instance that room aliases can only be deleted by their creator or a server administrator.
security: security:
- accessToken: [] - accessToken: []
parameters: parameters:
@ -79,9 +116,12 @@ paths:
name: roomAlias name: roomAlias
description: The room alias to remove. description: The room alias to remove.
required: true required: true
x-example: "#monkeys:matrix.org"
responses: responses:
200: 200:
description: The mapping was removed. description: The mapping was deleted.
examples:
application/json: |-
{}
schema: schema:
type: object # empty json object type: object

@ -98,6 +98,6 @@ paths:
type: object type: object
title: Event title: Event
allOf: allOf:
- "$ref": "core-event-schema/room_event.json" - "$ref": "../../event-schemas/schema/core-event-schema/room_event.json"
400: 400:
description: "Bad pagination ``from`` parameter." description: "Bad pagination ``from`` parameter."

@ -1,6 +1,6 @@
swagger: '2.0' swagger: '2.0'
info: info:
title: "Matrix Client-Server v1 Room Membership API" title: "Matrix Client-Server v1 Room Joining API"
version: "1.0.0" version: "1.0.0"
host: localhost:8008 host: localhost:8008
schemes: schemes:
@ -18,55 +18,6 @@ securityDefinitions:
name: access_token name: access_token
in: query in: query
paths: paths:
"/rooms/{roomId}/join":
post:
summary: Start the requesting user participating in a particular room.
description: |-
This API starts a user participating in a particular room, if that user
is allowed to participate in that room. After this call, the client is
allowed to see all current state events in the room, and all subsequent
events associated with the room until the user leaves the room.
After a user has joined a room, the room will appear as an entry in the
response of the |initialSync| API.
security:
- accessToken: []
parameters:
- in: path
type: string
name: roomId
description: The room identifier or room alias to join.
required: true
x-example: "#monkeys:matrix.org"
responses:
200:
description: |-
The room has been joined.
The joined room ID must be returned in the ``room_id`` field.
examples:
application/json: |-
{"room_id": "!d41d8cd:matrix.org"}
schema:
type: object
403:
description: |-
You do not have permission to join the room. A meaningful ``errcode`` and description error text will be returned. Example reasons for rejection are:
- The room is invite-only and the user was not invited.
- The user has been banned from the room.
examples:
application/json: |-
{"errcode": "M_FORBIDDEN", "error": "You are not invited to this room."}
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
x-alias:
canonical-link: "post-matrix-client-api-v1-rooms-roomid-join"
aliases:
- /join/{roomId}
# With an extra " " to disambiguate from the 3pid invite endpoint # With an extra " " to disambiguate from the 3pid invite endpoint
# The extra space makes it sort first for what I'm sure is a good reason. # The extra space makes it sort first for what I'm sure is a good reason.
"/rooms/{roomId}/invite ": "/rooms/{roomId}/invite ":

@ -0,0 +1,68 @@
swagger: '2.0'
info:
title: "Matrix Client-Server v1 Room Inviting API"
version: "1.0.0"
host: localhost:8008
schemes:
- https
- http
basePath: /_matrix/client/api/v1
consumes:
- application/json
produces:
- application/json
securityDefinitions:
accessToken:
type: apiKey
description: The user_id or application service access_token
name: access_token
in: query
paths:
"/rooms/{roomId}/join":
post:
summary: Start the requesting user participating in a particular room.
description: |-
This API starts a user participating in a particular room, if that user
is allowed to participate in that room. After this call, the client is
allowed to see all current state events in the room, and all subsequent
events associated with the room until the user leaves the room.
After a user has joined a room, the room will appear as an entry in the
response of the |initialSync| API.
security:
- accessToken: []
parameters:
- in: path
type: string
name: roomId
description: The room identifier or room alias to join.
required: true
x-example: "#monkeys:matrix.org"
responses:
200:
description: |-
The room has been joined.
The joined room ID must be returned in the ``room_id`` field.
examples:
application/json: |-
{"room_id": "!d41d8cd:matrix.org"}
schema:
type: object
403:
description: |-
You do not have permission to join the room. A meaningful ``errcode`` and description error text will be returned. Example reasons for rejection are:
- The room is invite-only and the user was not invited.
- The user has been banned from the room.
examples:
application/json: |-
{"errcode": "M_FORBIDDEN", "error": "You are not invited to this room."}
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
x-alias:
canonical-link: "post-matrix-client-api-v1-rooms-roomid-join"
aliases:
- /_matrix/client/api/v1/join/{roomId}

@ -0,0 +1,92 @@
swagger: '2.0'
info:
title: "Matrix Client-Server v1 Room Leaving API"
version: "1.0.0"
host: localhost:8008
schemes:
- https
- http
basePath: /_matrix/client/api/v1
consumes:
- application/json
produces:
- application/json
securityDefinitions:
accessToken:
type: apiKey
description: The user_id or application service access_token
name: access_token
in: query
paths:
"/rooms/{roomId}/leave":
post:
summary: Stop the requesting user participating in a particular room.
description: |-
This API stops a user participating in a particular room.
If the user was already in the room, they will no longer be able to see
new events in the room. If the room requires an invite to join, they
will need to be re-invited before they can re-join.
If the user was invited to the room, but had not joined, this call
serves to reject the invite.
The user will still be allowed to retrieve history from the room which
they were previously allowed to see.
security:
- accessToken: []
parameters:
- in: path
type: string
name: roomId
description: The room identifier to leave.
required: true
x-example: "!nkl290a:matrix.org"
responses:
200:
description: |-
The room has been left.
examples:
application/json: |-
{}
schema:
type: object
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
"/rooms/{roomId}/forget":
post:
summary: Stop the requesting user remembering about a particular room.
description: |-
This API stops a user remembering about a particular room.
In general, history is a first class citizen in Matrix. After this API
is called, however, a user will no longer be able to retrieve history
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.
security:
- accessToken: []
parameters:
- in: path
type: string
name: roomId
description: The room identifier to forget.
required: true
x-example: "!au1ba7o:matrix.org"
responses:
200:
description: |-
The room has been forgotten.
examples:
application/json: |-
{}
schema:
type: object
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"

@ -84,7 +84,7 @@ paths:
type: object type: object
title: Event title: Event
allOf: allOf:
- "$ref": "core-event-schema/room_event.json" - "$ref": "../../event-schemas/schema/core-event-schema/room_event.json"
400: 400:
description: "Bad pagination ``from`` parameter." description: "Bad pagination ``from`` parameter."
"/initialSync": "/initialSync":
@ -131,6 +131,14 @@ paths:
"type": "m.presence" "type": "m.presence"
} }
], ],
"account_data": [
{
"type": "org.example.custom.config",
"content": {
"custom_config_key": "custom_config_value"
}
}
],
"rooms": [ "rooms": [
{ {
"membership": "join", "membership": "join",
@ -245,7 +253,19 @@ paths:
"user_id": "@alice:localhost" "user_id": "@alice:localhost"
} }
], ],
"visibility": "private" "visibility": "private",
"account_data": [
{
"type": "m.tag",
"content": {"tags": {"work": {"order": 1}}}
},
{
"type": "org.example.custom.room.config",
"content": {
"custom_config_key": "custom_config_value"
}
}
]
} }
] ]
} }
@ -265,7 +285,7 @@ paths:
type: object type: object
title: Event title: Event
allOf: allOf:
- "$ref": "core-event-schema/event.json" - "$ref": "../../event-schemas/schema/core-event-schema/event.json"
rooms: rooms:
type: array type: array
items: items:
@ -284,7 +304,7 @@ paths:
title: "InviteEvent" title: "InviteEvent"
description: "The invite event if ``membership`` is ``invite``" description: "The invite event if ``membership`` is ``invite``"
allOf: allOf:
- "$ref": "v1-event-schema/m.room.member" - "$ref": "../../event-schemas/schema/m.room.member"
messages: messages:
type: object type: object
title: PaginationChunk title: PaginationChunk
@ -312,7 +332,7 @@ paths:
type: object type: object
title: RoomEvent title: RoomEvent
allOf: allOf:
- "$ref": "core-event-schema/room_event.json" - "$ref": "../../event-schemas/schema/core-event-schema/room_event.json"
required: ["start", "end", "chunk"] required: ["start", "end", "chunk"]
state: state:
type: array type: array
@ -325,13 +345,23 @@ paths:
title: StateEvent title: StateEvent
type: object type: object
allOf: allOf:
- "$ref": "core-event-schema/state_event.json" - "$ref": "../../event-schemas/schema/core-event-schema/state_event.json"
visibility: visibility:
type: string type: string
enum: ["private", "public"] enum: ["private", "public"]
description: |- description: |-
Whether this room is visible to the ``/publicRooms`` API Whether this room is visible to the ``/publicRooms`` API
or not." or not."
account_data:
type: array
description: |-
The private data that this user has attached to
this room.
items:
title: Event
type: object
allOf:
- "$ref": "../../event-schemas/schema/core-event-schema/event.json"
required: ["room_id", "membership"] required: ["room_id", "membership"]
required: ["end", "rooms", "presence"] required: ["end", "rooms", "presence"]
404: 404:
@ -368,6 +398,6 @@ paths:
} }
schema: schema:
allOf: allOf:
- "$ref": "core-event-schema/event.json" - "$ref": "../../event-schemas/schema/core-event-schema/event.json"
404: 404:
description: The event was not found or you do not have permission to read this event. description: The event was not found or you do not have permission to read this event.

@ -205,4 +205,4 @@ paths:
type: object type: object
title: PresenceEvent title: PresenceEvent
allOf: allOf:
- "$ref": "core-event-schema/event.json" - "$ref": "../../event-schemas/schema/core-event-schema/event.json"

@ -76,50 +76,3 @@ paths:
type: string type: string
description: |- description: |-
A unique identifier for the event. A unique identifier for the event.
"/rooms/{roomId}/send/{eventType}":
post:
summary: Send a message event to the given room.
description: |-
This endpoint can be used to send a message event to a room; however
the lack of a transaction ID means that it is possible to cause message
duplication if events are resent on error, so it is preferable to use
`PUT /_matrix/client/api/v1/rooms/{roomId}/send/{eventType}/{txnId}`_.
security:
- accessToken: []
parameters:
- in: path
type: string
name: roomId
description: The room to send the event to.
required: true
x-example: "!636q39766251:example.com"
- in: path
type: string
name: eventType
description: The type of event to send.
required: true
x-example: "m.room.message"
- in: body
name: body
schema:
type: object
example: |-
{
"msgtype": "m.text",
"body": "hello"
}
responses:
200:
description: "An ID for the sent event."
examples:
application/json: |-
{
"event_id": "YUwRidLecu"
}
schema:
type: object
properties:
event_id:
type: string
description: |-
A unique identifier for the event.

@ -173,7 +173,7 @@ paths:
title: StateEvent title: StateEvent
type: object type: object
allOf: allOf:
- "$ref": "core-event-schema/state_event.json" - "$ref": "../../event-schemas/schema/core-event-schema/state_event.json"
403: 403:
description: > description: >
You aren't a member of the room and weren't previously a You aren't a member of the room and weren't previously a
@ -311,7 +311,11 @@ paths:
"user_id": "@alice:example.com" "user_id": "@alice:example.com"
} }
], ],
"visibility": "private" "visibility": "private",
"account_data": [{
"type": "m.tag",
"content": {"tags": {"work": {"order": "1"}}}
}]
} }
schema: schema:
title: RoomInfo title: RoomInfo
@ -351,7 +355,7 @@ paths:
type: object type: object
title: RoomEvent title: RoomEvent
allOf: allOf:
- "$ref": "core-event-schema/room_event.json" - "$ref": "../../event-schemas/schema/core-event-schema/room_event.json"
required: ["start", "end", "chunk"] required: ["start", "end", "chunk"]
state: state:
type: array type: array
@ -364,13 +368,22 @@ paths:
title: StateEvent title: StateEvent
type: object type: object
allOf: allOf:
- "$ref": "core-event-schema/state_event.json" - "$ref": "../../event-schemas/schema/core-event-schema/state_event.json"
visibility: visibility:
type: string type: string
enum: ["private", "public"] enum: ["private", "public"]
description: |- description: |-
Whether this room is visible to the ``/publicRooms`` API Whether this room is visible to the ``/publicRooms`` API
or not." or not."
account_data:
type: array
description: |-
The private data that this user has attached to this room.
items:
title: Event
type: object
allOf:
- "$ref": "../../event-schemas/schema/core-event-schema/event.json"
required: ["room_id"] required: ["room_id"]
403: 403:
description: > description: >
@ -440,7 +453,7 @@ paths:
title: MemberEvent title: MemberEvent
type: object type: object
allOf: allOf:
- "$ref": "v1-event-schema/m.room.member" - "$ref": "../../event-schemas/schema/m.room.member"
403: 403:
description: > description: >
You aren't a member of the room and weren't previously a You aren't a member of the room and weren't previously a

@ -178,7 +178,7 @@ paths:
title: Event title: Event
description: The event that matched. description: The event that matched.
allOf: allOf:
- "$ref": "core-event-schema/room_event.json" - "$ref": "../../event-schemas/schema/core-event-schema/room_event.json"
context: context:
type: object type: object
title: Event Context title: Event Context
@ -218,7 +218,7 @@ paths:
type: object type: object
title: Event title: Event
allOf: allOf:
- "$ref": "core-event-schema/room_event.json" - "$ref": "../../event-schemas/schema/core-event-schema/room_event.json"
events_after: events_after:
type: array type: array
title: Events After title: Events After
@ -227,7 +227,7 @@ paths:
type: object type: object
title: Event title: Event
allOf: allOf:
- "$ref": "core-event-schema/room_event.json" - "$ref": "../../event-schemas/schema/core-event-schema/room_event.json"
state: state:
type: object type: object
title: Current state title: Current state
@ -238,7 +238,7 @@ paths:
type: object type: object
title: Event title: Event
allOf: allOf:
- "$ref": "core-event-schema/room_event.json" - "$ref": "../../event-schemas/schema/core-event-schema/room_event.json"
groups: groups:
type: object type: object
title: Groups title: Groups

@ -95,33 +95,26 @@ paths:
description: |- description: |-
Updates to rooms. Updates to rooms.
properties: properties:
joined: join:
title: Joined title: Joined Rooms
type: object type: object
description: |-
The rooms that the user has joined.
additionalProperties: additionalProperties:
title: Joined Room title: Joined Room
type: object type: object
properties: properties:
event_map:
title: EventMap
type: object
description: |-
A map from event ID to events for this room. The
events are referenced from the ``timeline`` and
``state`` keys for this room.
additionalProperties:
title: Event
description: An event object.
type: object
allOf:
- $ref: "core-event-schema/event.json"
state: state:
title: State title: State
type: object type: object
description: |- description: |-
The state updates for the room. Updates to the state, between the time indicated by
the ``since`` parameter, and the start of the
``timeline`` (or all state up to the start of the
``timeline``, if ``since`` is not given, or
``full_state`` is true).
allOf: allOf:
- $ref: "definitions/room_event_batch.json" - $ref: "definitions/event_batch.json"
timeline: timeline:
title: Timeline title: Timeline
type: object type: object
@ -139,8 +132,16 @@ paths:
e.g. typing. e.g. typing.
allOf: allOf:
- $ref: "definitions/event_batch.json" - $ref: "definitions/event_batch.json"
invited: account_data:
title: Invited title: Account Data
type: object
description: |-
The private data that this user has attached to
this room.
allOf:
- $ref: "definitions/event_batch.json"
invite:
title: Invited Rooms
type: object type: object
description: |- description: |-
The rooms that the user has been invited to. The rooms that the user has been invited to.
@ -166,37 +167,22 @@ paths:
``invite_state``. ``invite_state``.
allOf: allOf:
- $ref: "definitions/event_batch.json" - $ref: "definitions/event_batch.json"
archived: leave:
title: Archived title: Left rooms
type: object type: object
description: |- description: |-
The rooms that the user has left or been banned from. The The rooms that the user has left or been banned from.
entries in the room_map will lack an ``ephemeral`` key.
additionalProperties: additionalProperties:
title: Archived Room title: Left Room
type: object type: object
properties: properties:
event_map:
title: EventMap
type: object
description: |-
A map from event ID to events for this room. The
events are referenced from the ``timeline`` and
``state`` keys for this room.
additionalProperties:
title: Event
description: An event object.
type: object
allOf:
- $ref: "core-event-schema/event.json"
state: state:
title: State title: State
type: object type: object
description: |- description: |-
The state updates for the room up to the point when The state updates for the room up to the start of the timeline.
the user left.
allOf: allOf:
- $ref: "definitions/room_event_batch.json" - $ref: "definitions/event_batch.json"
timeline: timeline:
title: Timeline title: Timeline
type: object type: object
@ -225,48 +211,54 @@ paths:
} }
] ]
}, },
"account_data": {
"events": [
{
"type": "org.example.custom.config",
"content": {
"custom_config_key": "custom_config_value"
}
}
]
},
"rooms": { "rooms": {
"joined": { "join": {
"!726s6s6q:example.com": { "!726s6s6q:example.com": {
"event_map": {
"$66697273743031:example.com": {
"sender": "@alice:example.com",
"type": "m.room.member",
"state_key": "@alice:example.com",
"content": {"membership": "join"},
"origin_server_ts": 1417731086795
},
"$7365636s6r6432:example.com": {
"sender": "@bob:example.com",
"type": "m.room.member",
"state_key": "@bob:example.com",
"content": {"membership": "join"},
"unsigned": {
"prev_content": {"membership": "invite"}
},
"origin_server_ts": 1417731086795
},
"$74686972643033:example.com": {
"sender": "@alice:example.com",
"type": "m.room.message",
"unsigned": {"age": "124524", "txn_id": "1234"},
"content": {
"body": "I am a fish",
"msgtype": "m.text"
},
"origin_server_ts": 1417731086797
}
},
"state": { "state": {
"events": [ "events": [
"$66697273743031:example.com", {
"$7365636s6r6432:example.com" "sender": "@alice:example.com",
"type": "m.room.member",
"state_key": "@alice:example.com",
"content": {"membership": "join"},
"origin_server_ts": 1417731086795,
"event_id": "$66697273743031:example.com"
}
] ]
}, },
"timeline": { "timeline": {
"events": [ "events": [
"$7365636s6r6432:example.com", {
"$74686972643033:example.com" "sender": "@bob:example.com",
"type": "m.room.member",
"state_key": "@bob:example.com",
"content": {"membership": "join"},
"prev_content": {"membership": "invite"},
"origin_server_ts": 1417731086795,
"event_id": "$7365636s6r6432:example.com"
},
{
"sender": "@alice:example.com",
"type": "m.room.message",
"age": 124524,
"txn_id": "1234",
"content": {
"body": "I am a fish",
"msgtype": "m.text"
},
"origin_server_ts": 1417731086797,
"event_id": "$74686972643033:example.com"
}
], ],
"limited": true, "limited": true,
"prev_batch": "t34-23535_0_0" "prev_batch": "t34-23535_0_0"
@ -274,15 +266,28 @@ paths:
"ephemeral": { "ephemeral": {
"events": [ "events": [
{ {
"room_id": "!726s6s6q:example.com",
"type": "m.typing", "type": "m.typing",
"content": {"user_ids": ["@alice:example.com"]} "content": {"user_ids": ["@alice:example.com"]}
} }
] ]
},
"account_data": {
"events": [
{
"type": "m.tag",
"content": {"tags": {"work": {"order": 1}}}
},
{
"type": "org.example.custom.room.config",
"content": {
"custom_config_key": "custom_config_value"
}
}
]
} }
} }
}, },
"invited": { "invite": {
"!696r7674:example.com": { "!696r7674:example.com": {
"invite_state": { "invite_state": {
"events": [ "events": [
@ -302,6 +307,6 @@ paths:
} }
} }
}, },
"archived": {} "leave": {}
} }
} }

@ -0,0 +1,147 @@
swagger: '2.0'
info:
title: "Matrix Client-Server tag API"
version: "1.0.0"
host: localhost:8008
schemes:
- https
- http
basePath: /_matrix/client/v2_alpha
consumes:
- application/json
produces:
- application/json
securityDefinitions:
accessToken:
type: apiKey
description: The user_id or application service access_token
name: access_token
in: query
paths:
"/user/{userId}/rooms/{roomId}/tags":
get:
summary: List the tags for a room.
description: |-
List the tags set by a user on a room.
security:
- accessToken: []
parameters:
- in: path
type: string
name: userId
required: true
description: |-
The id of the user to get tags for. The access token must be
authorized to make requests for this user id.
x-example: "@alice:example.com"
- in: path
type: string
name: roomId
required: true
description: |-
The id of the room to get tags for.
x-example: "!726s6s6q:example.com"
responses:
200:
description:
The list of tags for the user for the room.
schema:
type: object
properties:
tags:
title: Tags
type: object
examples:
application/json: |-
{
"tags": {
"work": {"order": "1"},
"pinned": {}
}
}
"/user/{userId}/rooms/{roomId}/tags/{tag}":
put:
summary: Add a tag to a room.
description: |-
Add a tag to the room.
security:
- accessToken: []
parameters:
- in: path
type: string
name: userId
required: true
description: |-
The id of the user to add a tag for. The access token must be
authorized to make requests for this user id.
x-example: "@alice:example.com"
- in: path
type: string
name: roomId
required: true
description: |-
The id of the room to add a tag to.
x-example: "!726s6s6q:example.com"
- in: path
type: string
name: tag
required: true
description: |-
The tag to add.
x-example: "work"
- in: body
name: body
required: true
description: |-
Extra data for the tag, e.g. ordering.
schema:
type: object
example: |-
{"order": "1"}
responses:
200:
description:
The tag was successfully added.
schema:
type: object
examples:
application/json: |-
{}
delete:
summary: Remove a tag from the room.
description: |-
Remove a tag from the room.
security:
- access_token: []
parameters:
- in: path
type: string
name: userId
required: true
description: |-
The id of the user to remove a tag for. The access token must be
authorized to make requests for this user id.
x-example: "@alice:example.com"
- in: path
type: string
name: roomId
required: true
description: |-
The id of the room to remove a tag from.
x-example: "!726s6s6q:example.com"
- in: path
type: string
name: tag
required: true
description: |-
The tag to remove.
x-example: "work"
responses:
200:
description:
The tag was successfully removed
schema:
type: object
examples:
application/json: |-
{}

@ -1 +0,0 @@
v1-event-schema/core-event-schema

@ -1 +0,0 @@
../../../event-schemas/schema/v1

@ -1 +0,0 @@
../../../event-schemas/schema/v1/core-event-schema

@ -1,10 +0,0 @@
type: object
description: A Matrix-level Error
properties:
errcode:
type: string
description: An error code.
error:
type: string
description: A human-readable error message.
required: ["errcode"]

@ -1,12 +0,0 @@
{
"type": "object",
"properties": {
"events": {
"type": "array",
"description": "List of event ids",
"items": {
"type": "string"
}
}
}
}

@ -1,14 +0,0 @@
{
"type": "object",
"allOf": [{"$ref":"definitions/room_event_batch.json"}],
"properties": {
"limited": {
"type": "boolean",
"description": "Whether there are more events on the server"
},
"prev_batch": {
"type": "string",
"description": "If the batch was limited then this is a token that can be supplied to the server to retrieve more events"
}
}
}

@ -0,0 +1,146 @@
Goals of Key-Distribution in Matrix
===================================
* No Central Authority: Users should not need to trust a central authority
when determining the authenticity of keys.
* Easy to Add New Devices: It should be easy for a user to start using a
new device.
* Possible to discover MITM: It should be possible for a user to determine if
they are being MITM.
* Lost Devices: It should be possible for a user to recover if they lose all
their devices.
* No Copying Keys: Keys should be per device and shouldn't leave the device
they were created on.
A Possible Mechanism for Key Distribution
=========================================
Basic API for setting up keys on a server:
https://github.com/matrix-org/matrix-doc/pull/24
Client shouldn't trust the keys unless they have been verified, e.g by
comparing fingerprints.
If a user adds a new device it should some yet to be specified protocol
communicate with an old device and obtain a cross-signature from the old
device for its public key.
The new device can then present the cross-signed key to all the devices
that the user is in conversations with. Those devices should then include
the new device into those conversations.
If the user cannot cross-sign the new key, e.g. because their old device
is lost or stolen. Then they will need to reauthenticate their conversations
out of band, e.g by comparing fingerprints.
Goals of End-to-end encryption in Matrix
========================================
* Access to Chat History: Users should be able to see the history of a
conversation on a new device. User should be able to control who can
see their chat history and how much of the chat history they can see.
* Forward Secrecy of Discarded Chat History: Users should be able to discard
history from their device, once they have discarded the history it should be
impossible for an adversary to recover that history.
* Forward Secrecy of Future Messages: Users should be able to recover from
disclosure of the chat history on their device.
* Deniablity of Chat History: It should not be possible to prove to a third
party that a given user sent a message.
* Authenticity of Chat History: It should be possible to prove amoungst
the members of a chat that a message sent by a user was authored by that
user.
Bonus Goals:
* Traffic Analysis: It would be nice if the protocol was resilient to traffic
or metadata analysis. However it's not something we want to persue if it
harms the usability of the protocol. It might be cool if there was a
way for the user to could specify the trade off between performance and
resilience to traffic analysis that they wanted.
A Possible Design for Group Chat using Olm
==========================================
Protecting the secrecy of history
---------------------------------
Each message sent by a client has a 32-bit counter. This counter increments
by one for each message sent by the client. This counter is used to advance a
ratchet. The ratchet is split into a vector four 256-bit values,
:math:`R_{n,j}` for :math:`j \in {0,1,2,3}`. The ratchet can be advanced as
follows:
.. math::
\begin{align}
R_{2^24n,0} &= H_0\left(R_{2^24(i-1),0}\right) \\
R_{2^24n,1} &= H_1\left(R_{2^24(i-1),0}\right) \\
R_{2^24n,2} &= H_2\left(R_{2^24(i-1),0}\right) \\
R_{2^24n,3} &= H_3\left(R_{2^24(i-1),0}\right) \\
R_{2^16n,1} &= H_1\left(R_{2^16(i-1),1}\right) \\
R_{2^16n,2} &= H_2\left(R_{2^16(i-1),1}\right) \\
R_{2^16n,3} &= H_3\left(R_{2^16(i-1),1}\right) \\
R_{2^8i,2} &= H_2\left(R_{2^8(i-1),2}\right) \\
R_{2^8i,3} &= H_3\left(R_{2^8(i-1),2}\right) \\
R_{i,3} &= H_3\left(R_{(i-1),3}\right)
\end{align}
Where :math:`H_0`, :math:`H_1`, :math:`H_2`, and :math:`H_3`
are different hash functions. For example
:math:`H_0` could be :math:`HMAC\left(X,\text{"\textbackslash x00"}\right)` and
:math:`H_1` could be :math:`HMAC\left(X,\text{"\textbackslash x01"}\right)`.
So every :math:`2^24` iterations :math:`R_{n,1}` is reseeded from :math:`R_{n,0}`.
Every :math:`2^16` iterations :math:`R_{n,2}` is reseeded from :math:`R_{n,1}`.
Every :math:`2^8` iterations :math:`R_{n,3}` is reseeded from :math:`R_{n,2}`.
This scheme allows the ratchet to be advanced an arbitrary amount forwards
while needing only 1024 hash computations.
This the value of the ratchet is hashed to generate the keys used to encrypt
each mesage.
A client can decrypt chat history onwards from the earliest value of the
ratchet it is aware of. But cannot decrypt history from before that point
without reversing the hash function.
This allows a client to share its ability to decrypt chat history with another
from a point in the conversation onwards by giving a copy of the ratchet at
that point in the conversation.
A client can discard history by advancing a ratchet to beyond the last message
they want to discard and then forgetting all previous values of the ratchet.
Proving and denying the authenticity of history
-----------------------------------------------
Client sign the messages they send using a Ed25519 key generated per
conversation. That key, along with the ratchet key, is distributed
to other clients using 1:1 olm ratchets. Those 1:1 ratchets are started using
Triple Diffie-Hellman which provides authenticity of the messages to the
participants and deniability of the messages to third parties. Therefore
any keys shared over those keys inherit the same levels of deniability and
authenticity.
Protecting the secrecy of future messages
-----------------------------------------
A client would need to generate new keys if it wanted to prevent access to
messages beyond a given point in the conversation. It must generate new keys
whenever someone leaves the room. It should generate new keys periodically
anyway.
The frequency of key generation in a large room may need to be restricted to
keep the frequency of messages broadcast over the individual 1:1 channels
low.

@ -0,0 +1,285 @@
WebSockets API
==============
Introduction
------------
This document is a proposal for a WebSockets-based client-server API. It is not
intended to replace the REST API, but rather to complement it and provide an
alternative interface for certain operations.
The primary goal is to offer a more efficient interface than the REST API: by
using a bidirectional protocol such as WebSockets we can avoid the overheads
involved in long-polling (SSL negotiation, HTTP headers, etc). In doing so we
will reduce the latency between server and client by allowing the server to
send events as soon as they arrive, rather than having to wait for a poll from
the client.
Handshake
---------
1. Instead of calling ``/sync``, the client makes a websocket request to
``/_matrix/client/rN/stream``, passing the query parameters ``access_token``
and ``since``, and optionally ``filter`` - all of which have the same
meaning as for ``/sync``.
* The client sets the ``Sec-WebSocket-Protocol`` to ``m.json``. (Servers may
offer alternative encodings; at present only the JSON encoding is
specified but in future we will specify alternative encodings.)
#. The server returns the websocket handshake; the socket is then connected.
If the server does not return a valid websocket handshake, this indicates that
the server or an intermediate proxy does not support WebSockets. In this case,
the client should fall back to polling the ``/sync`` REST endpoint.
Example
~~~~~~~
Client request:
.. code:: http
GET /_matrix/client/v2_alpha/stream?access_token=123456&since=s72594_4483_1934 HTTP/1.1
Host: matrix.org
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: m.json
Sec-WebSocket-Version: 13
Origin: https://matrix.org
Server response:
.. code:: http
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: m.json
Update Notifications
--------------------
Once the socket is connected, the server begins streaming updates over the
websocket. The server sends Update notifications about new messages or state
changes. To make it easy for clients to parse, Update notifications have the
same structure as the response to ``/sync``: an object with the following
members:
============= ========== ===================================================
Key Type Description
============= ========== ===================================================
next_batch string The batch token to supply in the ``since`` param of
the next /sync request. This is not required for
streaming of events over the WebSocket, but is
provided so that clients can reconnect if the
socket is disconnected.
presence Presence The updates to the presence status of other users.
rooms Rooms Updates to rooms.
============= ========== ===================================================
Example
~~~~~~~
Message from the server:
.. code:: json
{
"next_batch": "s72595_4483_1934",
"presence": {
"events": []
},
"rooms": {
"join": {},
"invite": {},
"leave": {}
}
}
Client-initiated operations
---------------------------
The client can perform certain operations by sending a websocket message to
the server. Such a "Request" message should be a JSON-encoded object with
the following members:
============= ========== ===================================================
Key Type Description
============= ========== ===================================================
id string A unique identifier for this request
method string Specifies the name of the operation to be
performed; see below for available operations
param object The parameters for the requested operation.
============= ========== ===================================================
The server responds to a client Request with a Response message. This is a
JSON-encoded object with the following members:
============= ========== ===================================================
Key Type Description
============= ========== ===================================================
id string The same as the value in the corresponding Request
object. The presence of the ``id`` field
distinguishes a Response message from an Update
notification.
result object On success, the results of the request.
error object On error, an object giving the resons for the
error. This has the same structure as the "standard
error response" for the Matrix API: an object with
the fields ``errcode`` and ``error``.
============= ========== ===================================================
Request methods
~~~~~~~~~~~~~~~
It is not intended that all operations which are available via the REST API
will be available via the WebSockets API, but a few simple, common operations
will be exposed. The initial operations will be as follows.
``ping``
^^^^^^^^
This is a no-op which clients may use to keep their connection alive.
The request ``params`` and the response ``result`` should be empty.
``send``
^^^^^^^^
Send a message event to a room. The parameters are as follows:
============= ========== ===================================================
Parameter Type Description
============= ========== ===================================================
room_id string **Required.** The room to send the event to
event_type string **Required.** The type of event to send.
content object **Required.** The content of the event.
============= ========== ===================================================
The result is as follows:
============= ========== ===================================================
Key Type Description
============= ========== ===================================================
event_id string A unique identifier for the event.
============= ========== ===================================================
The ``id`` from the Request message is used as the transaction ID by the
server.
``state``
^^^^^^^^^
Update the state on a room.
============= ========== ===================================================
Parameter Type Description
============= ========== ===================================================
room_id string **Required.** The room to set the state in
event_type string **Required.** The type of event to send.
state_key string **Required.** The state_key for the state to send.
content object **Required.** The content of the event.
============= ========== ===================================================
The result is as follows:
============= ========== ===================================================
Key Type Description
============= ========== ===================================================
event_id string A unique identifier for the event.
============= ========== ===================================================
Example
~~~~~~~
Client request:
.. code:: json
{
"id": "12345",
"method": "send",
"params": {
"room_id": "!d41d8cd:matrix.org",
"event_type": "m.room.message",
"content": {
"msgtype": "m.text",
"body": "hello"
}
}
}
Server response:
.. code:: json
{
"id": "12345",
"result": {
"event_id": "$66697273743031:matrix.org"
}
}
Alternative server response, in case of error:
.. code:: json
{
"id": "12345",
"error": {
"errcode": "M_MISSING_PARAM",
"error": "Missing parameter: event_type"
}
}
Rationale
---------
Alternatives to WebSockets include HTTP/2, CoAP, and simply rolling our own
protocol over raw TCP sockets. However, the need to implement browser-based
clients essentially reduces our choice to WebSockets. HTTP/2 streams will
probably provide an interesting alternative in the future, but current browsers
do not appear to give javascript applications low-level access to the protocol.
Concerning the continued use of the JSON encoding: we prefer to focus on the
transition to WebSockets initially. Replacing JSON with a compact
representation such as CBOR, MessagePack, or even just compressed JSON will be
a likely extension for the future. The support for negotiation of subprotocols
within WebSockets should make this a simple transition once time permits.
The number of methods available for client requests is deliberately limited, as
each method requires code to be written to map it onto the equivalent REST
implementation. Some REST methods - for instance, user registration and login -
would be pointless to expose via WebSockets. It is likely, however, that we
will increate the number of methods available via the WebSockets API as it
becomes clear which would be most useful.
Open questions
--------------
Throttling
~~~~~~~~~~
At least in v2 sync, clients are inherently self-throttling - if they do not
poll quickly enough, events will be dropped from the next result. This proposal
raises the possibility that events will be produced more quickly than they can
be sent to the client; backlogs will build up on the server and/or in the
intermediate network, which will not only lead to high latency on events being
delivered, but will lead to responses to client requests also being delayed.
We may need to implement some sort of throttling mechanism by which the server
can start to drop events. The difficulty is in knowing when to start dropping
events. A few ideas:
* Use websocket pings to measure the RTT; if it starts to increase, start
dropping events. But this requires knowledge of the base RTT, and a useful
model of what constitutes an excessive increase.
* Have the client acknowledge each batch of events, and use a window to ensure
the number of outstanding batches is limited. This is annoying as it requires
the client to have to acknowledge batches - and it's not clear what the right
window size is: we want a big window for long fat networks (think of mobile
clients), but a small one for one with lower latency.
* Start dropping events if the server's TCP buffer starts filling up. This has
the advantage of delegating the congestion-detection to TCP (which already
has a number of algorithms to deal with it, to greater or lesser
effectiveness), but relies on homeservers being hosted on OSes which use
sensible TCP congestion-avoidance algorithms, and more critically, an ability
to read the fill level of the TCP send buffer.

@ -7,7 +7,7 @@ resolved correctly. For basic CLI testing, we recommend and have verified they
work with the Node.js package [z-schema](https://github.com/zaggino/z-schema): work with the Node.js package [z-schema](https://github.com/zaggino/z-schema):
``` ```
$ npm install -g z-schema $ npm install -g z-schema
$ z-schema schema/v1/m.room.message examples/v1/m.room.message_m.text $ z-schema schema/m.room.message examples/m.room.message_m.text
schema validation passed schema validation passed
json #1 validation passed json #1 validation passed
``` ```

@ -1,22 +0,0 @@
#!/bin/bash -e
# Runs z-schema over all of the schema files (looking for matching examples)
if ! which z-schema; then
echo >&2 "Need to install z-schema; run: sudo npm install -g z-schema"
exit 1
fi
find schema/v1/m.* | while read line
do
split_path=(${line///// })
event_type=(${split_path[2]})
echo "Checking $event_type"
echo "--------------------"
# match exact name or exact name with a #<something>
find examples/v1 -name $event_type -o -name "$event_type#*" | while read exline
do
echo " against $exline"
# run z-schema: because of bash -e if this fails we bail with exit code 1
z-schema schema/v1/$event_type $exline
done
done

@ -1,4 +1,4 @@
#! /usr/bin/env python #!/usr/bin/env python
import sys import sys
import json import json
@ -60,6 +60,8 @@ def check_example_dir(exampledir, schemadir):
continue continue
examplepath = os.path.join(root, filename) examplepath = os.path.join(root, filename)
schemapath = examplepath.replace(exampledir, schemadir) schemapath = examplepath.replace(exampledir, schemadir)
if schemapath.find("#") >= 0:
schemapath = schemapath[:schemapath.find("#")]
try: try:
check_example_file(examplepath, schemapath) check_example_file(examplepath, schemapath)
except Exception as e: except Exception as e:

@ -0,0 +1,30 @@
{
"age": 242352,
"content": {
"membership": "join",
"avatar_url": "mxc://localhost/SEsfnsuifSDFSSEF#auto",
"displayname": "Alice Margatroid"
},
"invite_room_state": [
{
"type": "m.room.name",
"state_key": "",
"content": {
"name": "Forest of Magic"
}
},
{
"type": "m.room.join_rules",
"state_key": "",
"content": {
"join_rules": "invite"
}
}
],
"state_key": "@alice:localhost",
"origin_server_ts": 1431961217939,
"event_id": "$WLGTSEFSEF:localhost",
"type": "m.room.member",
"room_id": "!Cuyf34gef24t:localhost",
"user_id": "@example:localhost"
}

@ -0,0 +1,25 @@
{
"age": 242352,
"content": {
"membership": "join",
"avatar_url": "mxc://localhost/SEsfnsuifSDFSSEF#auto",
"displayname": "Alice Margatroid",
"third_party_invite": {
"signed": {
"mxid": "@alice:localhost",
"signatures": {
"magic.forest": {
"ed25519:3": "fQpGIW1Snz+pwLZu6sTy2aHy/DYWWTspTJRPyNp0PKkymfIsNffysMl6ObMMFdIJhk6g6pwlIqZ54rxo8SLmAg"
}
},
"token": "abc123"
}
}
},
"state_key": "@alice:localhost",
"origin_server_ts": 1431961217939,
"event_id": "$WLGTSEFSEF:localhost",
"type": "m.room.member",
"room_id": "!Cuyf34gef24t:localhost",
"user_id": "@example:localhost"
}

@ -0,0 +1,8 @@
{
"type": "m.tag",
"content": {
"tags": {
"work": {"order": 1}
}
}
}

@ -3,7 +3,7 @@
"title": "Room Event", "title": "Room Event",
"description": "In addition to the Event fields, Room Events MUST have the following additional field.", "description": "In addition to the Event fields, Room Events MUST have the following additional field.",
"allOf":[{ "allOf":[{
"$ref": "core-event-schema/event.json" "$ref": "event.json"
}], }],
"properties": { "properties": {
"room_id": { "room_id": {

@ -3,7 +3,7 @@
"title": "State Event", "title": "State Event",
"description": "In addition to the Room Event fields, State Events have the following additional fields.", "description": "In addition to the Room Event fields, State Events have the following additional fields.",
"allOf":[{ "allOf":[{
"$ref": "core-event-schema/room_event.json" "$ref": "room_event.json"
}], }],
"properties": { "properties": {
"state_key": { "state_key": {

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

Loading…
Cancel
Save