You're looking at an unstable version of this specification. Unstable specifications may change at any time without notice.
Client-Server API
The client-server API allows clients to send messages, control rooms and synchronise conversation history. It is designed to support both lightweight clients which store no state and lazy-load data from the server as required, as well as heavyweight clients which maintain a full local persistent copy of server state.
List of Endpoints
- GET /.well-known/matrix/client
- GET /.well-known/matrix/support
- GET /.well-known/matrix/policy_server
- GET /_matrix/client/versions
- GET /_matrix/client/v1/register/m.login.registration_token/validity
- GET /_matrix/client/v3/login
- POST /_matrix/client/v3/login
- POST /_matrix/client/v1/login/get_token
- POST /_matrix/client/v3/refresh
- POST /_matrix/client/v3/logout
- POST /_matrix/client/v3/logout/all
- POST /_matrix/client/v3/register
- GET /_matrix/client/v3/register/available
- POST /_matrix/client/v3/register/email/requestToken
- POST /_matrix/client/v3/register/msisdn/requestToken
- POST /_matrix/client/v3/account/password
- POST /_matrix/client/v3/account/password/email/requestToken
- POST /_matrix/client/v3/account/password/msisdn/requestToken
- POST /_matrix/client/v3/account/deactivate
- GET /_matrix/client/v1/auth_metadata
- GET /_matrix/client/v3/account/3pid
- POST /_matrix/client/v3/account/3pid (deprecated)
- POST /_matrix/client/v3/account/3pid/add
- POST /_matrix/client/v3/account/3pid/bind
- POST /_matrix/client/v3/account/3pid/delete
- POST /_matrix/client/v3/account/3pid/email/requestToken
- POST /_matrix/client/v3/account/3pid/msisdn/requestToken
- POST /_matrix/client/v3/account/3pid/unbind
- GET /_matrix/client/v3/account/whoami
- GET /_matrix/client/v3/capabilities
- POST /_matrix/client/v3/user/{userId}/filter
- GET /_matrix/client/v3/user/{userId}/filter/{filterId}
- GET /_matrix/client/v3/sync
- GET /_matrix/client/v3/events (deprecated)
- GET /_matrix/client/v3/events/{eventId} (deprecated)
- GET /_matrix/client/v3/initialSync (deprecated)
- GET /_matrix/client/v3/rooms/{roomId}/event/{eventId}
- GET /_matrix/client/v3/rooms/{roomId}/joined_members
- GET /_matrix/client/v3/rooms/{roomId}/members
- GET /_matrix/client/v3/rooms/{roomId}/state
- GET /_matrix/client/v3/rooms/{roomId}/state/{eventType}/{stateKey}
- GET /_matrix/client/v3/rooms/{roomId}/messages
- GET /_matrix/client/v1/rooms/{roomId}/timestamp_to_event
- GET /_matrix/client/v3/rooms/{roomId}/initialSync
- PUT /_matrix/client/v3/rooms/{roomId}/state/{eventType}/{stateKey}
- PUT /_matrix/client/v3/rooms/{roomId}/send/{eventType}/{txnId}
- PUT /_matrix/client/v3/rooms/{roomId}/redact/{eventId}/{txnId}
- GET /_matrix/client/v1/rooms/{roomId}/relations/{eventId}
- GET /_matrix/client/v1/rooms/{roomId}/relations/{eventId}/{relType}
- GET /_matrix/client/v1/rooms/{roomId}/relations/{eventId}/{relType}/{eventType}
- POST /_matrix/client/v3/createRoom
- GET /_matrix/client/v3/directory/room/{roomAlias}
- PUT /_matrix/client/v3/directory/room/{roomAlias}
- DELETE /_matrix/client/v3/directory/room/{roomAlias}
- GET /_matrix/client/v3/rooms/{roomId}/aliases
- GET /_matrix/client/v3/joined_rooms
- POST /_matrix/client/v3/rooms/{roomId}/invite
- POST /_matrix/client/v3/join/{roomIdOrAlias}
- POST /_matrix/client/v3/rooms/{roomId}/join
- POST /_matrix/client/v3/knock/{roomIdOrAlias}
- POST /_matrix/client/v3/rooms/{roomId}/forget
- POST /_matrix/client/v3/rooms/{roomId}/leave
- POST /_matrix/client/v3/rooms/{roomId}/kick
- POST /_matrix/client/v3/rooms/{roomId}/ban
- POST /_matrix/client/v3/rooms/{roomId}/unban
- GET /_matrix/client/v3/directory/list/room/{roomId}
- PUT /_matrix/client/v3/directory/list/room/{roomId}
- GET /_matrix/client/v3/publicRooms
- POST /_matrix/client/v3/publicRooms
- GET /_matrix/client/v1/room_summary/{roomIdOrAlias}
- POST /_matrix/client/v3/user_directory/search
- GET /_matrix/client/v3/profile/{userId}
- GET /_matrix/client/v3/profile/{userId}/{keyName}
- PUT /_matrix/client/v3/profile/{userId}/{keyName}
- DELETE /_matrix/client/v3/profile/{userId}/{keyName}
- GET /_matrix/client/v1/media/config
- GET /_matrix/client/v1/media/download/{serverName}/{mediaId}
- GET /_matrix/client/v1/media/download/{serverName}/{mediaId}/{fileName}
- GET /_matrix/client/v1/media/preview_url
- GET /_matrix/client/v1/media/thumbnail/{serverName}/{mediaId}
- POST /_matrix/media/v1/create
- GET /_matrix/media/v3/config (deprecated)
- GET /_matrix/media/v3/download/{serverName}/{mediaId} (deprecated)
- GET /_matrix/media/v3/download/{serverName}/{mediaId}/{fileName} (deprecated)
- GET /_matrix/media/v3/preview_url (deprecated)
- GET /_matrix/media/v3/thumbnail/{serverName}/{mediaId} (deprecated)
- POST /_matrix/media/v3/upload
- PUT /_matrix/media/v3/upload/{serverName}/{mediaId}
- POST /_matrix/client/v3/keys/device_signing/upload
- POST /_matrix/client/v3/keys/signatures/upload
- GET /_matrix/client/v3/room_keys/keys
- PUT /_matrix/client/v3/room_keys/keys
- DELETE /_matrix/client/v3/room_keys/keys
- GET /_matrix/client/v3/room_keys/keys/{roomId}
- PUT /_matrix/client/v3/room_keys/keys/{roomId}
- DELETE /_matrix/client/v3/room_keys/keys/{roomId}
- GET /_matrix/client/v3/room_keys/keys/{roomId}/{sessionId}
- PUT /_matrix/client/v3/room_keys/keys/{roomId}/{sessionId}
- DELETE /_matrix/client/v3/room_keys/keys/{roomId}/{sessionId}
- GET /_matrix/client/v3/room_keys/version
- POST /_matrix/client/v3/room_keys/version
- GET /_matrix/client/v3/room_keys/version/{version}
- PUT /_matrix/client/v3/room_keys/version/{version}
- DELETE /_matrix/client/v3/room_keys/version/{version}
- GET /_matrix/client/v3/keys/changes
- POST /_matrix/client/v3/keys/claim
- POST /_matrix/client/v3/keys/query
- POST /_matrix/client/v3/keys/upload
- GET /_matrix/client/v3/pushrules/
- GET /_matrix/client/v3/pushrules/global/
- GET /_matrix/client/v3/pushrules/global/{kind}/{ruleId}
- PUT /_matrix/client/v3/pushrules/global/{kind}/{ruleId}
- DELETE /_matrix/client/v3/pushrules/global/{kind}/{ruleId}
- GET /_matrix/client/v3/pushrules/global/{kind}/{ruleId}/actions
- PUT /_matrix/client/v3/pushrules/global/{kind}/{ruleId}/actions
- GET /_matrix/client/v3/pushrules/global/{kind}/{ruleId}/enabled
- PUT /_matrix/client/v3/pushrules/global/{kind}/{ruleId}/enabled
- GET /_matrix/client/v3/pushers
- POST /_matrix/client/v3/pushers/set
- GET /_matrix/client/v3/notifications
API Standards
These standards only apply to the APIs defined in the Matrix specification. APIs used by this specification but defined in other specifications, like the OAuth 2.0 API, use their own rules.
The mandatory baseline for client-server communication in Matrix is exchanging JSON objects over HTTP APIs. More efficient transports may be specified in future as optional extensions.
HTTPS is recommended for communication. The use of plain HTTP is not recommended outside test environments.
Clients are authenticated using opaque access_token strings (see Client
Authentication for details).
All POST and PUT endpoints, with the exception of those listed below,
require the client to supply a request body containing a (potentially empty)
JSON object. Clients should supply a Content-Type header of
application/json for all requests with JSON bodies, but this is not required.
The exceptions are:
POST /_matrix/media/v3/uploadandPUT /_matrix/media/v3/upload/{serverName}/{mediaId}, both of which take the uploaded media as the request body.POST /_matrix/client/v3/logoutandPOST /_matrix/client/v3/logout/all, which take an empty request body.
Similarly, all endpoints require the server to return a JSON object,
with the exception of 200 responses to the media download endpoints in the
Content Repository module.
Servers must include a Content-Type header of application/json for all JSON responses.
All JSON data, in requests or responses, must be encoded using UTF-8.
See also Conventions for Matrix APIs in the Appendices for conventions which all Matrix APIs are expected to follow, and Web Browser Clients below for additional requirements for server responses.
Standard error response
Any errors which occur at the Matrix API level MUST return a “standard error response”. This is a JSON object which looks like:
{
"errcode": "<error code>",
"error": "<error message>"
}
The error string will be a human-readable error message, usually a
sentence explaining what went wrong.
The errcode string will be a unique string which can be used to handle an
error message e.g. M_FORBIDDEN. Error codes should have their namespace
first in ALL CAPS, followed by a single _. For example, if there was a custom
namespace com.mydomain.here, and a FORBIDDEN code, the error code should
look like COM.MYDOMAIN.HERE_FORBIDDEN. Error codes defined by this
specification should start with M_.
Some errcodes define additional keys which should be present in the error
response object, but the keys error and errcode MUST always be present.
Errors are generally best expressed by their error code rather than the
HTTP status code returned. When encountering the error code M_UNKNOWN,
clients should prefer the HTTP status code as a more reliable reference
for what the issue was. For example, if the client receives an error
code of M_NOT_FOUND but the request gave a 400 Bad Request status
code, the client should treat the error as if the resource was not
found. However, if the client were to receive an error code of
M_UNKNOWN with a 400 Bad Request, the client should assume that the
request being made was invalid.
Common error codes
These error codes can be returned by any API endpoint:
M_BAD_JSON- Request contained valid JSON, but it was malformed in some way, e.g. missing required keys, invalid values for keys.
M_FORBIDDEN- Forbidden access, e.g. joining a room without permission, failed login.
M_LIMIT_EXCEEDED- Too many requests have been sent in a short period of time. Wait a while then try again. See Rate limiting.
M_MISSING_TOKEN- No access token was specified for the request.
M_NOT_FOUND- No resource was found for this request.
M_NOT_JSON- Request did not contain valid JSON.
M_RESOURCE_LIMIT_EXCEEDED- The request cannot be completed because the homeserver has reached a
resource limit imposed on it. For example, a homeserver held in a shared
hosting environment may reach a resource limit if it starts using too
much memory or disk space. The error MUST have an
admin_contactfield to provide the user receiving the error a place to reach out to. Typically, this error will appear on routes which attempt to modify state (e.g.: sending messages, account data, etc) and not routes which only read state (e.g.:/sync,/user/{userId}/account_data/{type}, etc). M_UNKNOWN- An unknown error has occurred.
M_UNKNOWN_DEVICE- [Added in
v1.17] The device ID supplied by the application service does not belong to the user ID during identity assertion. M_UNKNOWN_TOKEN- The access or refresh token specified was not recognised.
-
An additional response parameter,
soft_logout, might be present on the response for 401 HTTP status codes. See the soft logout section for more information. M_UNRECOGNIZED- The server did not understand the request. This is expected to be returned with a 404 HTTP status code if the endpoint is not implemented or a 405 HTTP status code if the endpoint is implemented, but the incorrect HTTP method is used.
M_USER_LIMIT_EXCEEDED- [Added in
v1.18] The request cannot be completed because the user has exceeded (or the request would cause them to exceed) a limit associated with their account. For example, a user may have reached their allocated storage quota, reached a maximum number of allowed rooms, devices, or other account-scoped resources, or exceeded usage limits for specific features. -
The error response MUST have an
info_urifield (string), which is a URI that the client can present to the user to provide more context on the encountered limit and, if applicable, guidance on how to increase the limit. The homeserver MAY return different values forinfo_uridepending on the type of limit reached. -
The error response MAY include a
can_upgradefield (boolean, defaultfalse). Iftrue, it indicates that the specific limit encountered can be increased, for example by upgrading the user’s account tier. If absent orfalse, the limit is a hard limit that cannot be increased. -
The HTTP status code will depend on depend on the particular endpoint.
-
Example response:
{ "errcode": "M_USER_LIMIT_EXCEEDED", "error": "You have exceeded your storage quota of 10GB", "info_uri": "https://example.com/homeserver/about?limit_type=quota", "can_upgrade": true } M_USER_LOCKED- The account has been locked and cannot be used at this time.
M_USER_SUSPENDED- The account has been suspended and can only be used for limited actions at this time.
Other error codes
The following error codes are specific to certain endpoints.
M_BAD_STATE- The state change requested cannot be performed, such as attempting to unban a user who is not banned.
M_CANNOT_LEAVE_SERVER_NOTICE_ROOM- The user is unable to reject an invite to join the server notices room. See the Server Notices module for more information.
M_CAPTCHA_INVALID- The Captcha provided did not match what was expected.
M_CAPTCHA_NEEDED- A Captcha is required to complete the request.
M_EXCLUSIVE- The resource being requested is reserved by an application service, or the application service making the request has not created the resource.
M_GUEST_ACCESS_FORBIDDEN- The room or resource does not permit guests to access it.
M_INCOMPATIBLE_ROOM_VERSION- The client attempted to join a room that has a version the server does
not support. Inspect the
room_versionproperty of the error response for the room’s version. M_INVALID_PARAM- A parameter that was specified has the wrong value. For example, the server expected an integer and instead received a string.
M_INVALID_ROOM_STATE- Sent when the initial state given to the
createRoomAPI is invalid. M_INVALID_USERNAME- Encountered when trying to register a user ID which is not valid.
M_MISSING_PARAM- A required parameter was missing from the request.
M_ROOM_IN_USE- Sent when the room alias given to the
createRoomAPI is already in use. M_SERVER_NOT_TRUSTED- The client’s request used a third-party server, e.g. identity server, that this server does not trust.
M_THREEPID_AUTH_FAILED- Authentication could not be performed on the third-party identifier.
M_THREEPID_DENIED- The server does not permit this third-party identifier. This may happen if the server only permits, for example, email addresses from a particular domain.
M_THREEPID_IN_USE- The third party identifier specified by the client is not acceptable because it is already in use in some way.
M_THREEPID_MEDIUM_NOT_SUPPORTED- The homeserver does not support adding a third party identifier of the given medium.
M_THREEPID_NOT_FOUND- Sent when a threepid given to an API cannot be used because no record matching the threepid was found.
M_TOO_LARGE- The request or entity was too large.
M_UNAUTHORIZED- The request was not correctly authorized. Usually due to login failures.
M_UNSUPPORTED_ROOM_VERSION- The client’s request to create a room used a room version that the server does not support.
M_USER_DEACTIVATED- The user ID associated with the request has been deactivated. Typically
for endpoints that prove authentication, such as
/login. M_USER_IN_USE- Encountered when trying to register a user ID which has been taken.
Rate limiting
Homeservers SHOULD implement rate limiting to reduce the risk of being overloaded. If a request is refused due to rate limiting, it should return a standard error response of the form:
{
"errcode": "M_LIMIT_EXCEEDED",
"error": "string",
"retry_after_ms": integer (optional, deprecated)
}
Homeservers SHOULD include a Retry-After
header for any response with a 429 status code.
The retry_after_ms property MAY be included to tell the client how long
they have to wait in milliseconds before they can try again. This property is
deprecated, in favour of the Retry-After header.
[Changed in v1.10]: retry_after_ms property deprecated in favour of Retry-After header.
Transaction identifiers
The client-server API typically uses HTTP PUT to submit requests with
a client-generated transaction identifier in the HTTP path.
The purpose of the transaction ID is to allow the homeserver to distinguish a new request from a retransmission of a previous request so that it can make the request idempotent.
The transaction ID should only be used for this purpose.
After the request has finished, clients should change the {txnId} value for
the next request. How this is achieved, is left as an implementation detail.
It is recommended that clients use either version 4 UUIDs or a concatenation
of the current timestamp and a monotonically increasing integer.
The homeserver should identify a request as a retransmission if the transaction ID is the same as a previous request, and the path of the HTTP request is the same.
Where a retransmission has been identified, the homeserver should return
the same HTTP response code and content as the original request.
For example, PUT /_matrix/client/v3/rooms/{roomId}/send/{eventType}/{txnId}
would return a 200 OK with the event_id of the original request in
the response body.
The scope of a transaction ID is for a single device,
and a single HTTP endpoint. In other words: a single device could use the same
transaction ID for a request to PUT /_matrix/client/v3/rooms/{roomId}/send/{eventType}/{txnId}
and PUT /_matrix/client/v3/sendToDevice/{eventType}/{txnId},
and the two requests would be considered distinct because the two are
considered separate endpoints. Similarly, if a client logs out and back in
between two requests using the same transaction ID, the requests are distinct
because the act of logging in and out creates a new device (unless an existing
device_id is given during the login process). On the other hand, if
a client re-uses a transaction ID for the same endpoint after
refreshing an access token, it will be assumed to
be a duplicate request and ignored. See also
Relationship between access tokens and devices.
Some API endpoints may allow or require the use of POST requests
without a transaction ID. Where this is optional, the use of a PUT
request is strongly recommended.
Prior to v1.7, transaction IDs were scoped to “client sessions” rather than
devices.
Web Browser Clients
It is realistic to expect that some clients will be written to be run within a web browser or similar environment. In these cases, the homeserver should respond to pre-flight requests and supply Cross-Origin Resource Sharing (CORS) headers on all requests.
Servers MUST expect that clients will approach them with OPTIONS
requests, allowing clients to discover the CORS headers. All endpoints
in this specification support the OPTIONS method, however the server
MUST NOT perform any logic defined for the endpoints when approached
with an OPTIONS request.
When a client approaches the server with a request, the server should respond with the CORS headers for that route. The recommended CORS headers to be returned by servers on all requests are:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: X-Requested-With, Content-Type, Authorization
[Added in v1.13] The recommended value of the Access-Control-Allow-Methods
header only covers the existing endpoints in the specification. Servers which
support additional endpoints or methods should add those methods as well.
This section will be updated whenever a new method is supported by an endpoint.
Examples of possible future-use methods include PATCH and HEAD.
Server Discovery
In order to allow users to connect to a Matrix server without needing to explicitly specify the homeserver’s URL or other parameters, clients SHOULD use an auto-discovery mechanism to determine the server’s URL based on a user’s Matrix ID. Auto-discovery should only be done at login time.
In this section, the following terms are used with specific meanings:
PROMPT
Retrieve the specific piece of information from the user in a way which
fits within the existing client user experience, if the client is
inclined to do so. Failure can take place instead if no good user
experience for this is possible at this point.
IGNORE
Stop the current auto-discovery mechanism. If no more auto-discovery
mechanisms are available, then the client may use other methods of
determining the required parameters, such as prompting the user, or
using default values.
FAIL_PROMPT
Inform the user that auto-discovery failed due to invalid/empty data and
PROMPT for the parameter.
FAIL_ERROR
Inform the user that auto-discovery did not return any usable URLs. Do
not continue further with the current login process. At this point,
valid data was obtained, but no server is available to serve the client.
No further guess should be attempted and the user should make a
conscientious decision what to do next.
Well-known URIs
Matrix facilitates automatic discovery for the Client-Server API base URL and more via the
RFC 8615 “Well-Known URI” method.
This method uses JSON files at a predetermined location on the root path /.well-known/ to
specify parameter values.
Diverging from the rest of the endpoints in the Client-Server spec, these files can not be provided on the base URL that the Client-Server API is reachable on, as it is yet to be discovered. Instead, they can be reached via HTTPS on the server name’s hostname as domain.
Servers hosting the .well-known JSON file SHOULD offer CORS headers,
as per the CORS section in this specification.
The flow for auto-discovery is as follows:
- Extract the server name from the user’s Matrix ID by splitting the Matrix ID at the first colon.
- Extract the hostname from the server name as described by the grammar.
- Make a GET request to
https://hostname/.well-known/matrix/client.- If the returned status code is 404, then
IGNORE. - If the returned status code is not 200, or the response body is
empty, then
FAIL_PROMPT. - Parse the response body as a JSON object
- If the content cannot be parsed, then
FAIL_PROMPT.
- If the content cannot be parsed, then
- Extract the
base_urlvalue from them.homeserverproperty. This value is to be used as the base URL of the homeserver.- If this value is not provided, then
FAIL_PROMPT.
- If this value is not provided, then
- Validate the homeserver base URL:
- Parse it as a URL. If it is not a URL, then
FAIL_ERROR. - Clients SHOULD validate that the URL points to a valid
homeserver before accepting it by connecting to the
/_matrix/client/versionsendpoint, ensuring that it does not return an error, and parsing and validating that the data conforms with the expected response format. If any step in the validation fails, thenFAIL_ERROR. Validation is done as a simple check against configuration errors, in order to ensure that the discovered address points to a valid homeserver. - It is important to note that the
base_urlvalue might include a trailing/. Consumers should be prepared to handle both cases.
- Parse it as a URL. If it is not a URL, then
- If the
m.identity_serverproperty is present, extract thebase_urlvalue for use as the base URL of the identity server. Validation for this URL is done as in the step above, but using/_matrix/identity/v2as the endpoint to connect to. If them.identity_serverproperty is present, but does not have abase_urlvalue, thenFAIL_PROMPT.
- If the returned status code is 404, then
GET
/.well-known/matrix/client
Gets discovery information about the domain. The file may include
additional keys, which MUST follow the Java package naming convention,
e.g. com.example.myapp.property. This ensures property names are
suitably namespaced for each application and reduces the risk of
clashes.
This endpoint should be accessed with the hostname of the homeserver’s
server name by making a
GET request to https://hostname/.well-known/matrix/client.
Note that this endpoint is not necessarily handled by the homeserver, but by another webserver, to be used for discovering the homeserver URL.
| Rate-limited: | No |
|---|---|
| Requires authentication: | No |
Request
No request parameters or request body.
Responses
| Status | Description |
|---|---|
200 |
Server discovery information. |
404 |
No server discovery information available. |
200 response
| Name | Type | Description |
|---|---|---|
m.homeserver |
Homeserver Information |
Required: Used by clients to discover homeserver information. |
m.identity_server |
Identity Server Information |
Used by clients to discover identity server information. |
| <Other properties> | |
Application-dependent keys using Java package naming convention. |
| Name | Type | Description |
|---|---|---|
base_url |
URI |
Required: The base URL for the homeserver for client-server connections. |
| Name | Type | Description |
|---|---|---|
base_url |
URI |
Required: The base URL for the identity server for client-server connections. |
{
"m.homeserver": {
"base_url": "https://matrix.example.com"
},
"m.identity_server": {
"base_url": "https://identity.example.com"
},
"org.example.custom.property": {
"app_url": "https://custom.app.example.org"
}
}
GET
/.well-known/matrix/support
Added in v1.10
Gets server admin contact and support page of the domain.
Like the well-known discovery URI,
this endpoint should be accessed with the hostname of the homeserver’s
server name by making a
GET request to https://hostname/.well-known/matrix/support.
Note that this endpoint is not necessarily handled by the homeserver. It may be served by another webserver, used for discovering support information for the homeserver.
| Rate-limited: | No |
|---|---|
| Requires authentication: | No |
Request
No request parameters or request body.
Responses
| Status | Description |
|---|---|
200 |
Server support information. |
404 |
No server support information available. |
200 response
| Name | Type | Description |
|---|---|---|
contacts |
[Contact] |
Ways to contact the server administrator. At least one of |
support_page |
URI |
The URL of a page to give users help specific to the homeserver, like extra login/registration steps. At least one of |
| Name | Type | Description |
|---|---|---|
email_address |
Email Address |
An email address to reach the administrator. At least one of |
matrix_id |
User ID |
A Matrix User ID representing the administrator. It could be an account registered on a different homeserver so the administrator can be contacted when the homeserver is down. At least one of |
role |
string |
Required: An informal description of what the contact methods are used for.
Unspecified roles are permitted through the use of Namespaced Identifiers. One of: |
{
"contacts": [
{
"email_address": "[email protected]",
"matrix_id": "@admin:example.org",
"role": "m.role.admin"
},
{
"email_address": "[email protected]",
"role": "m.role.security"
}
],
"support_page": "https://example.org/support.html"
}
GET
/.well-known/matrix/policy_server
Added in v1.18
Gets public key information for a Policy Server.
Like the well-known discovery URI,
this endpoint should be accessed with the hostname of the Policy Server’s
server name by making a
GET request to https://hostname/.well-known/matrix/policy_server.
Note that this endpoint is not necessarily handled by the homeserver or Policy Server. It may be served by another webserver.
| Rate-limited: | No |
|---|---|
| Requires authentication: | No |
Request
No request parameters or request body.
Responses
| Status | Description |
|---|---|
200 |
Public keys for the Policy Server. Can be supplied to the m.room.policy
state event. |
404 |
No policy server information available. |
200 response
| Name | Type | Description |
|---|---|---|
public_keys |
object |
Required: The unpadded base64-encoded public keys for the Policy Server. MUST contain
at least |
| Name | Type | Description |
|---|---|---|
ed25519 |
string |
Required: The unpadded base64-encoded ed25519 public key for the Policy Server. |
| <Other properties> | string |
The unpadded base64-encoded public key for the key algorithm. |
{
"public_keys": {
"ed25519": "6yhHGKhCiXTSEN2ksjV7kX_N6rBQZ3Xb-M7LlC6NS-s"
}
}
API Versions
Upon connecting, the Matrix client and server need to negotiate which version of the specification they commonly support, as the API evolves over time. The server advertises its supported versions and optionally unstable features to the client, which can then go on to make requests to the endpoints it supports.
GET
/_matrix/client/versions
Changed in v1.10: This endpoint can behave differently when authentication is provided.
Gets the versions of the specification supported by the server.
Values will take the form vX.Y or rX.Y.Z in historical cases. See
the Specification Versioning for more
information.
The server may additionally advertise experimental features it supports
through unstable_features. These features should be namespaced and
may optionally include version information within their name if desired.
Features listed here are not for optionally toggling parts of the Matrix
specification and should only be used to advertise support for a feature
which has not yet landed in the spec. For example, a feature currently
undergoing the proposal process may appear here and eventually be taken
off this list once the feature lands in the spec and the server deems it
reasonable to do so. Servers can choose to enable some features only for
some users, so clients should include authentication in the request to
get all the features available for the logged-in user. If no
authentication is provided, the server should only return the features
available to all users. Servers may wish to keep advertising features
here after they’ve been released into the spec to give clients a chance
to upgrade appropriately. Additionally, clients should avoid using
unstable features in their stable releases.
| Rate-limited: | No |
|---|---|
| Requires authentication: | Optional |
Request
No request parameters or request body.
Responses
| Status | Description |
|---|---|
200 |
The versions supported by the server. |
200 response
| Name | Type | Description |
|---|---|---|
unstable_features |
{string: boolean} |
Experimental features the server supports. Features not listed here, or the lack of this property all together, indicate that a feature is not supported. |
versions |
[string] |
Required: The supported versions. |
{
"unstable_features": {
"org.example.my_feature": true
},
"versions": [
"r0.0.1",
"v1.1"
]
}
Client Authentication
[Changed in v1.15] OAuth 2.0 API added to the specification.
Most API endpoints require the user to identify themselves by presenting previously obtained credentials in the form of an access token. An access token is typically obtained via the Login or Registration processes. Access tokens can expire; a new access token can be generated by using a refresh token.
This specification does not mandate a particular format for the access token. Clients should treat it as an opaque byte sequence. Servers are free to choose an appropriate format. Server implementors may like to investigate macaroons.
Since Matrix 1.15, the Client-Server specification supports two authentication APIs:
- The legacy API
- The OAuth 2.0 API
The legacy API has existed since the first version of the Matrix specification, while the OAuth 2.0 API has been introduced to rely on a industry standard and its experience rather than implementing a custom protocol that might not follow the best practices.
A homeserver may support one of those two APIs, or both. The two APIs are mutually incompatible, which means that after logging in, clients MUST only use the API that was used to obtain their current access token.
Currently the OAuth 2.0 API doesn’t cover all the use cases of the legacy API, such as automated applications that cannot use a web browser.
[Added in v1.18]
A compatibility feature, called OAuth 2.0 aware clients,
is available to ease the transition to the OAuth 2.0 API for clients that only
support the legacy API.
Authentication API discovery
To discover if a homeserver supports the legacy API, the GET /login
endpoint can be used.
To discover if a homeserver supports the OAuth 2.0 API, the
GET /auth_metadata endpoint can be used.
In both cases, the server SHOULD respond with 404 and an M_UNRECOGNIZED error
code if the corresponding API is not supported.
Account registration
With the legacy API, a client can register a new account with the
/register endpoint.
With the OAuth 2.0 API, a client can’t register a new account directly. The end
user must do that directly in the homeserver’s web UI. However, the client can
signal to the homeserver that the user wishes to create a new account with the
prompt=create parameter during authorization.
[Added in v1.17]
Application services can use the /register endpoint to create users regardless
of the authentication API supported by the homeserver.
Login
With the legacy API, a client can obtain an access token by using one of the
login methods supported by the homeserver at the POST /login
endpoint. To invalidate the access token the client must call the /logout
endpoint.
With the OAuth 2.0 API, a client can obtain an access token by using one of the grant types supported by the homeserver and authorizing the proper scope, as demonstrated in the login flows. To invalidate the access token the client must use token revocation.
Using access tokens
Access tokens may be provided via a request header, using the Authentication
Bearer scheme: Authorization: Bearer TheTokenHere.
Clients may alternatively provide the access token via a query string parameter:
access_token=TheTokenHere. This method is deprecated to prevent the access
token being leaked in access/HTTP logs and SHOULD NOT be used by clients.
Homeservers MUST support both methods.
[Changed in v1.11]
Sending the access token as a query string parameter is now deprecated.
When credentials are required but missing or invalid, the HTTP call will
return with a status of 401 and the error code, M_MISSING_TOKEN or
M_UNKNOWN_TOKEN respectively. Note that an error code of M_UNKNOWN_TOKEN
could mean one of four things:
- the access token was never valid.
- the access token has been logged out.
- the access token has been soft logged out.
- [Added in
v1.3] the access token needs to be refreshed.
When a client receives an error code of M_UNKNOWN_TOKEN, it should:
- attempt to refresh the token, if it has a refresh token;
- if
soft_logoutis set totrue, it can offer to re-log in the user, retaining any of the client’s persisted information; - otherwise, consider the user as having been logged out.
Relationship between access tokens and devices
Client devices are closely related to access tokens and refresh tokens. Matrix servers should record which device each access token and refresh token are assigned to, so that subsequent requests can be handled correctly. When a refresh token is used to generate a new access token and refresh token, the new access and refresh tokens are now bound to the device associated with the initial refresh token.
During login or registration, the generated access token should be associated
with a device_id. The legacy Login and Registration
processes auto-generate a new device_id, but a client is also free to provide
its own device_id. With the OAuth 2.0 API, the device_id is always provided
by the client. The client can generate a new device_id or, provided the user
remains the same, reuse an existing device. If the client sets the device_id,
the server will invalidate any access and refresh tokens previously assigned to
that device.
Refreshing access tokens
[Added in v1.3]
Access tokens can expire after a certain amount of time. Any HTTP calls that
use an expired access token will return with an error code M_UNKNOWN_TOKEN,
preferably with soft_logout: true. When a client receives this error and it
has a refresh token, it should attempt to refresh the access token. Clients can
also refresh their access token at any time, even if it has not yet expired. If
the token refresh succeeds, the client should use the new token for future
requests, and can re-try previously-failed requests with the new token. When an
access token is refreshed, a new refresh token may be returned; if a new refresh
token is given, the old refresh token will be invalidated, and the new refresh
token should be used when the access token needs to be refreshed.
The old refresh token remains valid until the new access token or refresh token is used, at which point the old refresh token is revoked. This ensures that if a client fails to receive or persist the new tokens, it will be able to repeat the refresh operation.
If the token refresh fails and the error response included a soft_logout: true property, then the client can treat it as a soft logout
and attempt to obtain a new access token by re-logging in. If the error
response does not include a soft_logout: true property, the client should
consider the user as being logged out.
With the legacy API, refreshing access tokens is done by calling /refresh.
Handling of clients that do not support refresh tokens is up to the homeserver;
clients indicate their support for refresh tokens by including a
refresh_token: true property in the request body of the
/login and
/register endpoints. For example, homeservers
may allow the use of non-expiring access tokens, or may expire access tokens
anyways and rely on soft logout behaviour on clients that don’t support
refreshing.
With the OAuth 2.0 API, refreshing access tokens is done with the refresh token grant type, as demonstrated in the token refresh flow. Support for refreshing access tokens is mandatory with this API.
Soft logout
A client can be in a “soft logout” state if the server requires
re-authentication before continuing, but does not want to invalidate the
client’s session. The server indicates that the client is in a soft logout
state by including a soft_logout: true parameter in an M_UNKNOWN_TOKEN
error response; the soft_logout parameter defaults to false. If the
soft_logout parameter is omitted or is false, this means the server has
destroyed the session and the client should not reuse it. That is, any
persisted state held by the client, such as encryption keys and device
information, must not be reused and must be discarded. If soft_logout is
true the client can reuse any persisted state.
[Changed in v1.3] A client that receives such a response can try to
refresh its access token, if it has a refresh
token available. If it does not have a refresh token available, or refreshing
fails with soft_logout: true, the client can acquire a new access token by
specifying the device ID it is already using to the login API.
[Changed in v1.12] A client that receives such a response together
with an M_USER_LOCKED error code, cannot obtain a new access token until
the account has been unlocked.
Account management
With the legacy API, a client can use several endpoints to allow the user to manage their account like changing their password, managing their devices or deactivating their account.
With the OAuth 2.0 API, all account management is done via the homeserver’s web UI that can be accessed by users via the account management URL.
Legacy API
This is the original authentication API that was introduced in the first version of the Client-Server specification and uses custom APIs. Contrary to the OAuth 2.0 API, account management is primarily done in the client’s interface and as such it does not usually require the end user to be redirected to a web UI in their browser.
User-Interactive Authentication API
Overview
Some API endpoints require authentication that interacts with the user. The homeserver may provide many different ways of authenticating, such as user/password auth, login via a single-sign-on server (SSO), etc. This specification does not define how homeservers should authorise their users but instead defines the standard interface which implementations should follow so that ANY client can log in to ANY homeserver.
The process takes the form of one or more ‘stages’. At each stage the client submits a set of data for a given authentication type and awaits a response from the server, which will either be a final success or a request to perform an additional stage. This exchange continues until the final success.
For each endpoint, a server offers one or more ‘flows’ that the client can use to authenticate itself. Each flow comprises a series of stages, as described above. The client is free to choose which flow it follows, however the flow’s stages must be completed in order. Failing to follow the flows in order must result in an HTTP 401 response, as defined below. When all stages in a flow are complete, authentication is complete and the API call succeeds.
User-interactive API in the REST API
In the REST API described in this specification, authentication works by
the client and server exchanging JSON dictionaries. The server indicates
what authentication data it requires via the body of an HTTP 401
response, and the client submits that authentication data via the auth
request parameter.
A client should first make a request with no auth parameter.
The homeserver returns an HTTP 401 response, with a JSON body, as follows:
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
"flows": [
{
"stages": [ "example.type.foo", "example.type.bar" ]
},
{
"stages": [ "example.type.foo", "example.type.baz" ]
}
],
"params": {
"example.type.baz": {
"example_key": "foobar"
}
},
"session": "xxxxxx"
}
In addition to the flows, this object contains some extra information:
-
params: This section contains any information that the client will need to know in order to use a given type of authentication. For each authentication type presented, that type may be present as a key in this dictionary. For example, the public part of an OAuth client ID could be given here. -
session: This is a session identifier that the client must pass back to the homeserver, if one is provided, in subsequent attempts to authenticate in the same API call.
The client then chooses a flow and attempts to complete the first stage.
It does this by resubmitting the same request with the addition of an
auth key in the object that it submits. This dictionary contains a
type key whose value is the name of the authentication type that the
client is attempting to complete. It must also contain a session key
with the value of the session key given by the homeserver, if one was
given. It also contains other keys dependent on the auth type being
attempted. For example, if the client is attempting to complete auth
type example.type.foo, it might submit something like this:
POST /_matrix/client/v3/endpoint HTTP/1.1
Content-Type: application/json
{
"a_request_parameter": "something",
"another_request_parameter": "something else",
"auth": {
"type": "example.type.foo",
"session": "xxxxxx",
"example_credential": "verypoorsharedsecret"
}
}
If the homeserver deems the authentication attempt to be successful but
still requires more stages to be completed, it returns HTTP status 401
along with the same object as when no authentication was attempted, with
the addition of the completed key which is an array of auth types the
client has completed successfully:
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
"completed": [ "example.type.foo" ],
"flows": [
{
"stages": [ "example.type.foo", "example.type.bar" ]
},
{
"stages": [ "example.type.foo", "example.type.baz" ]
}
],
"params": {
"example.type.baz": {
"example_key": "foobar"
}
},
"session": "xxxxxx"
}
Individual stages may require more than one request to complete, in which case the response will be as if the request was unauthenticated with the addition of any other keys as defined by the auth type.
If the homeserver decides that an attempt on a stage was unsuccessful,
but the client may make a second attempt, it returns the same HTTP
status 401 response as above, with the addition of the standard
errcode and error fields describing the error. For example:
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
"errcode": "M_FORBIDDEN",
"error": "Invalid password",
"completed": [ "example.type.foo" ],
"flows": [
{
"stages": [ "example.type.foo", "example.type.bar" ]
},
{
"stages": [ "example.type.foo", "example.type.baz" ]
}
],
"params": {
"example.type.baz": {
"example_key": "foobar"
}
},
"session": "xxxxxx"
}
If the request fails for a reason other than authentication, the server returns an error message in the standard format. For example:
HTTP/1.1 400 Bad request
Content-Type: application/json
{
"errcode": "M_EXAMPLE_ERROR",
"error": "Something was wrong"
}
If the client has completed all stages of a flow, the homeserver performs the API call and returns the result as normal. Completed stages cannot be retried by clients, therefore servers must return either a 401 response with the completed stages, or the result of the API call if all stages were completed when a client retries a stage.
Some authentication types may be completed by means other than through the Matrix client, for example, an email confirmation may be completed when the user clicks on the link in the email. In this case, the client retries the request with an auth dict containing only the session key. The response to this will be the same as if the client were attempting to complete an auth state normally, i.e. the request will either complete or request auth, with the presence or absence of that auth type in the ‘completed’ array indicating whether that stage is complete.
A request to an endpoint that uses User-Interactive Authentication never
succeeds without auth. Homeservers may allow requests that don’t require
auth by offering a stage with only the m.login.dummy auth type, but they
must still give a 401 response to requests with no auth data.
Example
At a high level, the requests made for an API call completing an auth flow with three stages will resemble the following diagram:
_______________________
| Stage 0 |
| No auth |
| ___________________ |
| |_Request_1_________| | <-- Returns "session" key which is used throughout.
|_______________________|
|
|
_________V_____________
| Stage 1 |
| type: "<auth type1>" |
| ___________________ |
| |_Request_1_________| |
|_______________________|
|
|
_________V_____________
| Stage 2 |
| type: "<auth type2>" |
| ___________________ |
| |_Request_1_________| |
| ___________________ |
| |_Request_2_________| |
| ___________________ |
| |_Request_3_________| |
|_______________________|
|
|
_________V_____________
| Stage 3 |
| type: "<auth type3>" |
| ___________________ |
| |_Request_1_________| | <-- Returns API response
|_______________________|
Authentication types
This specification defines the following auth types:
m.login.passwordm.login.recaptcham.login.ssom.login.email.identitym.login.msisdnm.login.dummym.login.registration_token- [Added in
v1.11]m.login.terms - [Added in
v1.17]m.oauth
Password-based
| Type | Description |
|---|---|
m.login.password |
The client submits an identifier and secret password, both sent in plain-text. |
To use this authentication type, clients should submit an auth dict as follows:
{
"type": "m.login.password",
"identifier": {
...
},
"password": "<password>",
"session": "<session ID>"
}
where the identifier property is a user identifier object, as
described in Identifier types.
For example, to authenticate using the user’s Matrix ID, clients would submit:
{
"type": "m.login.password",
"identifier": {
"type": "m.id.user",
"user": "<user_id or user localpart>"
},
"password": "<password>",
"session": "<session ID>"
}
Alternatively reply using a 3PID bound to the user’s account on the
homeserver using the /account/3pid API rather than giving the user
explicitly as follows:
{
"type": "m.login.password",
"identifier": {
"type": "m.id.thirdparty",
"medium": "<The medium of the third-party identifier.>",
"address": "<The third-party address of the user>"
},
"password": "<password>",
"session": "<session ID>"
}
In the case that the homeserver does not know about the supplied 3PID, the homeserver must respond with 403 Forbidden.
Google ReCaptcha
| Type | Description |
|---|---|
m.login.recaptcha |
The user completes a Google ReCaptcha 2.0 challenge. |
To use this authentication type, clients should submit an auth dict as follows:
{
"type": "m.login.recaptcha",
"response": "<captcha response>",
"session": "<session ID>"
}
Single Sign-On
| Type | Description |
|---|---|
m.login.sso |
Authentication is supported by authorising with an external single sign-on provider. |
A client wanting to complete authentication using SSO should use the Fallback mechanism. See SSO during User-Interactive Authentication for more information.
Email-based (identity / homeserver)
| Type | Description |
|---|---|
m.login.email.identity |
Authentication is supported by authorising an email address with an identity server, or homeserver if supported. |
Prior to submitting this, the client should authenticate with an identity server (or homeserver). After authenticating, the session information should be submitted to the homeserver.
To use this authentication type, clients should submit an auth dict as follows:
{
"type": "m.login.email.identity",
"threepid_creds": {
"sid": "<identity server session id>",
"client_secret": "<identity server client secret>",
"id_server": "<url of identity server authed with, e.g. 'matrix.org:8090'>",
"id_access_token": "<access token previously registered with the identity server>"
},
"session": "<session ID>"
}
Note that id_server (and therefore id_access_token) is optional if
the /requestToken request did not include them.
Phone number/MSISDN-based (identity / homeserver)
| Type | Description |
|---|---|
m.login.msisdn |
Authentication is supported by authorising a phone number with an identity server, or homeserver if supported. |
Prior to submitting this, the client should authenticate with an identity server (or homeserver). After authenticating, the session information should be submitted to the homeserver.
To use this authentication type, clients should submit an auth dict as follows:
{
"type": "m.login.msisdn",
"threepid_creds": {
"sid": "<identity server session id>",
"client_secret": "<identity server client secret>",
"id_server": "<url of identity server authed with, e.g. 'matrix.org:8090'>",
"id_access_token": "<access token previously registered with the identity server>"
},
"session": "<session ID>"
}
Note that id_server (and therefore id_access_token) is optional if
the /requestToken request did not include them.
Dummy Auth
| Type | Description |
|---|---|
m.login.dummy |
Dummy authentication always succeeds and requires no extra parameters. |
The purpose of dummy authentication is to allow servers to not require any form of
User-Interactive Authentication to perform a request. It can also be
used to differentiate flows where otherwise one flow would be a subset
of another flow. e.g. if a server offers flows m.login.recaptcha and
m.login.recaptcha, m.login.email.identity and the client completes the
recaptcha stage first, the auth would succeed with the former flow, even
if the client was intending to then complete the email auth stage. A
server can instead send flows m.login.recaptcha, m.login.dummy and
m.login.recaptcha, m.login.email.identity to fix the ambiguity.
To use this authentication type, clients should submit an auth dict with just the type and session, if provided:
{
"type": "m.login.dummy",
"session": "<session ID>"
}
Token-authenticated registration
[Added in v1.2]
| Type | Description |
|---|---|
m.login.registration_token |
Registers an account with a pre-shared token for authentication |
The m.login.registration_token authentication type is only valid on the
/register endpoint.
This authentication type provides homeservers the ability to allow registrations to a limited set of people instead of either offering completely open registrations or completely closed registration (where the homeserver administrators create and distribute accounts).
The token required for this authentication type is shared out of band from Matrix and is an opaque string using the Opaque Identifier Grammar, with maximum length of 64 characters. The server can keep any number of tokens for any length of time/validity. Such cases might be a token limited to 100 uses or for the next 2 hours - after the tokens expire, they can no longer be used to create accounts.
To use this authentication type, clients should submit an auth dict with just the type, token, and session:
{
"type": "m.login.registration_token",
"token": "fBVFdqVE",
"session": "<session ID>"
}
To determine if a token is valid before attempting to use it, the client can
use the /validity API defined below. The API doesn’t guarantee that a token
will be valid when used, but does avoid cases where the user finds out late
in the registration process that their token has expired.
GET
/_matrix/client/v1/register/m.login.registration_token/validity
Added in v1.2
Queries the server to determine if a given registration token is still valid at the time of request. This is a point-in-time check where the token might still expire by the time it is used.
Servers should be sure to rate limit this endpoint to avoid brute force attacks.
| Rate-limited: | Yes |
|---|---|
| Requires authentication: | No |
Request
Request parameters
| Name | Type | Description |
|---|---|---|
token |
string |
Required: The token to check validity of. |
Responses
| Status | Description |
|---|---|
200 |
The check has a result. |
403 |
The homeserver does not permit registration and thus all tokens are considered invalid. |
429 |
This request was rate-limited. |
200 response
| Name | Type | Description |
|---|---|---|
valid |
boolean |
Required: True if the token is still valid, false otherwise. This should additionally be false if the token is not a recognised token by the server. |
{
"valid": true
}
403 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: An error code. |
error |
string |
A human-readable error message. |
{
"errcode": "M_FORBIDDEN",
"error": "Registration is not enabled on this homeserver."
}
429 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: The M_LIMIT_EXCEEDED error code |
error |
string |
A human-readable error message. |
retry_after_ms |
integer |
The amount of time in milliseconds the client should wait before trying the request again. |
{
"errcode": "M_LIMIT_EXCEEDED",
"error": "Too many requests",
"retry_after_ms": 2000
}
Terms of service at registration
[Added in v1.11]
| Type | Description |
|---|---|
m.login.terms |
Authentication requires the user to accept a set of policy documents. |
The m.login.terms authentication type is only valid on the
/register endpoint.
This authentication type is used when the homeserver requires new users to accept a given set of policy documents, such as a terms of service and a privacy policy. There may be many different types of documents, all of which are versioned and presented in (potentially) multiple languages.
When the server requires the user to accept some terms, it does so by returning
a 401 response to the /register request, where the response body includes
m.login.terms in the flows list, and the m.login.terms property in the
params object has the structure shown below.
If a client encounters an invalid parameter, registration should stop with an error presented to the user.
The client should present the user with a checkbox to accept each policy,
including a link to the provided URL. Once the user has done so, the client
submits an auth dict with just the type and session, as follows, to
indicate that all of the policies have been accepted:
{
"type": "m.login.terms",
"session": "<session ID>"
}
The server is expected to track which document versions it presented to the user during registration, if applicable.
Example
-
A client might submit a registration request as follows:
POST /_matrix/client/v3/register{ "username": "cheeky_monkey", "password": "ilovebananas" } -
The server requires the user to accept some terms of service before registration, so returns the following response:
HTTP/1.1 401 Unauthorized Content-Type: application/json{ "flows": [ { "stages": [ "m.login.terms" ] } ], "params": { "m.login.terms": { "policies": { "terms_of_service": { "version": "1.2", "en": { "name": "Terms of Service", "url": "https://example.org/somewhere/terms-1.2-en.html" }, "fr": { "name": "Conditions d'utilisation", "url": "https://example.org/somewhere/terms-1.2-fr.html" } } } } }, "session": "kasgjaelkgj" } -
The client presents the list of documents to the user, inviting them to accept the polices.
-
The client repeats the registration request, confirming that the user has accepted the documents:
POST /_matrix/client/v3/register{ "username": "cheeky_monkey", "password": "ilovebananas", "auth": { "type": "m.login.terms", "session": "kasgjaelkgj" } } -
All authentication steps have now completed, so the request is successful:
HTTP/1.1 200 OK Content-Type: application/json{ "access_token": "abc123", "device_id": "GHTYAJCE", "user_id": "@cheeky_monkey:matrix.org" }
m.login.terms params
m.login.terms params
Schema for m.login.terms entry in the params object in a User-Interactive Authentication response.
| Name | Type | Description |
|---|---|---|
policies |
{string: Policy Definition} |
Required: A map from “Policy ID” to the current definition of this policy document. The Policy ID is a unique identifier for a given policy document, using the Opaque Identifier Grammar. |
| Name | Type | Description |
|---|---|---|
version |
string |
Required: The version of this policy document. This is provided as a convenience for the client, and uses the Opaque Identifier Grammar. |
| <Other properties> | Policy Translation |
Map from language codes to details of the document in that language.
Language codes SHOULD be formatted as per Section 2.2 of RFC
5646,
though some implementations may use an underscore instead of dash
(for example, |
| Name | Type | Description |
|---|---|---|
name |
string |
Required: The name of this document, in the appropriate language. An arbitrary string with no specified maximum length. |
url |
URI |
Required: A link to the text of this document, in the appropriate
language. MUST be a valid URI with scheme |
Examples
{
"policies": {
"privacy_policy": {
"en": {
"name": "Privacy Policy",
"url": "https://example.org/somewhere/privacy-1.2-en.html"
},
"fr": {
"name": "Politique de confidentialité",
"url": "https://example.org/somewhere/privacy-1.2-fr.html"
},
"version": "1.2"
},
"terms_of_service": {
"en": {
"name": "Terms of Service",
"url": "https://example.org/somewhere/terms-1.2-en.html"
},
"fr": {
"name": "Conditions d'utilisation",
"url": "https://example.org/somewhere/terms-1.2-fr.html"
},
"version": "1.2"
}
}
}
OAuth authentication
[Added in v1.17]
| Type | Description |
|---|---|
m.oauth |
Authentication is supported by authorising via the homeserver’s OAuth account management web UI. |
The m.oauth authentication type is currently only valid on the
/keys/device_signing/upload endpoint.
This authentication type provides homeservers the ability to guard access to
sensitive actions when the client has authenticated via the
OAuth 2.0 API, which is otherwise not
compatible with User-Interactive Authentication (UIA). To do so, the server
returns a 401 response on the respective request, where the response body
includes m.oauth in the flows list, and the m.oauth property in the
params object has the structure shown below.
The client is expected to open the contained URL to let the user confirm the
action in the homeserver’s account management web UI. Once the user has done
so, the client submits an auth dict with just the session, as follows,
to complete the stage:
{
"session": "<session ID>"
}
m.oauth params
m.oauth params
Schema for m.oauth entry in the params object in a User-Interactive Authentication response.
| Name | Type | Description |
|---|---|---|
url |
URI |
Required: A URL pointing to the homeserver’s OAuth account management web UI
where the user can approve the action. MUST be a valid URI with scheme
|
Examples
{
"url": "https://example.org/account/reset-cross-signing"
}
Fallback
Clients cannot be expected to be able to know how to process every single login type. If a client does not know how to handle a given login type, it can direct the user to a web browser with the URL of a fallback page which will allow the user to complete that login step out-of-band in their web browser. The URL it should open is:
/_matrix/client/v3/auth/<auth type>/fallback/web?session=<session ID>
Where auth type is the type name of the stage it is attempting and
session ID is the ID of the session given by the homeserver.
This MUST return an HTML page which can perform this authentication stage. This page must use the following JavaScript when the authentication has been completed:
if (window.onAuthDone) {
window.onAuthDone();
} else if (window.opener && window.opener.postMessage) {
window.opener.postMessage("authDone", "*");
}
This allows the client to either arrange for the global function
onAuthDone to be defined in an embedded browser, or to use the HTML5
cross-document
messaging API, to
receive a notification that the authentication stage has been completed.
Once a client receives the notification that the authentication stage has been completed, it should resubmit the request with an auth dict with just the session ID:
{
"session": "<session ID>"
}
Example
A client webapp might use the following JavaScript to open a popup window which will handle unknown login types:
/**
* Arguments:
* homeserverUrl: the base url of the homeserver (e.g. "https://matrix.org")
*
* apiEndpoint: the API endpoint being used (e.g.
* "/_matrix/client/v3/account/password")
*
* loginType: the loginType being attempted (e.g. "m.login.recaptcha")
*
* sessionID: the session ID given by the homeserver in earlier requests
*
* onComplete: a callback which will be called with the results of the request
*/
function unknownLoginType(homeserverUrl, apiEndpoint, loginType, sessionID, onComplete) {
var popupWindow;
var eventListener = function(ev) {
// check it's the right message from the right place.
if (ev.data !== "authDone" || ev.origin !== homeserverUrl) {
return;
}
// close the popup
popupWindow.close();
window.removeEventListener("message", eventListener);
// repeat the request
var requestBody = {
auth: {
session: sessionID,
},
};
request({
method:'POST', url:apiEndpoint, json:requestBody,
}, onComplete);
};
window.addEventListener("message", eventListener);
var url = homeserverUrl +
"/_matrix/client/v3/auth/" +
encodeURIComponent(loginType) +
"/fallback/web?session=" +
encodeURIComponent(sessionID);
popupWindow = window.open(url);
}
Identifier types
Some authentication mechanisms use a user identifier object to identify
a user. The user identifier object has a type field to indicate the
type of identifier being used, and depending on the type, has other
fields giving the information required to identify the user as described
below.
This specification defines the following identifier types:
m.id.userm.id.thirdpartym.id.phone
Matrix User ID
| Type | Description |
|---|---|
m.id.user |
The user is identified by their Matrix ID. |
A client can identify a user using their Matrix ID. This can either be the fully qualified Matrix user ID, or just the localpart of the user ID.
"identifier": {
"type": "m.id.user",
"user": "<user_id or user localpart>"
}
Third-party ID
| Type | Description |
|---|---|
m.id.thirdparty |
The user is identified by a third-party identifier in canonicalised form. |
A client can identify a user using a 3PID associated with the user’s
account on the homeserver, where the 3PID was previously associated
using the /account/3pid API. See the 3PID
Types Appendix for a list of Third-party
ID media.
"identifier": {
"type": "m.id.thirdparty",
"medium": "<The medium of the third-party identifier>",
"address": "<The canonicalised third-party address of the user>"
}
Phone number
| Type | Description |
|---|---|
m.id.phone |
The user is identified by a phone number. |
A client can identify a user using a phone number associated with the
user’s account, where the phone number was previously associated using
the /account/3pid API. The phone number can be passed in as entered
by the user; the homeserver will be responsible for canonicalising it.
If the client wishes to canonicalise the phone number, then it can use
the m.id.thirdparty identifier type with a medium of msisdn
instead.
"identifier": {
"type": "m.id.phone",
"country": "<The country that the phone number is from>",
"phone": "<The phone number>"
}
The country is the two-letter uppercase ISO-3166-1 alpha-2 country
code that the number in phone should be parsed as if it were dialled
from.
Login
A client can obtain access tokens using the /login API.
Note that this endpoint does not currently use the User-Interactive Authentication API.
For a simple username/password login, clients should submit a /login
request as follows:
{
"type": "m.login.password",
"identifier": {
"type": "m.id.user",
"user": "<user_id or user localpart>"
},
"password": "<password>"
}
Alternatively, a client can use a 3PID bound to the user’s account on
the homeserver using the /account/3pid API rather than giving the
user explicitly, as follows:
{
"type": "m.login.password",
"identifier": {
"medium": "<The medium of the third-party identifier>",
"address": "<The canonicalised third-party address of the user>"
},
"password": "<password>"
}
In the case that the homeserver does not know about the supplied 3PID,
the homeserver must respond with 403 Forbidden.
To log in using a login token, clients should submit a /login request
as follows:
{
"type": "m.login.token",
"token": "<login token>"
}
The token must encode the user ID, since there is no other identifying
data in the request. In the case that the token is not valid, the homeserver must
respond with 403 Forbidden and an error code of M_FORBIDDEN.
If the homeserver advertises m.login.sso as a viable flow, and the
client supports it, the client should redirect the user to the
/redirect endpoint for client login via SSO. After authentication
is complete, the client will need to submit a /login request matching
m.login.token.
[Added in v1.7] Already-authenticated clients can additionally generate
a token for their user ID if supported by the homeserver using
POST /login/get_token.
GET
/_matrix/client/v3/login
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.
| Rate-limited: | Yes |
|---|---|
| Requires authentication: | No |
Request
No request parameters or request body.
Responses
| Status | Description |
|---|---|
200 |
The login types the homeserver supports |
404 |
With M_UNRECOGNIZED: the homeserver does not support the legacy authentication API.
(See Authentication API discovery.) |
429 |
This request was rate-limited. |
200 response
| Name | Type | Description |
|---|---|---|
flows |
[LoginFlow] |
The homeserver’s supported login types |
| Name | Type | Description |
|---|---|---|
get_login_token |
boolean |
If Added in |
type |
string |
Required: The login type. This is supplied as the |
{
"flows": [
{
"type": "m.login.password"
},
{
"get_login_token": true,
"type": "m.login.token"
}
]
}
404 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: An error code. |
error |
string |
A human-readable error message. |
{
"errcode": "M_UNRECOGNIZED",
"error": "OAuth 2.0 authentication is in use on this homeserver."
}
429 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: The M_LIMIT_EXCEEDED error code |
error |
string |
A human-readable error message. |
retry_after_ms |
integer |
The amount of time in milliseconds the client should wait before trying the request again. |
{
"errcode": "M_LIMIT_EXCEEDED",
"error": "Too many requests",
"retry_after_ms": 2000
}
POST
/_matrix/client/v3/login
Authenticates the user, and issues an access token they can use to authorize themself in subsequent requests.
If the client does not supply a device_id, the server must
auto-generate one.
The returned access token must be associated with the device_id
supplied by the client or generated by the server. The server may
invalidate any access token previously associated with that device. See
Relationship between access tokens and devices.
| Rate-limited: | Yes |
|---|---|
| Requires authentication: | No |
Request
Request body
| Name | Type | Description |
|---|---|---|
address |
string |
Third-party identifier for the user. Deprecated in favour of |
device_id |
string |
ID of the client device. If this does not correspond to a
known client device, a new device will be created. The given
device ID must not be the same as a
cross-signing key ID.
The server will auto-generate a |
identifier |
User identifier |
Identification information for a user |
initial_device_display_name |
string |
A display name to assign to the newly-created device. Ignored
if |
medium |
string |
When logging in using a third-party identifier, the medium of the identifier. Must be ’email’. Deprecated in favour of |
password |
string |
Required when |
refresh_token |
boolean |
If true, the client supports refresh tokens. Added in |
token |
string |
Required when |
type |
string |
Required: The login type being used. This must be a type returned in one of the flows of the
response of the |
user |
string |
The fully qualified user ID or just local part of the user ID, to log in. Deprecated in favour of |
| Name | Type | Description |
|---|---|---|
type |
string |
Required: The type of identification. See Identifier types for supported values and additional property descriptions. |
| <Other properties> | |
Keys dependent on the identification type. |
Request body example
{
"identifier": {
"type": "m.id.user",
"user": "cheeky_monkey"
},
"initial_device_display_name": "Jungle Phone",
"password": "ilovebananas",
"type": "m.login.password"
}
Responses
| Status | Description |
|---|---|
200 |
The user has been authenticated. |
400 |
Part of the request was invalid. For example, the login type may not be recognised. Specific error codes used with this status code include:
|
403 |
The login attempt failed. This can include one of the following error codes:
|
429 |
This request was rate-limited. |
200 response
| Name | Type | Description |
|---|---|---|
access_token |
string |
Required: An access token for the account. This access token can then be used to authorize other requests. |
device_id |
string |
Required: ID of the logged-in device. Will be the same as the corresponding parameter in the request, if one was specified. |
expires_in_ms |
integer |
The lifetime of the access token, in milliseconds. Once the access token has expired a new access token can be obtained by using the provided refresh token. If no refresh token is provided, the client will need to re-log in to obtain a new access token. If not given, the client can assume that the access token will not expire. Added in |
home_server |
Server Name |
The server_name of the homeserver on which the account has been registered. Deprecated. Clients should extract the server_name from
|
refresh_token |
string |
A refresh token for the account. This token can be used to
obtain a new access token when it expires by calling the
Added in |
user_id |
User ID |
Required: The fully-qualified Matrix ID for the account. |
well_known |
Discovery Information |
Optional client configuration provided by the server. If present, clients SHOULD use the provided object to reconfigure themselves, optionally validating the URLs within. This object takes the same form as the one returned from .well-known autodiscovery. |
| Name | Type | Description |
|---|---|---|
m.homeserver |
Homeserver Information |
Required: Used by clients to discover homeserver information. |
m.identity_server |
Identity Server Information |
Used by clients to discover identity server information. |
| <Other properties> | |
Application-dependent keys using Java package naming convention. |
| Name | Type | Description |
|---|---|---|
base_url |
URI |
Required: The base URL for the homeserver for client-server connections. |
| Name | Type | Description |
|---|---|---|
base_url |
URI |
Required: The base URL for the identity server for client-server connections. |
{
"access_token": "abc123",
"device_id": "GHTYAJCE",
"expires_in_ms": 60000,
"refresh_token": "def456",
"user_id": "@cheeky_monkey:matrix.org",
"well_known": {
"m.homeserver": {
"base_url": "https://example.org"
},
"m.identity_server": {
"base_url": "https://id.example.org"
}
}
}
400 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: An error code. |
error |
string |
A human-readable error message. |
{
"errcode": "M_UNKNOWN",
"error": "Bad login type."
}
403 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: An error code. |
error |
string |
A human-readable error message. |
{
"errcode": "M_FORBIDDEN"
}
429 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: The M_LIMIT_EXCEEDED error code |
error |
string |
A human-readable error message. |
retry_after_ms |
integer |
The amount of time in milliseconds the client should wait before trying the request again. |
{
"errcode": "M_LIMIT_EXCEEDED",
"error": "Too many requests",
"retry_after_ms": 2000
}
POST
/_matrix/client/v1/login/get_token
Added in v1.7
Optional endpoint - the server is not required to implement this endpoint if it does not intend to use or support this functionality.
This API endpoint uses the User-Interactive Authentication API.
An already-authenticated client can call this endpoint to generate a single-use, time-limited,
token for an unauthenticated client to log in with, becoming logged in as the same user which
called this endpoint. The unauthenticated client uses the generated token in a m.login.token
login flow with the homeserver.
Clients, both authenticated and unauthenticated, might wish to hide user interface which exposes
this feature if the server is not offering it. Authenticated clients can check for support on
a per-user basis with the m.get_login_token capability,
while unauthenticated clients can detect server support by looking for an m.login.token login
flow with get_login_token: true on GET /login.
In v1.7 of the specification, transmission of the generated token to an unauthenticated client is left as an implementation detail. Future MSCs such as MSC3906 might standardise a way to transmit the token between clients.
The generated token MUST only be valid for a single login, enforced by the server. Clients which intend to log in multiple devices must generate a token for each.
With other User-Interactive Authentication (UIA)-supporting endpoints, servers sometimes do not re-prompt for verification if the session recently passed UIA. For this endpoint, servers MUST always re-prompt the user for verification to ensure explicit consent is gained for each additional client.
Servers are encouraged to apply stricter than normal rate limiting to this endpoint, such as maximum of 1 request per minute.
| Rate-limited: | Yes |
|---|---|
| Requires authentication: | Yes |
Request
Request body
| Name | Type | Description |
|---|---|---|
auth |
Authentication Data |
Additional authentication information for the user-interactive authentication API. |
| Name | Type | Description |
|---|---|---|
session |
string |
The value of the session key given by the homeserver. |
type |
string |
The authentication type that the client is attempting to complete.
May be omitted if |
| <Other properties> | |
Keys dependent on the login type |
Request body example
{
"auth": {
"example_credential": "verypoorsharedsecret",
"session": "xxxxx",
"type": "example.type.foo"
}
}
Responses
| Status | Description |
|---|---|
200 |
The login token an unauthenticated client can use to log in as the requesting user. |
400 |
The request was malformed, or the user does not have an ability to generate tokens for their devices, as implied by the User-Interactive Authentication API. Clients should verify whether the user has an ability to call this endpoint with the
|
401 |
The homeserver requires additional authentication information. |
429 |
This request was rate-limited. |
200 response
| Name | Type | Description |
|---|---|---|
expires_in_ms |
integer |
Required: The time remaining in milliseconds until the homeserver will no longer accept the token. |
login_token |
string |
Required: The login token for the |
{
"expires_in_ms": 120000,
"login_token": "<opaque string>"
}
400 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: An error code. |
error |
string |
A human-readable error message. |
{
"errcode": "M_UNKNOWN",
"error": "An unknown error occurred"
}
401 response
| Name | Type | Description |
|---|---|---|
completed |
[string] |
A list of the stages the client has completed successfully |
flows |
[Flow information] |
Required: A list of the login flows supported by the server for this API. |
params |
{string: object} |
Contains any information that the client will need to know in order to use a given type of authentication. For each login type presented, that type may be present as a key in this dictionary. For example, the public part of an OAuth client ID could be given here. |
session |
string |
This is a session identifier that the client must pass back to the home server, if one is provided, in subsequent attempts to authenticate in the same API call. |
| Name | Type | Description |
|---|---|---|
stages |
[string] |
Required: The login type of each of the stages required to complete this authentication flow |
{
"completed": [
"example.type.foo"
],
"flows": [
{
"stages": [
"example.type.foo"
]
}
],
"params": {
"example.type.baz": {
"example_key": "foobar"
}
},
"session": "xxxxxxyz"
}
429 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: The M_LIMIT_EXCEEDED error code |
error |
string |
A human-readable error message. |
retry_after_ms |
integer |
The amount of time in milliseconds the client should wait before trying the request again. |
{
"errcode": "M_LIMIT_EXCEEDED",
"error": "Too many requests",
"retry_after_ms": 2000
}
POST
/_matrix/client/v3/refresh
Added in v1.3
Refresh an access token. Clients should use the returned access token when making subsequent API calls, and store the returned refresh token (if given) in order to refresh the new access token when necessary.
After an access token has been refreshed, a server can choose to invalidate the old access token immediately, or can choose not to, for example if the access token would expire soon anyways. Clients should not make any assumptions about the old access token still being valid, and should use the newly provided access token instead.
The old refresh token remains valid until the new access token or refresh token is used, at which point the old refresh token is revoked.
Note that this endpoint does not require authentication via an access token. Authentication is provided via the refresh token.
Application Service identity assertion is disabled for this endpoint.
| Rate-limited: | Yes |
|---|---|
| Requires authentication: | No |
Request
Request body
| Name | Type | Description |
|---|---|---|
refresh_token |
string |
Required: The refresh token |
Request body example
{
"refresh_token": "some_token"
}
Responses
| Status | Description |
|---|---|
200 |
A new access token and refresh token were generated. |
401 |
The provided token was unknown, or has already been used. |
429 |
This request was rate-limited. |
200 response
| Name | Type | Description |
|---|---|---|
access_token |
string |
Required: The new access token to use. |
expires_in_ms |
integer |
The lifetime of the access token, in milliseconds. If not given, the client can assume that the access token will not expire. |
refresh_token |
string |
The new refresh token to use when the access token needs to be refreshed again. If not given, the old refresh token can be re-used. |
{
"access_token": "a_new_token",
"expires_in_ms": 60000,
"refresh_token": "another_new_token"
}
401 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: An error code. |
error |
string |
A human-readable error message. |
{
"errcode": "M_UNKNOWN_TOKEN",
"error": "Soft logged out",
"soft_logout": true
}
429 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: The M_LIMIT_EXCEEDED error code |
error |
string |
A human-readable error message. |
retry_after_ms |
integer |
The amount of time in milliseconds the client should wait before trying the request again. |
{
"errcode": "M_LIMIT_EXCEEDED",
"error": "Too many requests",
"retry_after_ms": 2000
}
POST
/_matrix/client/v3/logout
Invalidates an existing access token, so that it can no longer be used for authorization. The device associated with the access token is also deleted. Device keys for the device are deleted alongside the device.
| Rate-limited: | No |
|---|---|
| Requires authentication: | Yes |
Request
No request parameters or request body.
Responses
| Status | Description |
|---|---|
200 |
The access token used in the request was successfully invalidated. |
200 response
{}
POST
/_matrix/client/v3/logout/all
Invalidates all access tokens for a user, so that they can no longer be used for authorization. This includes the access token that made this request. All devices for the user are also deleted. Device keys for the device are deleted alongside the device.
This endpoint does not use the User-Interactive Authentication API because User-Interactive Authentication is designed to protect against attacks where someone gets hold of a single access token then takes over the account. This endpoint invalidates all access tokens for the user, including the token used in the request, and therefore the attacker is unable to take over the account in this way.
| Rate-limited: | No |
|---|---|
| Requires authentication: | Yes |
Request
No request parameters or request body.
Responses
| Status | Description |
|---|---|
200 |
The user’s access tokens were successfully invalidated. |
200 response
{}
Appservice Login
[Added in v1.2]
An appservice can log in by providing a valid appservice token and a user within the appservice’s namespace.
Appservices do not need to log in as individual users in all cases, as they can perform Identity Assertion using the appservice token. However, if the appservice needs a scoped token for a single user then they can use this API instead.
This request must be authenticated by the appservice as_token
(see Client Authentication on how to provide the token).
To use this login type, clients should submit a /login request as follows:
{
"type": "m.login.application_service",
"identifier": {
"type": "m.id.user",
"user": "<user_id or user localpart>"
}
}
If the access token is not valid, does not correspond to an appservice
or the user has not previously been registered then the homeserver will
respond with an errcode of M_FORBIDDEN.
If the access token does correspond to an appservice, but the user id does
not lie within its namespace then the homeserver will respond with an
errcode of M_EXCLUSIVE.
[Added in v1.17] If this login type is used and the server doesn’t
support logging in via the Legacy authentication API, it MUST return a 400 HTTP
status code with an M_APPSERVICE_LOGIN_UNSUPPORTED error code.
Login Fallback
If a client does not recognize any or all login flows it can use the fallback login API:
GET /_matrix/static/client/login/
This returns an HTML and JavaScript page which can perform the entire
login process. The page will attempt to call the JavaScript function
window.matrixLogin.onLogin(response) when login has been successfully
completed. The argument, response, is the JSON response body of
POST /_matrix/client/v3/login parsed
into a JavaScript object.
[Added in v1.1] Non-credential parameters valid for the /login
endpoint can be provided as query string parameters here. These are to be
forwarded to the login endpoint during the login process. For example:
GET /_matrix/static/client/login/?device_id=GHTYAJCE
Account registration
POST
/_matrix/client/v3/register
This API endpoint uses the User-Interactive Authentication API, except in the cases where a guest account is being registered.
Register for an account on this homeserver.
There are two kinds of user account:
-
useraccounts. These accounts may use the full API described in this specification. -
guestaccounts. These accounts may have limited permissions and may not be supported by all servers.
If registration is successful, this endpoint will issue an access token the client can use to authorize itself in subsequent requests.
If the client does not supply a device_id, the server must
auto-generate one.
The server SHOULD register an account with a User ID based on the
username provided, if any. Note that the grammar of Matrix User ID
localparts is restricted, so the server MUST either map the provided
username onto a user_id in a logical manner, or reject any
username which does not comply to the grammar with
M_INVALID_USERNAME.
Matrix clients MUST NOT assume that localpart of the registered
user_id matches the provided username.
The returned access token must be associated with the device_id
supplied by the client or generated by the server. The server may
invalidate any access token previously associated with that device. See
Relationship between access tokens and devices.
When registering a guest account, all parameters in the request body
with the exception of initial_device_display_name MUST BE ignored
by the server. The server MUST pick a device_id for the account
regardless of input.
Any user ID returned by this API must conform to the grammar given in the Matrix specification.
[Added in v1.17]
Even if the server doesn’t support the Legacy authentication API, it
MUST support this endpoint for application services to be able to
create users.
In that case application services MUST set the "inhibit_login": true
parameter as they cannot use it to log in as users. If the
inhibit_login parameter is not set to true, the server MUST return a
400 HTTP status code with an M_APPSERVICE_LOGIN_UNSUPPORTED error code.
[Added in v1.18] OAuth 2.0 aware clients
MUST NOT use this endpoint when the server offers the m.login.sso
authentication flow with
oauth_aware_preferred set to true. Instead they MUST use the
/login/sso/redirect
endpoint, adding the action=register parameter.
| Rate-limited: | Yes |
|---|---|
| Requires authentication: | No |
Request
Request parameters
| Name | Type | Description |
|---|---|---|
kind |
string |
The kind of account to register. Defaults to One of: |
Request body
| Name | Type | Description |
|---|---|---|
auth |
Authentication Data |
Additional authentication information for the
user-interactive authentication API. Note that this
information is not used to define how the registered user
should be authenticated, but is instead used to
authenticate the |
device_id |
string |
ID of the client device. If this does not correspond to a
known client device, a new device will be created. The server
will auto-generate a |
inhibit_login |
boolean |
If true, an |
initial_device_display_name |
string |
A display name to assign to the newly-created device. Ignored
if |
password |
string |
The desired password for the account. |
refresh_token |
boolean |
If Added in |
username |
string |
The basis for the localpart of the desired Matrix ID. If omitted, the homeserver MUST generate a Matrix ID local part. |
| Name | Type | Description |
|---|---|---|
session |
string |
The value of the session key given by the homeserver. |
type |
string |
The authentication type that the client is attempting to complete.
May be omitted if |
| <Other properties> | |
Keys dependent on the login type |
Request body example
{
"auth": {
"example_credential": "verypoorsharedsecret",
"session": "xxxxx",
"type": "example.type.foo"
},
"device_id": "GHTYAJCE",
"initial_device_display_name": "Jungle Phone",
"password": "ilovebananas",
"username": "cheeky_monkey"
}
Responses
| Status | Description |
|---|---|
200 |
The account has been registered. |
400 |
Part of the request was invalid. This may include one of the following error codes:
These errors may be returned at any stage of the registration process, including after authentication if the requested user ID was registered whilst the client was performing authentication. Homeservers MUST perform the relevant checks and return these codes before performing User-Interactive Authentication, although they may also return them after authentication is completed if, for example, the requested user ID was registered whilst the client was performing authentication. |
401 |
The homeserver requires additional authentication information. |
403 |
The homeserver does not permit registering the account. This response
can be used to identify that a particular kind of account is not
allowed, or that registration is generally not supported by the homeserver. |
429 |
This request was rate-limited. |
200 response
| Name | Type | Description |
|---|---|---|
access_token |
string |
An access token for the account.
This access token can then be used to authorize other requests.
Required if the |
device_id |
string |
ID of the registered device. Will be the same as the
corresponding parameter in the request, if one was specified.
Required if the |
expires_in_ms |
integer |
The lifetime of the access token, in milliseconds. Once the access token has expired a new access token can be obtained by using the provided refresh token. If no refresh token is provided, the client will need to re-log in to obtain a new access token. If not given, the client can assume that the access token will not expire. Omitted if the Added in |
home_server |
Server Name |
The server_name of the homeserver on which the account has been registered. Deprecated. Clients should extract the server_name from
|
refresh_token |
string |
A refresh token for the account. This token can be used to
obtain a new access token when it expires by calling the
Omitted if the Added in |
user_id |
User ID |
Required: The fully-qualified Matrix user ID (MXID) that has been registered. Any user ID returned by this API must conform to the grammar given in the Matrix specification. |
{
"access_token": "abc123",
"device_id": "GHTYAJCE",
"user_id": "@cheeky_monkey:matrix.org"
}
400 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: An error code. |
error |
string |
A human-readable error message. |
{
"errcode": "M_USER_IN_USE",
"error": "Desired user ID is already taken."
}
401 response
| Name | Type | Description |
|---|---|---|
completed |
[string] |
A list of the stages the client has completed successfully |
flows |
[Flow information] |
Required: A list of the login flows supported by the server for this API. |
params |
{string: object} |
Contains any information that the client will need to know in order to use a given type of authentication. For each login type presented, that type may be present as a key in this dictionary. For example, the public part of an OAuth client ID could be given here. |
session |
string |
This is a session identifier that the client must pass back to the home server, if one is provided, in subsequent attempts to authenticate in the same API call. |
| Name | Type | Description |
|---|---|---|
stages |
[string] |
Required: The login type of each of the stages required to complete this authentication flow |
{
"completed": [
"example.type.foo"
],
"flows": [
{
"stages": [
"example.type.foo"
]
}
],
"params": {
"example.type.baz": {
"example_key": "foobar"
}
},
"session": "xxxxxxyz"
}
403 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: An error code. |
error |
string |
A human-readable error message. |
{
"errcode": "M_FORBIDDEN",
"error": "Registration is disabled"
}
429 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: The M_LIMIT_EXCEEDED error code |
error |
string |
A human-readable error message. |
retry_after_ms |
integer |
The amount of time in milliseconds the client should wait before trying the request again. |
{
"errcode": "M_LIMIT_EXCEEDED",
"error": "Too many requests",
"retry_after_ms": 2000
}
GET
/_matrix/client/v3/register/available
Checks to see if a username is available, and valid, for the server.
The server should check to ensure that, at the time of the request, the username requested is available for use. This includes verifying that an application service has not claimed the username and that the username fits the server’s desired requirements (for example, a server could dictate that it does not permit usernames with underscores).
Matrix clients may wish to use this API prior to attempting registration, however the clients must also be aware that using this API does not normally reserve the username. This can mean that the username becomes unavailable between checking its availability and attempting to register it.
| Rate-limited: | Yes |
|---|---|
| Requires authentication: | No |
Request
Request parameters
| Name | Type | Description |
|---|---|---|
username |
string |
Required: The username to check the availability of. |
Responses
| Status | Description |
|---|---|
200 |
The username is available |
400 |
Part of the request was invalid or the username is not available. This may include one of the following error codes:
|
429 |
This request was rate-limited. |
200 response
| Name | Type | Description |
|---|---|---|
available |
boolean |
A flag to indicate that the username is available. This should always
be |
{
"available": true
}
400 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: An error code. |
error |
string |
A human-readable error message. |
{
"errcode": "M_USER_IN_USE",
"error": "Desired user ID is already taken."
}
429 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: The M_LIMIT_EXCEEDED error code |
error |
string |
A human-readable error message. |
retry_after_ms |
integer |
The amount of time in milliseconds the client should wait before trying the request again. |
{
"errcode": "M_LIMIT_EXCEEDED",
"error": "Too many requests",
"retry_after_ms": 2000
}
POST
/_matrix/client/v3/register/email/requestToken
The homeserver must check that the given email address is not already associated with an account on this homeserver. The homeserver should validate the email itself, either by sending a validation email itself or by using a service it has control over.
| Rate-limited: | No |
|---|---|
| Requires authentication: | No |
Request
Request body
| Name | Type | Description |
|---|---|---|
client_secret |
string |
Required: A unique string generated by the client, and used to identify the
validation attempt. It must be a string consisting of the characters
|
email |
Email Address |
Required: The email address to validate. |
id_access_token |
string |
An access token previously registered with the identity server. Servers can treat this as optional to distinguish between r0.5-compatible clients and this specification version. Required if an |
id_server |
string |
The hostname of the identity server to communicate with. May optionally include a port. This parameter is ignored when the homeserver handles 3PID verification. This parameter is deprecated with a plan to be removed in a future specification
version for |
next_link |
URI |
Optional. When the validation is completed, the identity server will redirect the user to this URL. This option is ignored when submitting 3PID validation information through a POST request. |
send_attempt |
integer |
Required: The server will only send an email if the |
Request body example
{
"client_secret": "monkeys_are_GREAT",
"email": "[email protected]",
"id_server": "id.example.com",
"next_link": "https://example.org/congratulations.html",
"send_attempt": 1
}
Responses
| Status | Description |
|---|---|
200 |
An email has been sent to the specified address. Note that this may be an email containing the validation token or it may be informing the user of an error. |
400 |
Part of the request was invalid. This may include one of the following error codes:
|
403 |
The homeserver does not permit the address to be bound. |
200 response
| Name | Type | Description |
|---|---|---|
sid |
string |
Required: The session ID. Session IDs are opaque strings that must consist entirely
of the characters |
submit_url |
URI |
An optional field containing a URL where the client must submit the
validation token, with identical request and response parameters and error
codes to the Identity Service API’s
If this field is not present, the client can assume that verification
will happen without the client’s involvement provided the homeserver
advertises a sufficiently recent version in the Changed in |
{
"sid": "123abc",
"submit_url": "https://example.org/path/to/submitToken"
}
400 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: An error code. |
error |
string |
A human-readable error message. |
{
"errcode": "M_THREEPID_IN_USE",
"error": "The specified address is already in use"
}
403 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: An error code. |
error |
string |
A human-readable error message. |
{
"errcode": "M_THREEPID_DENIED",
"error": "Third-party identifier is not allowed"
}
POST
/_matrix/client/v3/register/msisdn/requestToken
The homeserver must check that the given phone number is not already associated with an account on this homeserver. The homeserver should validate the phone number itself, either by sending a validation message itself or by using a service it has control over.
| Rate-limited: | No |
|---|---|
| Requires authentication: | No |
Request
Request body
| Name | Type | Description |
|---|---|---|
client_secret |
string |
Required: A unique string generated by the client, and used to identify the
validation attempt. It must be a string consisting of the characters
|
country |
string |
Required: The two-letter uppercase ISO-3166-1 alpha-2 country code that the
number in |
id_access_token |
string |
An access token previously registered with the identity server. Servers can treat this as optional to distinguish between r0.5-compatible clients and this specification version. Required if an |
id_server |
string |
The hostname of the identity server to communicate with. May optionally include a port. This parameter is ignored when the homeserver handles 3PID verification. This parameter is deprecated with a plan to be removed in a future specification
version for |
next_link |
URI |
Optional. When the validation is completed, the identity server will redirect the user to this URL. This option is ignored when submitting 3PID validation information through a POST request. |
phone_number |
string |
Required: The phone number to validate. |
send_attempt |
integer |
Required: The server will only send an SMS if the |
Request body example
{
"client_secret": "monkeys_are_GREAT",
"country": "GB",
"id_server": "id.example.com",
"next_link": "https://example.org/congratulations.html",
"phone_number": "07700900001",
"send_attempt": 1
}
Responses
| Status | Description |
|---|---|
200 |
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. |
400 |
Part of the request was invalid. This may include one of the following error codes:
|
403 |
The homeserver does not permit the address to be bound. |
200 response
| Name | Type | Description |
|---|---|---|
sid |
string |
Required: The session ID. Session IDs are opaque strings that must consist entirely
of the characters |
submit_url |
URI |
An optional field containing a URL where the client must submit the
validation token, with identical request and response parameters and error
codes to the Identity Service API’s
If this field is not present, the client can assume that verification
will happen without the client’s involvement provided the homeserver
advertises a sufficiently recent version in the Changed in |
{
"sid": "123abc",
"submit_url": "https://example.org/path/to/submitToken"
}
400 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: An error code. |
error |
string |
A human-readable error message. |
{
"errcode": "M_THREEPID_IN_USE",
"error": "The specified address is already in use"
}
403 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: An error code. |
error |
string |
A human-readable error message. |
{
"errcode": "M_THREEPID_DENIED",
"error": "Third-party identifier is not allowed"
}
Account management
Password management
Clients SHOULD enforce that the password provided is suitably complex.
The password SHOULD include a lower-case letter, an upper-case letter, a
number and a symbol and be at a minimum 8 characters in length. Servers
MAY reject weak passwords with an error code M_WEAK_PASSWORD.
POST
/_matrix/client/v3/account/password
Changes the password for an account on this homeserver.
This API endpoint uses the User-Interactive Authentication API to ensure the user changing the password is actually the owner of the account.
An access token should be submitted to this endpoint if the client has an active session.
The homeserver may change the flows available depending on whether a valid access token is provided. The homeserver SHOULD NOT revoke the access token provided in the request. Whether other access tokens for the user are revoked depends on the request parameters.
This endpoint uses capabilities negotiation.
Clients SHOULD check the value of the m.change_password capability
to determine if this endpoint is available.
| Rate-limited: | Yes |
|---|---|
| Requires authentication: | Optional |
Request
Request body
| Name | Type | Description |
|---|---|---|
auth |
Authentication Data |
Additional authentication information for the user-interactive authentication API. |
logout_devices |
boolean |
Whether the user’s other access tokens, and their associated devices, should be
revoked if the request succeeds. Defaults to When |
new_password |
string |
Required: The new password for the account. |
| Name | Type | Description |
|---|---|---|
session |
string |
The value of the session key given by the homeserver. |
type |
string |
The authentication type that the client is attempting to complete.
May be omitted if |
| <Other properties> | |
Keys dependent on the login type |
Request body example
{
"auth": {
"example_credential": "verypoorsharedsecret",
"session": "xxxxx",
"type": "example.type.foo"
},
"logout_devices": true,
"new_password": "ihatebananas"
}
Responses
| Status | Description |
|---|---|
200 |
The password has been changed. |
401 |
The homeserver requires additional authentication information. |
429 |
This request was rate-limited. |
200 response
{}
401 response
| Name | Type | Description |
|---|---|---|
completed |
[string] |
A list of the stages the client has completed successfully |
flows |
[Flow information] |
Required: A list of the login flows supported by the server for this API. |
params |
{string: object} |
Contains any information that the client will need to know in order to use a given type of authentication. For each login type presented, that type may be present as a key in this dictionary. For example, the public part of an OAuth client ID could be given here. |
session |
string |
This is a session identifier that the client must pass back to the home server, if one is provided, in subsequent attempts to authenticate in the same API call. |
| Name | Type | Description |
|---|---|---|
stages |
[string] |
Required: The login type of each of the stages required to complete this authentication flow |
{
"completed": [
"example.type.foo"
],
"flows": [
{
"stages": [
"example.type.foo"
]
}
],
"params": {
"example.type.baz": {
"example_key": "foobar"
}
},
"session": "xxxxxxyz"
}
429 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: The M_LIMIT_EXCEEDED error code |
error |
string |
A human-readable error message. |
retry_after_ms |
integer |
The amount of time in milliseconds the client should wait before trying the request again. |
{
"errcode": "M_LIMIT_EXCEEDED",
"error": "Too many requests",
"retry_after_ms": 2000
}
POST
/_matrix/client/v3/account/password/email/requestToken
The homeserver must check that the given email address is
associated with an account on this homeserver. 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
/register/email/requestToken
endpoint, 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
email to the given address prompting the user to create an account.
M_THREEPID_IN_USE may not be returned.
The homeserver should validate the email itself, either by sending a validation email itself or by using a service it has control over.
| Rate-limited: | No |
|---|---|
| Requires authentication: | No |
Request
Request body
| Name | Type | Description |
|---|---|---|
client_secret |
string |
Required: A unique string generated by the client, and used to identify the
validation attempt. It must be a string consisting of the characters
|
email |
Email Address |
Required: The email address to validate. |
id_access_token |
string |
An access token previously registered with the identity server. Servers can treat this as optional to distinguish between r0.5-compatible clients and this specification version. Required if an |
id_server |
string |
The hostname of the identity server to communicate with. May optionally include a port. This parameter is ignored when the homeserver handles 3PID verification. This parameter is deprecated with a plan to be removed in a future specification
version for |
next_link |
URI |
Optional. When the validation is completed, the identity server will redirect the user to this URL. This option is ignored when submitting 3PID validation information through a POST request. |
send_attempt |
integer |
Required: The server will only send an email if the |
Request body example
{
"client_secret": "monkeys_are_GREAT",
"email": "[email protected]",
"id_server": "id.example.com",
"next_link": "https://example.org/congratulations.html",
"send_attempt": 1
}
Responses
| Status | Description |
|---|---|
200 |
An email was sent to the given address. |
400 |
The referenced third-party identifier is not recognised by the
homeserver, or the request was invalid. The error code M_SERVER_NOT_TRUSTED
can be returned if the server does not trust/support the identity server
provided in the request. |
403 |
The homeserver does not allow the third-party identifier as a contact option. |
200 response
| Name | Type | Description |
|---|---|---|
sid |
string |
Required: The session ID. Session IDs are opaque strings that must consist entirely
of the characters |
submit_url |
URI |
An optional field containing a URL where the client must submit the
validation token, with identical request and response parameters and error
codes to the Identity Service API’s
If this field is not present, the client can assume that verification
will happen without the client’s involvement provided the homeserver
advertises a sufficiently recent version in the Changed in |
{
"sid": "123abc",
"submit_url": "https://example.org/path/to/submitToken"
}
400 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: An error code. |
error |
string |
A human-readable error message. |
{
"errcode": "M_THREEPID_NOT_FOUND",
"error": "Email not found"
}
403 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: An error code. |
error |
string |
A human-readable error message. |
{
"errcode": "M_THREEPID_DENIED",
"error": "Third-party identifier is not allowed"
}
POST
/_matrix/client/v3/account/password/msisdn/requestToken
The homeserver must check that the given phone number is
associated with an account on this homeserver. 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
/register/msisdn/requestToken
endpoint, except that
M_THREEPID_NOT_FOUND may be returned if no account matching the
given phone number could be found. The server may instead send the SMS
to the given phone number prompting the user to create an account.
M_THREEPID_IN_USE may not be returned.
The homeserver should validate the phone number itself, either by sending a validation message itself or by using a service it has control over.
| Rate-limited: | No |
|---|---|
| Requires authentication: | No |
Request
Request body
| Name | Type | Description |
|---|---|---|
client_secret |
string |
Required: A unique string generated by the client, and used to identify the
validation attempt. It must be a string consisting of the characters
|
country |
string |
Required: The two-letter uppercase ISO-3166-1 alpha-2 country code that the
number in |
id_access_token |
string |
An access token previously registered with the identity server. Servers can treat this as optional to distinguish between r0.5-compatible clients and this specification version. Required if an |
id_server |
string |
The hostname of the identity server to communicate with. May optionally include a port. This parameter is ignored when the homeserver handles 3PID verification. This parameter is deprecated with a plan to be removed in a future specification
version for |
next_link |
URI |
Optional. When the validation is completed, the identity server will redirect the user to this URL. This option is ignored when submitting 3PID validation information through a POST request. |
phone_number |
string |
Required: The phone number to validate. |
send_attempt |
integer |
Required: The server will only send an SMS if the |
Request body example
{
"client_secret": "monkeys_are_GREAT",
"country": "GB",
"id_server": "id.example.com",
"next_link": "https://example.org/congratulations.html",
"phone_number": "07700900001",
"send_attempt": 1
}
Responses
| Status | Description |
|---|---|
200 |
An SMS message was sent to the given phone number. |
400 |
The referenced third-party identifier is not recognised by the
homeserver, or the request was invalid. The error code M_SERVER_NOT_TRUSTED
can be returned if the server does not trust/support the identity server
provided in the request. |
403 |
The homeserver does not allow the third-party identifier as a contact option. |
200 response
| Name | Type | Description |
|---|---|---|
sid |
string |
Required: The session ID. Session IDs are opaque strings that must consist entirely
of the characters |
submit_url |
URI |
An optional field containing a URL where the client must submit the
validation token, with identical request and response parameters and error
codes to the Identity Service API’s
If this field is not present, the client can assume that verification
will happen without the client’s involvement provided the homeserver
advertises a sufficiently recent version in the Changed in |
{
"sid": "123abc",
"submit_url": "https://example.org/path/to/submitToken"
}
400 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: An error code. |
error |
string |
A human-readable error message. |
{
"errcode": "M_THREEPID_NOT_FOUND",
"error": "Phone number not found"
}
403 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: An error code. |
error |
string |
A human-readable error message. |
{
"errcode": "M_THREEPID_DENIED",
"error": "Third-party identifier is not allowed"
}
Account deactivation
POST
/_matrix/client/v3/account/deactivate
Deactivate the user’s account, removing all ability for the user to login again.
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 homeserver may change the flows available depending on whether a valid access token is provided.
Unlike other endpoints, this endpoint does not take an id_access_token
parameter because the homeserver is expected to sign the request to the
identity server instead.
[Added in v1.18] OAuth 2.0 aware clients
MUST NOT use this endpoint when the server supports the OAuth 2.0 API.
Instead they MUST refer the user to the account management URL,
if available, and MAY use the action=org.matrix.account_deactivate
parameter.
| Rate-limited: | Yes |
|---|---|
| Requires authentication: | Optional |
Request
Request body
| Name | Type | Description |
|---|---|---|
auth |
Authentication Data |
Additional authentication information for the user-interactive authentication API. |
erase |
boolean |
Whether the user would like their content to be erased as much as possible from the server. Erasure means that any users (or servers) which join the room after the erasure request are served redacted copies of the events sent by this account. Users which had visibility on those events prior to the erasure are still able to see unredacted copies. No redactions are sent and the erasure request is not shared over federation, so other servers might still serve unredacted copies. The server should additionally erase any non-event data associated with the user, such as account data and contact 3PIDs. Defaults to Added in |
id_server |
string |
The identity server to unbind all of the user’s 3PIDs from.
If not provided, the homeserver MUST use the |
| Name | Type | Description |
|---|---|---|
session |
string |
The value of the session key given by the homeserver. |
type |
string |
The authentication type that the client is attempting to complete.
May be omitted if |
| <Other properties> | |
Keys dependent on the login type |
Request body example
{
"auth": {
"example_credential": "verypoorsharedsecret",
"session": "xxxxx",
"type": "example.type.foo"
},
"id_server": "example.org"
}
Responses
| Status | Description |
|---|---|
200 |
The account has been deactivated. |
401 |
The homeserver requires additional authentication information. |
429 |
This request was rate-limited. |
200 response
| Name | Type | Description |
|---|---|---|
id_server_unbind_result |
string |
Required: An indicator as to whether or not the homeserver was able to unbind
the user’s 3PIDs from the identity server(s). One of: |
{
"id_server_unbind_result": "success"
}
401 response
| Name | Type | Description |
|---|---|---|
completed |
[string] |
A list of the stages the client has completed successfully |
flows |
[Flow information] |
Required: A list of the login flows supported by the server for this API. |
params |
{string: object} |
Contains any information that the client will need to know in order to use a given type of authentication. For each login type presented, that type may be present as a key in this dictionary. For example, the public part of an OAuth client ID could be given here. |
session |
string |
This is a session identifier that the client must pass back to the home server, if one is provided, in subsequent attempts to authenticate in the same API call. |
| Name | Type | Description |
|---|---|---|
stages |
[string] |
Required: The login type of each of the stages required to complete this authentication flow |
{
"completed": [
"example.type.foo"
],
"flows": [
{
"stages": [
"example.type.foo"
]
}
],
"params": {
"example.type.baz": {
"example_key": "foobar"
}
},
"session": "xxxxxxyz"
}
429 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: The M_LIMIT_EXCEEDED error code |
error |
string |
A human-readable error message. |
retry_after_ms |
integer |
The amount of time in milliseconds the client should wait before trying the request again. |
{
"errcode": "M_LIMIT_EXCEEDED",
"error": "Too many requests",
"retry_after_ms": 2000
}
OAuth 2.0 aware clients
[Added in v1.18]
This is a compatibility feature to aide clients in the transition to the OAuth 2.0 API. It allows clients that only support the legacy API to make some less-invasive changes to improve the user experience when talking to a homeserver that is using the OAuth 2.0 API without actually having to implement the full OAuth 2.0 API.
Client behaviour
For a client to be considered fully OAuth 2.0 aware it MUST:
-
Support the
m.login.ssoauthentication flow. -
Where a
oauth_aware_preferredvalue oftrueis present on anm.login.ssoflow, only offer that auth flow to the user. -
Append
action=loginoraction=registerparameters to the SSO redirect endpoints. The client might determine the value to use based on whether the user clicked a “Login” or “Register” button. -
Check and honour the
m.3pid_changescapability so that the user is not offered the ability to add or remove 3PIDs if the homeserver says the capability is not available. -
Determine if the homeserver is using the OAuth 2.0 API by using server metadata discovery from the OAuth 2.0 API.
-
If a homeserver is using the OAuth 2.0 API as discovered in the previous step then the client MUST redirect users to manage their account at the account management URL, if available, instead of providing a native UI using the legacy API endpoints.
- If the user wishes to deactivate their account then the client MUST refer them to the account management URL.
- If the user wishes to sign out a device other than its own then the client
MUST deep link the user to the account management URL by adding the
action=org.matrix.device_deleteanddevice_id=<device_id>parameters so that the web UI knows that the user wishes to sign out a device and which one it is.
Optionally, an OAuth 2.0 aware client MAY:
- Label the SSO button as “Continue” rather than “SSO” when
oauth_aware_preferredistrue. This is because after redirect the server may then offer a password and/or further upstream IdPs. - Pass other account management URL parameters for context when linking to the account web UI.
Server behaviour
For a homeserver to provide support for OAuth 2.0 aware clients it MUST:
- Support the OAuth 2.0 API.
- Provide an implementation of the
m.login.ssoauthentication flow from the legacy API. - If password authentication was previously enabled on the homeserver then
provide an implementation of the
m.login.passwordauthentication flow from the legacy API. - Indicate that the
m.login.ssoflow is preferred by settingoauth_aware_preferredtotrue. - Support a value for the
actionparam on the SSO redirect endpoints.
Additionally, the homeserver SHOULD:
- Advertise the account management URL in the server metadata.
OAuth 2.0 API
[Added in v1.15]
Contrary to the legacy API that uses custom endpoints and UIA, this authentication API is based on the OAuth 2.0 industry standard introduced in RFC 6749 and extended by other RFCs, with a few features from OpenID Connect. This allows us to benefit from its experience and from any further enhancements or best practice recommendations.
The main change for end users with this API is that all the account management occurs in their browser on the homeserver’s web UI. This is where they will register a new account or log into an existing account and authorize a client to access their Matrix account. This means that the homeserver has complete control over the requirements to create a new account and is not limited by the steps defined in this specification. It also means that less trust is given to clients because they don’t have access to the user’s credentials anymore.
The User-Interactive Authentication API is not compatible with the OAuth 2.0 API, so the endpoints that depend on it for authentication can’t be used when an access token is obtained with this API.
The only exception to this is the
/keys/device_signing/upload
endpoint which uses the m.oauth
authentication type.
Sample flow
- Discover the OAuth 2.0 server metadata.
- Register the client with the homeserver.
- Obtain an access token by authorizing a scope for the client with the authorization code grant or device authorization grant.
- Refresh the access token with the refresh token grant when it expires.
- Revoke the tokens when the users wants to log out of the client.
Login flows
Logging in and obtaining an access token with the OAuth 2.0 API should be done using either the authorization code grant or device authorization grant. In the context of the Matrix specification, this means requesting a scope including full client-server API read/write access and allocating a device ID.
Authorization code flow
This login flow uses the authorization code grant and is suitable for clients where the following criteria are met:
- There is a web browser available for the user to complete authentication and authorization.
- The client can receive the callback via a redirect from the web browser.
Once the client has retrieved the server metadata the client needs to generate the following values:
-
device_id: a unique identifier for this device; see theurn:matrix:client:device:<device_id>scope token. -
state: a unique opaque identifier, like a transaction ID, that will allow the client to maintain state between the authorization request and the callback. -
code_verifier: a cryptographically random value that will allow to make sure that the client that makes the token request for a givencodeis the same one that made the authorization request.It is defined in RFC 7636 as a high-entropy cryptographic random string using the characters
[A-Z],[a-z],[0-9],-,.,_and~with a minimum length of 43 characters and a maximum length of 128 characters.
Authorization request
The client then constructs the authorization request URL using the
authorization_endpoint value, with the following query parameters:
| Parameter | Value |
|---|---|
response_type |
code |
client_id |
The client ID returned from client registration. |
redirect_uri |
The redirect URI that MUST match one of the values registered in the client metadata |
scope |
urn:matrix:client:api:* urn:matrix:client:device:<device_id> with the device_id generated previously. |
state |
The state value generated previously. |
response_mode |
fragment or query (see “Callback” below). |
code_challenge |
Computed from the code_verifier value generated previously using the SHA-256 algorithm, as described in RFC 7636. |
code_challenge_method |
S256 |
This authorization request URL must be opened in the user’s browser:
- For web-based clients, this can be done through a redirection or by opening the URL in a new tab.
- For native clients, this can be done by opening the URL using the system
browser, or, when available, through platform-specific APIs such as
ASWebAuthenticationSessionon iOS or Android Custom Tabs.
Sample authorization request, with extra whitespaces for readability:
https://account.example.com/oauth2/auth?
client_id = s6BhdRkqt3 &
response_type = code &
response_mode = fragment &
redirect_uri = https://app.example.com/oauth2-callback &
scope = urn:matrix:client:api:* urn:matrix:client:device:AAABBBCCCDDD &
state = ewubooN9weezeewah9fol4oothohroh3 &
code_challenge = 72xySjpngTcCxgbPfFmkPHjMvVDl2jW1aWP7-J6rmwU &
code_challenge_method = S256
Once completed, the user is redirected to the redirect_uri, with either a
successful or failed authorization in the URL fragment or query parameters.
Whether the parameters are in the URL fragment or query parameters is determined
by the response_mode value:
- If set to
fragment, the parameters will be placed in the URL fragment, likehttps://example.com/callback#param1=value1¶m2=value2. - If set to
query, the parameters will be in placed the query string, likecom.example.app:/callback?param1=value1¶m2=value2.
To avoid disclosing the parameters to the web server hosting the redirect_uri,
clients SHOULD use the fragment response mode if the redirect_uri is an
HTTPS URI with a remote host.
In both success and failure cases, the parameters will include the state value
used in the authorization request.
A successful authorization will have a code value, for example:
https://app.example.com/oauth2-callback#state=ewubooN9weezeewah9fol4oothohroh3&code=iuB7Eiz9heengah1joh2ioy9ahChuP6R
A failed authorization will have the following values:
error: the error codeerror_description: the error description (optional)error_uri: the URI where the user can find more information about the error (optional)
For example:
https://app.example.com/oauth2-callback#state=ewubooN9weezeewah9fol4oothohroh3&error=access_denied&error_description=The+resource+owner+or+authorization+server+denied+the+request.&error_uri=https%3A%2F%2Ferrors.example.com%2F
Token request
The client then exchanges the authorization code to obtain an access token using the token endpoint.
This is done by making a POST request to the token_endpoint with the following
parameters, encoded as application/x-www-form-urlencoded in the body:
| Parameter | Value |
|---|---|
grant_type |
authorization_code |
code |
The value of code obtained from the callback. |
redirect_uri |
The same redirect_uri used in the authorization request. |
client_id |
The client ID returned from client registration. |
code_verifier |
The value generated at the start of the authorization flow. |
The server replies with a JSON object containing the access token, the token type, the expiration time, and the refresh token.
Sample token request:
POST /oauth2/token HTTP/1.1
Host: account.example.com
Content-Type: application/x-www-form-urlencoded
Accept: application/json
grant_type=authorization_code
&code=iuB7Eiz9heengah1joh2ioy9ahChuP6R
&redirect_uri=https://app.example.com/oauth2-callback
&client_id=s6BhdRkqt3
&code_verifier=ogie4iVaeteeKeeLaid0aizuimairaCh
Sample response:
{
"access_token": "2YotnFZFEjr1zCsicMWpAA",
"token_type": "Bearer",
"expires_in": 299,
"refresh_token": "tGz3JOkF0XG5Qx2TlKWIA",
"scope": "urn:matrix:client:api:* urn:matrix:client:device:AAABBBCCCDDD"
}
Finally, the client can call the /whoami
endpoint to get the user ID that owns the access token.
Device authorization flow
[Added in v1.18]
This flow uses the device authorization grant to allow clients to obtain an access token without needing to directly interact with a web browser. Instead, the user completes authorization on a web browser that can be a separate device.
This is useful for devices with limited input capabilities (such as CLI applications or embedded devices) or where the redirect handling may be unreliable (such as a desktop applications).
Once the client has retrieved the server metadata the client needs to generate following value:
device_id: a unique identifier for this device; see theurn:matrix:client:device:<device_id>scope token.
Device authorization request
The client sends a application/x-www-form-urlencoded encoded POST request to
the device_authorization_endpoint as defined in
RFC 8628 section 3.1:
| Parameter | Value |
|---|---|
client_id |
The client ID returned from client registration. |
scope |
urn:matrix:client:api:* urn:matrix:client:device:<device_id> with the device_id generated previously. |
Sample device authorization request:
POST /oauth2/device HTTP/1.1
Host: account.example.com
Content-Type: application/x-www-form-urlencoded
client_id=s6BhdRkqt3&scope=urn%3Amatrix%3Aclient%3Aapi%3A%2A%20urn%3Amatrix%3Aclient%3Adevice%3AAABBBCCCDDD
Device authorization response
The server responds with a JSON object as defined in RFC 8628 section 3.2, containing:
| Parameter | |
|---|---|
device_code |
The device verification code. |
user_code |
An end-user verification code. |
verification_uri |
The end-user verification URI on the authorization server. |
verification_uri_complete |
Optionally, the URI which doesn’t require the user to manually type the user_code, designed for non-textual transmission. |
expires_in |
The lifetime in seconds of the device_code and user_code. |
interval |
The minimum number of seconds the client should wait between polling requests to the token endpoint. If omitted, clients should default to 5. |
It is RECOMMENDED that the server provides a verification_uri_complete such
that the user does not need to type in the user_code.
Sample response:
{
"device_code": "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS",
"user_code": "WDJB-MJHT",
"verification_uri": "https://account.example.com/link",
"verification_uri_complete": "https://account.example.com/link?user_code=WDJB-MJHT",
"expires_in": 1800,
"interval": 5
}
User interaction
The client conveys the verification_uri_complete (and/or verification_uri
and user_code) to the user. How the client does this depends on the
specific device characteristics and use case. For example:
- A CLI application could display the
verification_urianduser_codeas text for the user to type into their browser on another device. - An embedded device with a screen could encode the
verification_uri_complete(with fallback toverification_uri) as a QR code for the user to scan with their phone. - A desktop application running on a platform that does not support callbacks
could launch the
verification_uri_complete(with fallback toverification_uri) in the system browser.
The user opens the verification URI in a web browser, which may be on another device, and completes authentication and authorization.
Token polling
While the user is completing authorization, the client polls the
token_endpoint for the outcome, at intervals no shorter than the interval
value from the device authorization response.
The poll request is a POST to the token_endpoint with the following
parameters, encoded as application/x-www-form-urlencoded in the body:
| Parameter | Value |
|---|---|
grant_type |
urn:ietf:params:oauth:grant-type:device_code |
device_code |
The device_code from the device authorization response. |
client_id |
The client ID returned from client registration. |
Sample token polling request:
POST /oauth2/token HTTP/1.1
Host: account.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS&client_id=s6BhdRkqt3
The server responds as defined in RFC 8628 section 3.5:
- While authorization is pending, the server returns an
authorization_pendingerror (orslow_downif the client is polling too frequently). - If authorization is denied, the server returns an
access_deniederror. - If the device code expires, the server returns an
expired_tokenerror. - On successful authorization, the server returns a JSON object containing the access token, token type, expiration time, refresh token, and scope:
{
"access_token": "2YotnFZFEjr1zCsicMWpAA",
"token_type": "Bearer",
"expires_in": 299,
"refresh_token": "tGz3JOkF0XG5Qx2TlKWIA",
"scope": "urn:matrix:client:api:* urn:matrix:client:device:AAABBBCCCDDD"
}
Finally, the client can call the /whoami
endpoint to get the user ID that owns the access token.
Token refresh flow
Refreshing a token with the OAuth 2.0 API should be done with the refresh token grant.
When the access token expires, the client must refresh it by making a POST
request to the token_endpoint with the following parameters, encoded as
application/x-www-form-urlencoded in the body:
| Parameter | Value |
|---|---|
grant_type |
refresh_token |
refresh_token |
The refresh_token obtained from the token response during the last token request. |
client_id |
The client ID returned from client registration. |
The server replies with a JSON object containing the new access token, the token type, the expiration time, and a new refresh token, like in the authorization flow.
Server metadata discovery
GET
/_matrix/client/v1/auth_metadata
Gets the OAuth 2.0 authorization server metadata, as defined in RFC 8414, including the endpoint URLs and the supported parameters that can be used by the clients.
This endpoint definition includes only the fields that are meaningful in the context of the Matrix specification. The full list of possible fields is available in the OAuth Authorization Server Metadata registry, and normative definitions of them are available in their respective RFCs.
The authorization server metadata is relatively large and may change over time. Clients should:
- Cache the metadata appropriately based on HTTP caching headers
- Refetch the metadata if it is stale
| Rate-limited: | No |
|---|---|
| Requires authentication: | No |
Request
No request parameters or request body.
Responses
| Status | Description |
|---|---|
200 |
The OAuth 2.0 authorization server metadata. |
404 |
With M_UNRECOGNIZED: the homeserver does not support the OAuth 2.0 API.
(See Authentication API discovery.) |
200 response
| Name | Type | Description |
|---|---|---|
account_management_actions_supported |
[string] |
List of actions that the account management URL supports. This is an extension defined in this specification. Added in |
account_management_uri |
URI |
The URL where the user is able to access the account management capabilities of the homeserver. This is an extension defined in this specification. Added in |
authorization_endpoint |
URI |
Required: URL of the authorization endpoint, necessary to use the authorization code grant. |
code_challenge_methods_supported |
[string] |
Required: List of OAuth 2.0 Proof Key for Code Exchange (PKCE) code challenge methods that the server supports at the authorization endpoint. This array MUST contain at least the |
device_authorization_endpoint |
URI |
URL of the device authorization endpoint, as defined in RFC 8628, necessary to use the device authorization grant. Added in |
grant_types_supported |
[string] |
Required: List of OAuth 2.0 grant type strings that the server supports at the token endpoint. This array MUST contain at least the [Added in |
issuer |
URI |
Required: The authorization server’s issuer identifier, which is a URL that uses the
This is not used in the context of the Matrix specification, but is required by RFC 8414. |
prompt_values_supported |
[string] |
List of OpenID Connect prompt values that the server supports at the authorization endpoint. Only the |
registration_endpoint |
URI |
Required: URL of the client registration endpoint, necessary to perform dynamic registration of a client. |
response_modes_supported |
[string] |
Required: List of OAuth 2.0 response mode strings that the server supports at the authorization endpoint. This array MUST contain at least the |
response_types_supported |
[string] |
Required: List of OAuth 2.0 response type strings that the server supports at the authorization endpoint. This array MUST contain at least the |
revocation_endpoint |
URI |
Required: URL of the revocation endpoint, necessary to log out a client by invalidating its access and refresh tokens. |
token_endpoint |
URI |
Required: URL of the token endpoint, used by the grants. |
{
"account_management_actions_supported": [
"org.matrix.profile",
"org.matrix.devices_list",
"org.matrix.device_view",
"org.matrix.device_delete",
"org.matrix.account_deactivate",
"org.matrix.cross_signing_reset"
],
"account_management_uri": "https://account.example.com/manage",
"authorization_endpoint": "https://account.example.com/oauth2/auth",
"code_challenge_methods_supported": [
"S256"
],
"device_authorization_endpoint": "https://account.example.com/oauth2/device",
"grant_types_supported": [
"authorization_code",
"refresh_token",
"urn:ietf:params:oauth:grant-type:device_code"
],
"issuer": "https://account.example.com/",
"registration_endpoint": "https://account.example.com/oauth2/clients/register",
"response_modes_supported": [
"query",
"fragment"
],
"response_types_supported": [
"code"
],
"revocation_endpoint": "https://account.example.com/oauth2/revoke",
"token_endpoint": "https://account.example.com/oauth2/token"
}
404 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: An error code. |
error |
string |
A human-readable error message. |
{
"errcode": "M_UNRECOGNIZED",
"error": "Legacy authentication is in use on this homeserver."
}
Client registration
Before being able to use the authorization flow to obtain an access token, a
client needs to obtain a client_id by registering itself with the server.
This should be done via OAuth 2.0 Dynamic Client Registration as defined in RFC 7591.
Client metadata
In OAuth 2.0, clients register a set of metadata values with the authorization
server, which associates it with a newly generated client_id. These values are
used to describe the client to the user and define how the client interacts with
the server.
OAuthClientMetadata
OAuthClientMetadata
This definition of the metadata specifies only the fields that are meaningful in the context of the Matrix specification. All the possible values are registered in the OAuth Dynamic Client Registration Metadata registry, and normative definitions of them are available in their respective RFCs.
| Name | Type | Description |
|---|---|---|
application_type |
string |
Kind of the application. The homeserver MUST support the Defaults to |
client_name |
string |
Human-readable name of the client to be presented to the user. This field can be localized. |
client_uri |
URI |
Required: A URL to a valid web page that SHOULD give the user more information about the client. This URL MUST use the The server MAY reject client registrations if this field is invalid or missing. This URI is a common base for all the other URIs in the metadata: those
MUST be either on the same host or on a subdomain of the host of the
For example, if the |
grant_types |
[string] |
Array of the OAuth 2.0 grant types that the client may use. This MUST include:
The server MUST ignore values that it does not understand. |
logo_uri |
URI |
URL that references a logo for the client. This URL MUST use the This field can be localized. |
policy_uri |
URI |
URL that points to a human-readable policy document for the client. This URL MUST use the If this field is set, the server SHOULD show or link to this URL. This field can be localized. |
redirect_uris |
[URI] |
Array of redirection URIs for use in redirect-based flows. At least one URI is required to use the authorization code grant. The server MUST perform validation on redirect URIs. |
response_types |
[string] |
Array of the OAuth 2.0 response types that the client may use. This MUST include the The server MUST ignore values that it does not understand. |
token_endpoint_auth_method |
string |
String indicator of the requested authentication method for the token endpoint. The homeserver MUST support the |
tos_uri |
URI |
URL that points to a human-readable terms of service document for the client. This URL MUST use the If this field is set, the server SHOULD show or link to this URL. This field can be localized. |
Metadata localization
As per RFC 7591 section 2.2, all the human-readable metadata values MAY be localized.
The human-readable values include:
client_namelogo_uritos_uripolicy-uri
For example:
{
"client_name": "Digital mailbox",
"client_name#en-US": "Digital mailbox",
"client_name#en-GB": "Digital postbox",
"client_name#fr": "Boîte aux lettres numérique",
"tos_uri": "https://example.com/tos.html",
"tos_uri#fr": "https://example.com/fr/tos.html",
"policy_uri": "https://example.com/policy.html",
"policy_uri#fr": "https://example.com/fr/policy.html"
}
Redirect URI validation
The redirect URI plays a critical role in validating the authenticity of the client. The client “proves” its identity by demonstrating that it controls the redirect URI. This is why it is critical to have strict validation of the redirect URI.
The application_type metadata is used to determine the type of client.
In all cases, the redirect URI MUST NOT have a fragment component.
Web clients
web clients can use redirect URIs that:
- MUST use the
httpsscheme. - MUST NOT use a user or password in the authority component of the URI.
- MUST use the client URI as a common base for the authority component, as defined previously.
- MAY include an
application/x-www-form-urlencodedformatted query component.
For example, with https://example.com/ as the client URI, the following are
valid redirect URIs:
https://example.com/callbackhttps://app.example.com/callbackhttps://example.com:5173/?query=value
With the same client URI, the following are invalid redirect URIs:
https://example.com/callback#fragmenthttp://example.com/callbackhttp://localhost/
Native clients
native clients can use three types of redirect URIs:
-
Private-Use URI Scheme
- The scheme MUST be prefixed with the client URI hostname in reverse-DNS
notation. For example, if the client URI is
https://example.com/, then a valid custom URI scheme would becom.example.app:/. - There MUST NOT be an authority component. This means that the URI MUST have either a single slash or none immediately following the scheme, with no hostname, username, or port.
- The scheme MUST be prefixed with the client URI hostname in reverse-DNS
notation. For example, if the client URI is
-
httpURI on the loopback interface- The scheme MUST be
http. - The host part MUST be
localhost,127.0.0.1, or[::1]. - There MUST NOT be a port. The homeserver MUST then accept any port number during the authorization flow.
- The scheme MUST be
-
Claimed
httpsScheme URISome operating systems allow apps to claim
httpsscheme URIs in the domains they control. When the browser encounters a claimed URI, instead of the page being loaded in the browser, the native app is launched with the URI supplied as a launch parameter. The same rules as forwebclients apply.
These restrictions are the same as defined by RFC 8252 section 7.
For example, with https://example.com/ as the client URI,
These are valid redirect URIs:
com.example.app:/callbackcom.example:/com.example:callbackhttp://localhost/callbackhttp://127.0.0.1/callbackhttp://[::1]/callback
These are invalid redirect URIs:
example:/callbackcom.example.app://callbackhttps://localhost/callbackhttp://localhost:1234/callback
Dynamic client registration flow
To register, the client sends an HTTP POST request to the
registration_endpoint, which can be found in the server metadata.
The body of the request is the JSON-encoded OAuthClientMetadata.
For example, the client could send the following registration request:
POST /register HTTP/1.1
Content-Type: application/json
Accept: application/json
Server: auth.example.com
{
"client_name": "My App",
"client_name#fr": "Mon application",
"client_uri": "https://example.com/",
"logo_uri": "https://example.com/logo.png",
"tos_uri": "https://example.com/tos.html",
"tos_uri#fr": "https://example.com/fr/tos.html",
"policy_uri": "https://example.com/policy.html",
"policy_uri#fr": "https://example.com/fr/policy.html",
"redirect_uris": ["https://app.example.com/callback"],
"token_endpoint_auth_method": "none",
"response_types": ["code"],
"grant_types": [
"authorization_code",
"refresh_token",
"urn:ietf:params:oauth:grant-type:token-exchange"
],
"application_type": "web"
}
Upon successful registration, the server replies with an HTTP 201 Created
response, with a JSON object containing the allocated client_id and all the
registered metadata values.
With the registration request above, the server might reply with:
{
"client_id": "s6BhdRkqt3",
"client_name": "My App",
"client_uri": "https://example.com/",
"logo_uri": "https://example.com/logo.png",
"tos_uri": "https://example.com/tos.html",
"policy_uri": "https://example.com/policy.html",
"redirect_uris": ["https://app.example.com/callback"],
"token_endpoint_auth_method": "none",
"response_types": ["code"],
"grant_types": ["authorization_code", "refresh_token"],
"application_type": "web"
}
In this example, the server has not registered the locale-specific values for
client_name, tos_uri, and policy_uri, which is why they are not present in
the response. The server also does not support the
urn:ietf:params:oauth:grant-type:token-exchange grant type, which is why it is
not present in the response.
The client MUST store the client_id for future use.
To avoid the number of client registrations growing over time, the server MAY choose to delete client registrations that don’t have an active session. The server MUST NOT delete client registrations that have an active session.
Clients MUST perform a new client registration at the start of each authorization flow.
Because each client on each user device will do its own registration, they may
all have different client_ids. This means that the server may store the same
client registration multiple times, which could lead to a large number of client
registrations.
This can be mitigated by de-duplicating client registrations that have identical
metadata. By doing so, different users on different devices using the same
client can share a single client_id, reducing the overall number of
registrations.
Scope
The client requests a scope in the OAuth 2.0 authorization flow, which is then associated to the generated access and refresh tokens. This provides a framework for obtaining user consent.
A scope is defined in RFC 6749 section 3.3 as a string containing a list of space-separated scope tokens.
The framework encourages the practice of obtaining additional user consent when a client asks for a new scope that was not granted previously. This could be used by future MSCs to replace the legacy User-Interactive Authentication API.
Scope token format
All scope tokens related to Matrix should start with urn:matrix: and use the
: delimiter for further sub-division.
Scope tokens related to mapping of Client-Server API access levels should start
with urn:matrix:client:.
For MSCs that build on this namespace, unstable subdivisions should be used
whilst in development. For example, if MSCXXXX wants to introduce the
urn:matrix:client:foo scope, it could use
urn:matrix:client:com.example.mscXXXX.foo during development.
If it needs to introduce multiple scopes, like urn:matrix:client:foo and
urn:matrix:client:bar, it could use
urn:matrix:client:com.example.mscXXXX:foo and
urn:matrix:client:com.example.mscXXXX:bar.
Allocated scope tokens
This specification defines the following scope tokens:
Full client-server API read/write access
| Scope | Purpose |
|---|---|
urn:matrix:client:api:* |
Grants full access to the Client-Server API. |
This token matches the behavior of the legacy authentication API. Future MSCs
could introduce more fine-grained scope tokens like
urn:matrix:client:api:read:* for read-only access.
Device ID allocation
| Scope | Purpose |
|---|---|
urn:matrix:client:device:<device_id> |
Allocates the given device_id and associates it to the generated access and refresh tokens. |
Contrary to the legacy login and registration APIs where the homeserver is
typically the one generating a device_id and providing it to the client, with
the OAuth 2.0 API, the client is responsible for allocating the device_id.
There MUST be exactly one urn:matrix:client:device:<device_id> token in the
requested scope in the login flow.
When generating a new device_id, the client SHOULD generate a random string
with enough entropy. It SHOULD only use characters from the unreserved character
list defined by RFC 3986 section 2.3:
unreserved = a-z / A-Z / 0-9 / "-" / "." / "_" / "~"
Using this alphabet, a 10 character string is enough to stand a sufficient
chance of being unique per user. The homeserver MAY reject a request for a
device_id that is not long enough or contains characters outside the
unreserved list.
In any case it MUST only use characters allowed by the OAuth 2.0 scope definition in RFC 6749 section 3.3, which is defined as the following ASCII ranges:
%x21 / %x23-5B / %x5D-7E
This definition matches:
- alphanumeric characters:
A-Z,a-z,0-9 - the following characters:
! # $ % & ' ( ) * + , - . / : ; < = > ? @ [ ] ^ _ ` { | } ~
Grant types
RFC 6749 and other RFCs define several “grant types”: ways to obtain an “access token”.
All these grants types require the client to know the following authorization server metadata:
token_endpointgrant_types_supported
The client must also have obtained a client_id by registering with the server.
This specification supports the following grant types:
- Authorization code grant
- [Added in
v1.18] Device authorization grant - Refresh token grant
Authorization code grant
As per RFC 6749 section 4.1, the authorization code grant lets the client obtain an access token through a browser redirect.
This grant requires the client to know the following authorization server metadata:
authorization_endpointresponse_types_supportedresponse_mode_supported
To use this grant, homeservers and clients MUST:
- Support the authorization code grant as per RFC 6749 section 4.1.
- Support the refresh token grant.
- Support PKCE using the
S256code challenge method as per RFC 7636. - Use pre-registered, strict redirect URIs.
- Use the
fragmentresponse mode as per OAuth 2.0 Multiple Response Type Encoding Practices for clients with an HTTPS redirect URI.
Device authorization grant
[Added in v1.18]
As per RFC 8628, the device authorization grant lets clients on devices with limited input capabilities obtain an access token by having the user complete authorization on a separate device with a web browser.
This grant requires the client to know the following authorization server metadata:
device_authorization_endpoint
To use this grant, homeservers and clients MUST:
- Support the device authorization grant as per RFC 8628.
- Support the refresh token grant.
As with the authorization code grant, when authorization is granted to a client, the homeserver MUST issue a refresh token to the client in addition to the access token. The access token and refresh token have the same lifetime constraints as described in the refresh token grant section.
The full flow for using this grant is described in the device authorization flow.
Refresh token grant
As per RFC 6749 section 6, the refresh token grant lets the client exchange a refresh token for an access token.
When authorization is granted to a client, the homeserver MUST issue a refresh token to the client in addition to the access token.
The access token MUST be short-lived and SHOULD be refreshed using the
refresh_token when expired.
The homeserver SHOULD issue a new refresh token each time an old one is used, and invalidate the old one. However, it MUST ensure that the client is able to retry the refresh request in the case that the response to the request is lost.
The homeserver SHOULD consider that the session is compromised if an old, invalidated refresh token is used, and SHOULD revoke the session.
The client MUST handle access token refresh failures as follows:
- If the refresh fails due to network issues or a
5xxHTTP status code from the server, the client should retry the request with the old refresh token later. - If the refresh fails due to a
4xxHTTP status code from the server, the client should consider the session logged out.
Token revocation
When a user wants to log out from a client, the client SHOULD use OAuth 2.0 token revocation as defined in RFC 7009.
The client makes a POST request to the revocation_endpoint that can be found
in the authorization server metadata.
The body of the request includes the following parameters, encoded as
application/x-www-form-urlencoded:
| Parameter | Value |
|---|---|
token |
Required. MUST contain either the access token or the refresh token to be revoked. |
token_type_hint |
Optional. If present, MUST have a value of either
access_token or refresh_token. The server MAY
use this value to optimize the token lookup process.
|
client_id |
Optional. The client identifier obtained during client registration.
If the |
For example, revoking using the access token:
POST /oauth2/revoke HTTP/1.1
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded
token=mat_ooreiPhei2wequu9fohkai3AeBaec9oo&
token_type_hint=access_token&
client_id=s6BhdRkqt3
The server MUST revoke both the access token and refresh token associated with the token provided in the request.
The server SHOULD return one of the following responses:
- If the token is already revoked or invalid, the server returns a
200 OKresponse - If the client is not authorized to revoke the token, the server returns a
401 Unauthorizedresponse - For other errors, the server returns a
400 Bad Requestresponse with error details
User registration
Clients can signal to the server that the user desires to register a new account
by initiating the authorization code grant with the prompt=create parameter
set in the authorization request as defined in Initiating User Registration via
OpenID Connect 1.0.
Whether the homeserver supports this parameter is advertised by the
prompt_values_supported authorization server metadata.
Servers that support this parameter SHOULD show the account registration UI in the browser.
The prompt=create parameter is not supported when using the device
authorization grant.
Account management
[Added in v1.18]
All account management is done via the homeserver’s web UI.
This specification defines extensions to the OAuth Authorization Server Metadata registry to offer clients a way to deep-link to the account management capabilities of the homeserver to allow the user to complete the account management operations in a browser.
Account management URL discovery
The OAuth 2.0 authorization server metadata is extended to include the following optional fields.
OAuth 2.0 Server Metadata Account Management Extension
OAuth 2.0 Server Metadata Account Management Extension
| Name | Type | Description |
|---|---|---|
account_management_actions_supported |
[string] |
List of actions that the account management URL supports. |
account_management_uri |
URI |
The URL where the user is able to access the account management capabilities of the server. |
Account management URL parameters
The account management URL MAY accept the following minimum query parameters.
OAuth 2.0 Account Management URL Query Parameters
OAuth 2.0 Account Management URL Query Parameters
| Name | Type | Description |
|---|---|---|
action |
string |
The action that the user wishes to take. Must match one of the actions advertised by the
server in |
device_id |
string |
For Matrix-specific actions, the user’s device ID. Actions which don’t support the device ID will ignore it. If the |
Account management URL actions
Account management actions are unique to the application. They SHOULD follow the Common Namespaced Identifier Grammar where feasible. The Matrix-specific actions are:
| Action | Description |
|---|---|
org.matrix.profile |
The user wishes to view/edit their profile (name, avatar, contact details). |
org.matrix.devices_list |
The user wishes to view a list of their devices. |
org.matrix.device_view |
The user wishes to view the details of a specific device. A device_id SHOULD be provided. |
org.matrix.device_delete |
The user wishes to delete/log out a specific device. A device_id SHOULD be provided. |
org.matrix.account_deactivate |
The user wishes to deactivate their account. |
org.matrix.cross_signing_reset |
The user wishes to reset their cross-signing identity. Servers SHOULD use this action in the URL of the m.oauth UIA type. |
Account moderation
Account locking
[Added in v1.12]
Server administrators may apply locks to prevent users from usefully using their accounts, for instance, due to safety or security concerns. In contrast to account deactivation, locking is a non-destructive action that can be reversed.
[Added in v1.18] To lock or unlock an account, administrators
SHOULD use the PUT /admin/lock/{userId}
endpoint. They MAY also use GET /admin/lock/{userId}
to check whether a user’s account is locked.
When an account is locked, servers MUST return a 401 Unauthorized error
response with an M_USER_LOCKED error code and soft_logout
set to true on all but the following Client-Server APIs:
Servers MAY additionally include details of why the lock was applied in
the error field.
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
"errcode": "M_USER_LOCKED",
"error": "This account has been locked",
"soft_logout": true
}
Servers SHOULD NOT invalidate access tokens on locked accounts unless the client requests a logout (using the above endpoints). This ensures that users can retain their sessions without having to log back in if the account becomes unlocked.
Upon receiving an M_USER_LOCKED error, clients SHOULD retain session
information including encryption state and inform the user that their account
has been locked. While the lock is applied, clients SHOULD hide the normal UI
from the user, preventing general use of their account. Clients SHOULD, however,
continue to make rate-limited requests to /sync
and other APIs to detect when the lock has been lifted.
To enable users to appeal to a lock clients MAY use server contact discovery.
Account suspension
[Added in v1.13]
Server administrators MAY suspend a user’s account to prevent further activity from that account. The effect is similar to locking, though without risk of the client losing state from a logout. Suspensions are reversible, like locks and unlike deactivations.
[Added in v1.18] To suspend or unsuspend an account, administrators
SHOULD use the PUT /admin/suspend/{userId}
endpoint. They MAY also use GET /admin/suspend/{userId}
to check whether a user’s account is suspended.
The actions a user can perform while suspended is deliberately left as an implementation detail. Servers SHOULD permit the user to perform at least the following, however:
- Log in and create additional sessions (which are also suspended).
- See and receive messages, particularly through
/syncand/messages. - Verify other devices and write associated cross-signing data.
- Populate their key backup.
- Leave rooms and reject invites.
- Redact their own events.
- Log out or delete any device of theirs, including the current session.
- Deactivate their account, potentially with a time delay to discourage making a new account right away.
- Change or add admin contacts, but not remove. Servers are recommended to only permit this if they keep a changelog on contact information to prevent misuse.
General purpose endpoints like /send/{eventType}
MAY return the error described below depending on the path parameters. For example,
a user may be allowed to send m.room.redaction events but not m.room.message
events through /send.
Where a room is used to maintain communication between server administration teams and the suspended user, servers are recommended to allow the user to send events to that room specifically. Server administrators which do not want the user to continue receiving messages may be interested in account locking instead.
Otherwise, the recommended set of explicitly forbidden actions is:
- Joining or knocking on rooms.
- Accepting or sending invites.
- Sending messages to rooms.
- Changing profile data (display name and avatar, primarily).
- Redacting other users’ events, when permission is possible in a room.
When a client attempts to perform an action while suspended, the server MUST
respond with a 403 Forbidden error response with M_USER_SUSPENDED as the
error code, as shown below:
HTTP/1.1 403 Forbidden
Content-Type: application/json
{
"errcode": "M_USER_SUSPENDED",
"error": "You cannot perform this action while suspended."
}
Adding Account Administrative Contact Information
A homeserver may keep some contact information for administrative use. This is independent of any information kept by any identity servers, though can be proxied (bound) to the identity server in many cases.
This section deals with two terms: “add” and “bind”. Where “add” (or “remove”) is used, it is speaking about an identifier that was not bound to an identity server. As a result, “bind” (or “unbind”) references an identifier that is found in an identity server. Note that an identifier can be added and bound at the same time, depending on context.
GET
/_matrix/client/v3/account/3pid
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 homeserver as, for example, identifiers that it will accept to reset the user’s account password.
| Rate-limited: | No |
|---|---|
| Requires authentication: | Yes |
Request
No request parameters or request body.
Responses
| Status | Description |
|---|---|
200 |
The lookup was successful. |
200 response
| Name | Type | Description |
|---|---|---|
threepids |
[Third-party identifier] |
| Name | Type | Description |
|---|---|---|
added_at |
integer |
Required: The timestamp, in milliseconds, when the homeserver associated the third-party identifier with the user. |
address |
string |
Required: The third-party identifier address. |
medium |
string |
Required: The medium of the third-party identifier. One of: |
validated_at |
integer |
Required: The timestamp, in milliseconds, when the identifier was validated by the identity server. |
{
"threepids": [
{
"added_at": 1535336848756,
"address": "[email protected]",
"medium": "email",
"validated_at": 1535176800000
}
]
}
POST
/_matrix/client/v3/account/3pid
Adds contact information to the user’s account.
This endpoint is deprecated in favour of the more specific /3pid/add
and /3pid/bind endpoints.
Note:
Previously this endpoint supported a bind parameter. This parameter
has been removed, making this endpoint behave as though it was false.
This results in this endpoint being an equivalent to /3pid/bind rather
than dual-purpose.
This endpoint uses capabilities negotiation.
Clients SHOULD check the value of the m.3pid_changes capability
to determine if this endpoint is available.
| Rate-limited: | No |
|---|---|
| Requires authentication: | Yes |
Request
Request body
| Name | Type | Description |
|---|---|---|
three_pid_creds |
ThreePidCredentials |
Required: The third-party credentials to associate with the account. |
| Name | Type | Description |
|---|---|---|
client_secret |
string |
Required: The client secret used in the session with the identity server. |
id_access_token |
string |
Required: An access token previously registered with the identity server. Servers can treat this as optional to distinguish between r0.5-compatible clients and this specification version. |
id_server |
string |
Required: The identity server to use. |
sid |
string |
Required: The session identifier given by the identity server. |
Request body example
{
"three_pid_creds": {
"client_secret": "d0nt-T3ll",
"id_access_token": "abc123_OpaqueString",
"id_server": "matrix.org",
"sid": "abc123987"
}
}
Responses
| Status | Description |
|---|---|
200 |
The addition was successful. |
403 |
The credentials could not be verified with the identity server. |
200 response
| Name | Type | Description |
|---|---|---|
submit_url |
URI |
An optional field containing a URL where the client must
submit the validation token to, with identical parameters
to the Identity Service API’s If this field is not present, the client can assume that
verification will happen without the client’s involvement
provided the homeserver advertises this specification version
in the |
{
"submit_url": "https://example.org/path/to/submitToken"
}
403 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: An error code. |
error |
string |
A human-readable error message. |
{
"errcode": "M_THREEPID_AUTH_FAILED",
"error": "The third-party credentials could not be verified by the identity server."
}
POST
/_matrix/client/v3/account/3pid/add
This API endpoint uses the User-Interactive Authentication API.
Adds contact information to the user’s account. Homeservers should use 3PIDs added through this endpoint for password resets instead of relying on the identity server.
Homeservers should prevent the caller from adding a 3PID to their account if it has already been added to another user’s account on the homeserver.
This endpoint uses capabilities negotiation.
Clients SHOULD check the value of the m.3pid_changes capability
to determine if this endpoint is available.
Since this endpoint uses User-Interactive Authentication, it cannot be used when the access token was obtained via the OAuth 2.0 API.
| Rate-limited: | Yes |
|---|---|
| Requires authentication: | Yes |
Request
Request body
| Name | Type | Description |
|---|---|---|
auth |
Authentication Data |
Additional authentication information for the user-interactive authentication API. |
client_secret |
string |
Required: The client secret used in the session with the homeserver. |
sid |
string |
Required: The session identifier given by the homeserver. |
| Name | Type | Description |
|---|---|---|
session |
string |
The value of the session key given by the homeserver. |
type |
string |
The authentication type that the client is attempting to complete.
May be omitted if |
| <Other properties> | |
Keys dependent on the login type |
Request body example
{
"auth": {
"example_credential": "verypoorsharedsecret",
"session": "xxxxx",
"type": "example.type.foo"
},
"client_secret": "d0nt-T3ll",
"sid": "abc123987"
}
Responses
| Status | Description |
|---|---|
200 |
The addition was successful. |
401 |
The homeserver requires additional authentication information. |
429 |
This request was rate-limited. |
200 response
{}
401 response
| Name | Type | Description |
|---|---|---|
completed |
[string] |
A list of the stages the client has completed successfully |
flows |
[Flow information] |
Required: A list of the login flows supported by the server for this API. |
params |
{string: object} |
Contains any information that the client will need to know in order to use a given type of authentication. For each login type presented, that type may be present as a key in this dictionary. For example, the public part of an OAuth client ID could be given here. |
session |
string |
This is a session identifier that the client must pass back to the home server, if one is provided, in subsequent attempts to authenticate in the same API call. |
| Name | Type | Description |
|---|---|---|
stages |
[string] |
Required: The login type of each of the stages required to complete this authentication flow |
{
"completed": [
"example.type.foo"
],
"flows": [
{
"stages": [
"example.type.foo"
]
}
],
"params": {
"example.type.baz": {
"example_key": "foobar"
}
},
"session": "xxxxxxyz"
}
429 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: The M_LIMIT_EXCEEDED error code |
error |
string |
A human-readable error message. |
retry_after_ms |
integer |
The amount of time in milliseconds the client should wait before trying the request again. |
{
"errcode": "M_LIMIT_EXCEEDED",
"error": "Too many requests",
"retry_after_ms": 2000
}
POST
/_matrix/client/v3/account/3pid/bind
Binds a 3PID to the user’s account through the specified identity server.
Homeservers should not prevent this request from succeeding if another user has bound the 3PID. Homeservers should simply proxy any errors received by the identity server to the caller.
Homeservers should track successful binds so they can be unbound later.
| Rate-limited: | Yes |
|---|---|
| Requires authentication: | Yes |
Request
Request body
| Name | Type | Description |
|---|---|---|
client_secret |
string |
Required: The client secret used in the session with the identity server. |
id_access_token |
string |
Required: An access token previously registered with the identity server. |
id_server |
string |
Required: The identity server to use. |
sid |
string |
Required: The session identifier given by the identity server. |
Request body example
{
"client_secret": "d0nt-T3ll",
"id_access_token": "abc123_OpaqueString",
"id_server": "example.org",
"sid": "abc123987"
}
Responses
| Status | Description |
|---|---|
200 |
The addition was successful. |
429 |
This request was rate-limited. |
200 response
{}
429 response
| Name | Type | Description |
|---|---|---|
errcode |
string |
Required: The M_LIMIT_EXCEEDED error code |
error |
string |
A human-readable error message. |
retry_after_ms |
integer |
The amount of time in milliseconds the client should wait before trying the request again. |
{
"errcode": "M_LIMIT_EXCEEDED",
"error": "Too many requests",
"retry_after_ms": 2000
}
POST
/_matrix/client/v3/account/3pid/delete
Removes a third-party identifier from the user’s account. This might not cause an unbind of the identifier from the identity server.
Unlike other endpoints, this endpoint does not take an id_access_token
parameter because the homeserver is expected to sign the request to the
identity server instead.
This endpoint uses capabilities negotiation.
Clients SHOULD check the value of the m.3pid_changes capability
to determine if this endpoint is available.
| Rate-limited: | No |
|---|---|
| Requires authentication: | Yes |
Request
Request body
| Name | Type | Description |
|---|---|---|
address |
string |
Required: The third-party address being removed. |
id_server |
string |
The identity server to unbind from. If not provided, the homeserver
MUST use the |
medium |
string |
Required: The medium of the third-party identifier being removed. One of: |
Request body example
{
"address": "[email protected]",
"id_server": "example.org",
"medium": "email"
}
Responses
| Status | Description |
|---|---|
200 |
The homeserver has disassociated the third-party identifier from the user. |
200 response
| Name | Type | Description |
|---|---|---|
id_server_unbind_result |
string |
Required: An indicator as to whether or not the homeserver was able to unbind
the 3PID from the identity server. One of: |
{
"id_server_unbind_result": "success"
}
POST
/_matrix/client/v3/account/3pid/email/requestToken
The homeserver must check that the given email address is not
already associated with an account on this homeserver. This API should
be used to request validation tokens when adding an email address to an
account. This API’s parameters and response are identical to that of
the /register/email/requestToken
endpoint. The homeserver should validate
the email itself, either by sending a validation email itself or by using
a service it has control over.
| Rate-limited: | No |
|---|---|
| Requires authentication: | No |
Request
Request body
| Name | Type | Description |
|---|---|---|
client_secret |
string |
Required: A unique string generated by the client, and used to identify the
validation attempt. It must be a string consisting of the characters
|
email |
Email Address |
Required: The email address to validate. |
id_access_token |
string |
An access token previously registered with the identity server. Servers can treat this as optional to distinguish between r0.5-compatible clients and this specification version. Required if an |
id_server |
string |
The hostname of the identity server to communicate with. May optionally include a port. This parameter is ignored when the homeserver handles 3PID verification. This parameter is deprecated with a plan to be removed in a future specification
version for |
next_link |
URI |
Optional. When the validation is completed, the identity server will redirect the user to this URL. This option is ignored when submitting 3PID validation information through a POST request. |
send_attempt |
integer |
Required: The server will only send an email if the |
Request body example
{
"client_secret": "monkeys_are_GREAT",
"email": "[email protected]",
"id_server": "id.example.com",
"next_link": "https://example.org/congratulations.html",
"send_attempt": 1
}
Responses
| Status | Description |
|---|---|
200 |
An email was sent to the given address. Note that this may be an email containing the validation token or it may be informing the user of an error. |
400 |
The third-party identifier is already in use on the homeserver, or the request was invalid. Error codes that can be returned are:
|
403 |
The homeserver does not allow the third-party identifier as a contact option. |
200 response
| Name | Type | Description |
|---|---|---|
sid |
string |
Required: The session ID. Session IDs are opaque strings that must consist entirely
of the characters |
submit_url |
URI |
An optional field containing a URL where the client must submit the
validation token, with identical request and response parameters and error
codes to the Identity Service API’s
|