# Copyright 2019-2020 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
swagger: '2.0'
info:
  title: "Matrix Client-Server Key Backup API"
  version: "1.0.0"
host: localhost:8008
schemes:
  - https
  - http
basePath: /_matrix/client/%CLIENT_MAJOR_VERSION%
consumes:
  - application/json
produces:
  - application/json
securityDefinitions:
  $ref: definitions/security.yaml
paths:
  "/room_keys/version":
    post:
      summary: Create a new backup.
      description: |-
        Creates a new backup.
      operationId: postRoomKeysVersion
      security:
        - accessToken: []
      parameters:
        - in: body
          name: version
          description: "The backup configuration."
          required: true
          schema:
            type: object
            properties:
              algorithm:
                description: The algorithm used for storing backups.
                type: string
                enum: ["m.megolm_backup.v1.curve25519-aes-sha2"]
                example: "m.megolm_backup.v1.curve25519-aes-sha2"
              auth_data:
                description: |-
                  Algorithm-dependent data. See the documentation for the backup
                  algorithms in `Server-side key backups`_ for more information on the
                  expected format of the data.
                type: object
                example: {
                  "public_key": "abcdefg",
                  "signatures": {
                    "@alice:example.org": {
                      "ed25519:deviceid": "signature"
                    }
                  }
                }
            required:
              - algorithm
              - auth_data
      responses:
        200:
          description:
            The version id of the new backup.
          schema:
            type: object
            properties:
              version:
                type: string
                description: The backup version. This is an opaque string.
                example: "1"
            required:
              - version
        429:
          description: This request was rate-limited.
          schema:
            "$ref": "definitions/errors/rate_limited.yaml"
      tags:
        - End-to-end encryption
    get:
      summary: Get information about the latest backup version.
      description: |-
        Get information about the latest backup version.
      operationId: getRoomKeysVersionCurrent
      security:
        - accessToken: []
      responses:
        200:
          description:
            The information about the backup.
          schema:
            type: object
            properties:
              algorithm:
                type: string
                description: The algorithm used for storing backups.
                enum: ["m.megolm_backup.v1.curve25519-aes-sha2"]
                example: "m.megolm_backup.v1.curve25519-aes-sha2"
              auth_data:
                description: |-
                  Algorithm-dependent data. See the documentation for the backup
                  algorithms in `Server-side key backups`_ for more information on the
                  expected format of the data.
                type: object
                example: {
                  "public_key": "abcdefg",
                  "signatures": {
                    "@alice:example.org": {
                      "ed25519:deviceid": "signature"
                    }
                  }
                }
              count:
                description: The number of keys stored in the backup.
                type: integer
                example: 42
              etag:
                description: |-
                  An opaque string representing stored keys in the backup.
                  Clients can compare it with the ``etag`` value they received
                  in the request of their last key storage request.  If not
                  equal, another client has modified the backup.
                type: string
                example: "anopaquestring"
              version:
                type: string
                description: The backup version.
                example: "1"
            required:
              - algorithm
              - auth_data
              - count
              - etag
              - version
        404:
          description:
            No backup exists.
          examples:
            application/json: {
              "errcode": "M_NOT_FOUND",
              "error": "No current backup version"
            }
          schema:
            "$ref": "definitions/errors/error.yaml"
        429:
          description: This request was rate-limited.
          schema:
            "$ref": "definitions/errors/rate_limited.yaml"
      tags:
        - End-to-end encryption
  "/room_keys/version/{version}":
    get:
      summary: Get information about an existing backup.
      description: |-
        Get information about an existing backup.
      operationId: getRoomKeysVersion
      security:
        - accessToken: []
      parameters:
        - in: path
          type: string
          name: version
          description: |-
            The backup version to get, as returned in the ``version`` parameter
            of the response in `POST /_matrix/client/r0/room_keys/version`_ or
            this endpoint.
          required: true
          x-example: "1"
      responses:
        200:
          description:
            The information about the requested backup.
          schema:
            type: object
            properties:
              algorithm:
                type: string
                description: The algorithm used for storing backups.
                enum: ["m.megolm_backup.v1.curve25519-aes-sha2"]
                example: "m.megolm_backup.v1.curve25519-aes-sha2"
              auth_data:
                description: |-
                  Algorithm-dependent data. See the documentation for the backup
                  algorithms in `Server-side key backups`_ for more information on the
                  expected format of the data.
                type: object
                example: {
                  "public_key": "abcdefg",
                  "signatures": {
                    "@alice:example.org": {
                      "ed25519:deviceid": "signature"
                    }
                  }
                }
              count:
                description: The number of keys stored in the backup.
                type: integer
                example: 42
              etag:
                description: |-
                  An opaque string representing stored keys in the backup.
                  Clients can compare it with the ``etag`` value they received
                  in the request of their last key storage request.  If not
                  equal, another client has modified the backup.
                type: string
                example: "anopaquestring"
              version:
                type: string
                description: The backup version.
                example: "1"
            required:
              - algorithm
              - auth_data
              - count
              - etag
              - version
        404:
          description:
            The backup specified does not exist.
          examples:
            application/json: {
              "errcode": "M_NOT_FOUND",
              "error": "Unknown backup version"
            }
          schema:
            "$ref": "definitions/errors/error.yaml"
        429:
          description: This request was rate-limited.
          schema:
            "$ref": "definitions/errors/rate_limited.yaml"
      tags:
        - End-to-end encryption
    put:
      summary: Update information about an existing backup.
      description: |-
        Update information about an existing backup.  Only ``auth_data`` can be modified.
      operationId: putRoomKeysVersion
      security:
        - accessToken: []
      parameters:
        - in: path
          type: string
          name: version
          description: |-
            The backup version to update, as returned in the ``version``
            parameter in the response of `POST
            /_matrix/client/r0/room_keys/version`_ or `GET
            /_matrix/client/r0/room_keys/version/{version}`_.
          required: true
          x-example: "1"
        - in: body
          name: version
          description: "The backup configuration"
          required: true
          schema:
            type: object
            properties:
              algorithm:
                description: |-
                  The algorithm used for storing backups.  Must be the same as
                  the algorithm currently used by the backup.
                type: string
                enum: ["m.megolm_backup.v1.curve25519-aes-sha2"]
                example: "m.megolm_backup.v1.curve25519-aes-sha2"
              auth_data:
                description: |-
                  Algorithm-dependent data. See the documentation for the backup
                  algorithms in `Server-side key backups`_ for more information on the
                  expected format of the data.
                type: object
                example: {
                  "public_key": "abcdefg",
                  "signatures": {
                    "@alice:example.org": {
                      "ed25519:deviceid": "signature"
                    }
                  }
                }
              version:
                description: |-
                  The backup version.  If present, must be the same as the
                  version in the path parameter.
                type: string
                example: "1"
            required:
              - algorithm
              - auth_data
      responses:
        200:
          description: The update succeeded.
          schema:
            type: object
            properties: {}
        400:
          description: |-
            A parameter was incorrect.  For example, the ``algorithm`` does not
            match the current backup algorithm, or the ``version`` in the body
            does not match the ``version`` in the path.
          examples:
            application/json: {
              "errcode": "M_INVALID_PARAM",
              "error": "Algorithm does not match"
            }
          schema:
            "$ref": "definitions/errors/error.yaml"
        404:
          description: The backup specified does not exist.
          examples:
            application/json: {
              "errcode": "M_NOT_FOUND",
              "error": "Unknown backup version"
            }
          schema:
            "$ref": "definitions/errors/error.yaml"
        429:
          description: This request was rate-limited.
          schema:
            "$ref": "definitions/errors/rate_limited.yaml"
      tags:
        - End-to-end encryption
    delete:
      summary: Delete an existing key backup.
      description: |-
        Delete an existing key backup. Both the information about the backup,
        as well as all key data related to the backup will be deleted.
      operationId: deleteRoomKeysVersion
      security:
        - accessToken: []
      parameters:
        - in: path
          type: string
          name: version
          description: |-
            The backup version to delete, as returned in the ``version``
            parameter in the response of `POST
            /_matrix/client/r0/room_keys/version`_ or `GET
            /_matrix/client/r0/room_keys/version/{version}`_.
          required: true
          x-example: "1"
      responses:
        200:
          description: |-
            The delete succeeded, or the specified backup was previously
            deleted.
          schema:
            type: object
            properties: {}
        404:
          description: |-
            The backup specified does not exist. If the backup was previously
            deleted, the call should succeed rather than returning an error.
          examples:
            application/json: {
              "errcode": "M_NOT_FOUND",
              "error": "Unknown backup version"
            }
          schema:
            "$ref": "definitions/errors/error.yaml"
        429:
          description: This request was rate-limited.
          schema:
            "$ref": "definitions/errors/rate_limited.yaml"
      tags:
        - End-to-end encryption
  "/room_keys/keys/{roomId}/{sessionId}":
    put:
      summary: Store a key in the backup.
      description: |-
        Store a key in the backup.
      operationId: postRoomKeysKeyRoomIdSessionId
      security:
        - accessToken: []
      parameters:
        - in: query
          type: string
          name: version
          description: |-
            The backup in which to store the key. Must be the current backup.
          required: true
          x-example: "1"
        - in: path
          type: string
          name: roomId
          description: The ID of the room that the key is for.
          required: true
          x-example: "!roomid:example.org"
        - in: path
          type: string
          name: sessionId
          description: The ID of the megolm session that the key is for.
          required: true
          x-example: "sessionid"
        - in: body
          name: data
          description: "The key data."
          required: true
          schema:
            "$ref": "definitions/key_backup_data.yaml"
      responses:
        200:
          description: The update succeeded.
          schema:
            type: object
            properties:
              etag:
                description: |-
                  The new etag value representing stored keys in the backup.
                  See ``GET /room_keys/version/{version}`` for more details.
                type: string
                example: "abcdefg"
              count:
                description: The number of keys stored in the backup
                type: integer
                example: 10
            required:
              - etag
              - count
        403:
          description: |-
            The version specified does not match the current backup version.
            The current version will be included in the ``current_version``
            field.
          examples:
            application/json: {
              "errcode": "M_WRONG_ROOM_KEYS_VERSION",
              "error": "Wrong backup version.",
              "current_version": "42"
            }
          schema:
            "$ref": "definitions/errors/error.yaml"
        429:
          description: This request was rate-limited.
          schema:
            "$ref": "definitions/errors/rate_limited.yaml"
      tags:
        - End-to-end encryption
    get:
      summary: Retrieve a key from the backup
      description: |-
        Retrieve a key from the backup.
      operationId: getRoomKeysKeyRoomIdSessionId
      security:
        - accessToken: []
      parameters:
        - in: query
          type: string
          name: version
          description: |-
            The backup from which to retrieve the key.
          required: true
          x-example: "1"
        - in: path
          type: string
          name: roomId
          description: The ID of the room that the requested key is for.
          required: true
          x-example: "!roomid:example.org"
        - in: path
          type: string
          name: sessionId
          description: The ID of the megolm session whose key is requested.
          required: true
          x-example: "sessionid"
      responses:
        200:
          description: The key data
          schema:
            "$ref": "definitions/key_backup_data.yaml"
        404:
          description: The key or backup was not found.
          examples:
            application/json: {
              "errcode": "M_NOT_FOUND",
              "error": "Key not found."
            }
          schema:
            "$ref": "definitions/errors/error.yaml"
        429:
          description: This request was rate-limited.
          schema:
            "$ref": "definitions/errors/rate_limited.yaml"
    delete:
      summary: Delete a key from the backup
      description: |-
        Delete a key from the backup.
      operationId: deleteRoomKeysKeyRoomIdSessionId
      security:
        - accessToken: []
      parameters:
        - in: query
          type: string
          name: version
          description: |-
            The backup from which to delete the key
          required: true
          x-example: "1"
        - in: path
          type: string
          name: roomId
          description: The ID of the room that the specified key is for.
          required: true
          x-example: "!roomid:example.org"
        - in: path
          type: string
          name: sessionId
          description: The ID of the megolm session whose key is to be deleted.
          required: true
          x-example: "sessionid"
      responses:
        200:
          description: The update succeeded
          schema:
            type: object
            properties:
              etag:
                description: |-
                  The new etag value representing stored keys in the backup.
                  See ``GET /room_keys/version/{version}`` for more details.
                type: string
                example: "abcdefg"
              count:
                description: The number of keys stored in the backup
                type: integer
                example: 10
            required:
              - etag
              - count
        404:
          description: |-
            The backup was not found.
          examples:
            application/json: {
              "errcode": "M_NOT_FOUND",
              "error": "Unknown backup version"
            }
          schema:
            "$ref": "definitions/errors/error.yaml"
        429:
          description: This request was rate-limited.
          schema:
            "$ref": "definitions/errors/rate_limited.yaml"
  "/room_keys/keys/{roomId}":
    put:
      summary: Store several keys in the backup for a given room.
      description: |-
        Store a key in the backup.
      operationId: postRoomKeysKeyRoomId
      security:
        - accessToken: []
      parameters:
        - in: query
          type: string
          name: version
          description: |-
            The backup in which to store the keys. Must be the current backup.
          required: true
          x-example: "1"
        - in: path
          type: string
          name: roomId
          description: The ID of the room that the keys are for.
          required: true
          x-example: "!roomid:example.org"
        - in: body
          description: "The backup data"
          name: backupData
          required: true
          schema:
            $ref: "definitions/room_key_backup.yaml"
      responses:
        200:
          description: The update succeeded
          schema:
            type: object
            properties:
              etag:
                description: |-
                  The new etag value representing stored keys in the backup.
                  See ``GET /room_keys/version/{version}`` for more details.
                type: string
                example: "abcdefg"
              count:
                description: The number of keys stored in the backup
                type: integer
                example: 10
            required:
              - etag
              - count
        403:
          description: |-
            The version specified does not match the current backup version.
            The current version will be included in the ``current_version``
            field.
          examples:
            application/json: {
                "errcode": "M_WRONG_ROOM_KEYS_VERSION",
                "error": "Wrong backup version.",
                "current_version": "42"
              }
          schema:
            "$ref": "definitions/errors/error.yaml"
        404:
          description: |-
            The backup was not found.
          examples:
            application/json: {
              "errcode": "M_NOT_FOUND",
              "error": "Unknown backup version"
            }
          schema:
            "$ref": "definitions/errors/error.yaml"
        429:
          description: This request was rate-limited.
          schema:
            "$ref": "definitions/errors/rate_limited.yaml"
      tags:
        - End-to-end encryption
    get:
      summary: Retrieve the keys from the backup for a given room
      description: |-
        Retrieve the keys from the backup for a given room
      operationId: getRoomKeysKeyRoomId
      security:
        - accessToken: []
      parameters:
        - in: query
          type: string
          name: version
          description: |-
            The backup from which to retrieve the key.
          required: true
          x-example: "1"
        - in: path
          type: string
          name: roomId
          description: The ID of the room that the requested key is for.
          required: true
          x-example: "!roomid:example.org"
      responses:
        200:
          description: |-
            The key data.  If no keys are found, then an object with an empty
            ``sessions`` property will be returned (``{"sessions": {}}``).
          schema:
            type: object
            $ref: "definitions/room_key_backup.yaml"
        404:
          description: |-
            The backup was not found.
          examples:
            application/json: {
              "errcode": "M_NOT_FOUND",
              "error": "Unknown backup version"
            }
          schema:
            "$ref": "definitions/errors/error.yaml"
        429:
          description: This request was rate-limited.
          schema:
            "$ref": "definitions/errors/rate_limited.yaml"
    delete:
      summary: Delete a key from the backup
      description: |-
        Delete a key from the backup.
      operationId: deleteRoomKeysKeyRoomId
      security:
        - accessToken: []
      parameters:
        - in: query
          type: string
          name: version
          description: |-
            The backup from which to delete the key.
          required: true
          x-example: "1"
        - in: path
          type: string
          name: roomId
          description: The ID of the room that the specified key is for.
          required: true
          x-example: "!roomid:example.org"
      responses:
        200:
          description: The update succeeded
          schema:
            type: object
            properties:
              etag:
                description: |-
                  The new etag value representing stored keys in the backup.
                  See ``GET /room_keys/version/{version}`` for more details.
                type: string
                example: "abcdefg"
              count:
                description: The number of keys stored in the backup
                type: integer
                example: 10
            required:
              - etag
              - count
        404:
          description: |-
            The backup was not found.
          examples:
            application/json: {
              "errcode": "M_NOT_FOUND",
              "error": "Unknown backup version"
            }
          schema:
            "$ref": "definitions/errors/error.yaml"
        429:
          description: This request was rate-limited.
          schema:
            "$ref": "definitions/errors/rate_limited.yaml"
  "/room_keys/keys":
    put:
      summary: Store several keys in the backup.
      description: |-
        Store several keys in the backup.
      operationId: postRoomKeysKey
      security:
        - accessToken: []
      parameters:
        - in: query
          type: string
          name: version
          description: |-
            The backup in which to store the keys. Must be the current backup.
          required: true
          x-example: "1"
        - in: body
          description: "The backup data."
          name: backupData
          required: true
          schema:
            type: object
            properties:
              rooms:
                type: object
                description: |-
                  A map of room IDs to room key backup data.
                additionalProperties:
                  allOf:
                    - $ref: "definitions/room_key_backup.yaml"
                example: {
                  "!room:example.org": {
                    "sessions": {
                      "sessionid1": {
                        "first_message_index": 1,
                        "forwarded_count": 0,
                        "is_verified": true,
                        "session_data": {
                          "ephemeral": "base64+ephemeral+key",
                          "ciphertext": "base64+ciphertext+of+JSON+data",
                          "mac": "base64+mac+of+ciphertext"
                        }
                      }
                    }
                  }
                }
            required:
              - rooms
      responses:
        200:
          description: The update succeeded
          schema:
            type: object
            properties:
              etag:
                description: |-
                  The new etag value representing stored keys in the backup.
                  See ``GET /room_keys/version/{version}`` for more details.
                type: string
                example: "abcdefg"
              count:
                description: The number of keys stored in the backup
                type: integer
                example: 10
            required:
              - etag
              - count
        403:
          description: |-
            The version specified does not match the current backup version.
            The current version will be included in the ``current_version``
            field.
          examples:
            application/json: {
              "errcode": "M_WRONG_ROOM_KEYS_VERSION",
              "error": "Wrong backup version.",
              "current_version": "42"
            }
          schema:
            "$ref": "definitions/errors/error.yaml"
        404:
          description: |-
            The backup was not found.
          examples:
            application/json: {
              "errcode": "M_NOT_FOUND",
              "error": "Unknown backup version"
            }
          schema:
            "$ref": "definitions/errors/error.yaml"
        429:
          description: This request was rate-limited.
          schema:
            "$ref": "definitions/errors/rate_limited.yaml"
      tags:
        - End-to-end encryption
    get:
      summary: Retrieve the keys from the backup for a given room
      description: |-
        Retrieve the keys from the backup for a given room
      operationId: getRoomKeysKeyRoomId
      security:
        - accessToken: []
      parameters:
        - in: query
          type: string
          name: version
          description: |-
            The backup from which to retrieve the keys.
          required: true
          x-example: "1"
      responses:
        200:
          description: |-
            The key data.  If no keys are found, then an object with an empty
            ``rooms`` property will be returned (``{"rooms": {}}``).
          schema:
            type: object
            properties:
              rooms:
                type: object
                description: |-
                  A map of room IDs to room key backup data.
                additionalProperties:
                  allOf:
                    - $ref: "definitions/room_key_backup.yaml"
                example: {
                  "!room:example.org": {
                    "sessions": {
                      "sessionid1": {
                        "first_message_index": 1,
                        "forwarded_count": 0,
                        "is_verified": true,
                        "session_data": {
                          "ephemeral": "base64+ephemeral+key",
                          "ciphertext": "base64+ciphertext+of+JSON+data",
                          "mac": "base64+mac+of+ciphertext"
                        }
                      }
                    }
                  }
                }
        404:
          description: The backup was not found.
          examples:
            application/json: {
              "errcode": "M_NOT_FOUND",
              "error": "Unknown backup version."
            }
          schema:
            "$ref": "definitions/errors/error.yaml"
        429:
          description: This request was rate-limited.
          schema:
            "$ref": "definitions/errors/rate_limited.yaml"
    delete:
      summary: Delete a key from the backup
      description: |-
        Delete a key from the backup.
      operationId: deleteRoomKeysKeyRoomId
      security:
        - accessToken: []
      parameters:
        - in: query
          type: string
          name: version
          description: |-
            The backup from which to delete the key
          required: true
          x-example: "1"
      responses:
        200:
          description: The update succeeded
          schema:
            type: object
            properties:
              etag:
                description: |-
                  The new etag value representing stored keys in the backup.
                  See ``GET /room_keys/version/{version}`` for more details.
                type: string
                example: "abcdefg"
              count:
                description: The number of keys stored in the backup
                type: integer
                example: 10
            required:
              - etag
              - count
        404:
          description: |-
            The backup was not found.
          examples:
            application/json: {
              "errcode": "M_NOT_FOUND",
              "error": "Unknown backup version"
            }
          schema:
            "$ref": "definitions/errors/error.yaml"
        429:
          description: This request was rate-limited.
          schema:
            "$ref": "definitions/errors/rate_limited.yaml"
