{
  "openapi": "3.1.0",
  "info": {
    "title": "Matrix Authentication Service admin API",
    "version": ""
  },
  "servers": [
    {
      "url": "{base}",
      "variables": {
        "base": {
          "default": "/",
          "description": null
        }
      }
    }
  ],
  "paths": {
    "/api/admin/v1/compat-sessions": {
      "get": {
        "tags": [
          "compat-session"
        ],
        "summary": "List compatibility sessions",
        "description": "Retrieve a list of compatibility sessions.\nNote that by default, all sessions, including finished ones are returned, with the oldest first.\nUse the `filter[status]` parameter to filter the sessions by their status and `page[last]` parameter to retrieve the last N sessions.",
        "operationId": "listCompatSessions",
        "parameters": [
          {
            "in": "query",
            "name": "page[before]",
            "description": "Retrieve the items before the given ID",
            "schema": {
              "description": "Retrieve the items before the given ID",
              "$ref": "#/components/schemas/ULID",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "page[after]",
            "description": "Retrieve the items after the given ID",
            "schema": {
              "description": "Retrieve the items after the given ID",
              "$ref": "#/components/schemas/ULID",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "page[first]",
            "description": "Retrieve the first N items",
            "schema": {
              "description": "Retrieve the first N items",
              "type": "integer",
              "format": "uint",
              "minimum": 1.0,
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "page[last]",
            "description": "Retrieve the last N items",
            "schema": {
              "description": "Retrieve the last N items",
              "type": "integer",
              "format": "uint",
              "minimum": 1.0,
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "filter[user]",
            "description": "Retrieve the items for the given user",
            "schema": {
              "description": "Retrieve the items for the given user",
              "$ref": "#/components/schemas/ULID",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "filter[user-session]",
            "description": "Retrieve the items started from the given browser session",
            "schema": {
              "description": "Retrieve the items started from the given browser session",
              "$ref": "#/components/schemas/ULID",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "filter[status]",
            "description": "Retrieve the items with the given status\n\nDefaults to retrieve all sessions, including finished ones.\n\n* `active`: Only retrieve active sessions\n\n* `finished`: Only retrieve finished sessions",
            "schema": {
              "description": "Retrieve the items with the given status\n\nDefaults to retrieve all sessions, including finished ones.\n\n* `active`: Only retrieve active sessions\n\n* `finished`: Only retrieve finished sessions",
              "$ref": "#/components/schemas/CompatSessionStatus",
              "nullable": true
            },
            "style": "form"
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated response of compatibility sessions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedResponse_for_CompatSession"
                },
                "example": {
                  "meta": {
                    "count": 42
                  },
                  "data": [
                    {
                      "type": "compat-session",
                      "id": "01040G2081040G2081040G2081",
                      "attributes": {
                        "user_id": "01040G2081040G2081040G2081",
                        "device_id": "AABBCCDDEE",
                        "user_session_id": "0H248H248H248H248H248H248H",
                        "redirect_uri": "https://example.com/redirect",
                        "created_at": "1970-01-01T00:00:00Z",
                        "user_agent": "Mozilla/5.0",
                        "last_active_at": "1970-01-01T00:00:00Z",
                        "last_active_ip": "1.2.3.4",
                        "finished_at": null,
                        "human_name": "Laptop"
                      },
                      "links": {
                        "self": "/api/admin/v1/compat-sessions/01040G2081040G2081040G2081"
                      }
                    },
                    {
                      "type": "compat-session",
                      "id": "02081040G2081040G2081040G2",
                      "attributes": {
                        "user_id": "01040G2081040G2081040G2081",
                        "device_id": "FFGGHHIIJJ",
                        "user_session_id": "0J289144GJ289144GJ289144GJ",
                        "redirect_uri": null,
                        "created_at": "1970-01-01T00:00:00Z",
                        "user_agent": "Mozilla/5.0",
                        "last_active_at": "1970-01-01T00:00:00Z",
                        "last_active_ip": "1.2.3.4",
                        "finished_at": "1970-01-01T00:00:00Z",
                        "human_name": null
                      },
                      "links": {
                        "self": "/api/admin/v1/compat-sessions/02081040G2081040G2081040G2"
                      }
                    },
                    {
                      "type": "compat-session",
                      "id": "030C1G60R30C1G60R30C1G60R3",
                      "attributes": {
                        "user_id": "01040G2081040G2081040G2081",
                        "device_id": null,
                        "user_session_id": null,
                        "redirect_uri": null,
                        "created_at": "1970-01-01T00:00:00Z",
                        "user_agent": null,
                        "last_active_at": null,
                        "last_active_ip": null,
                        "finished_at": null,
                        "human_name": null
                      },
                      "links": {
                        "self": "/api/admin/v1/compat-sessions/030C1G60R30C1G60R30C1G60R3"
                      }
                    }
                  ],
                  "links": {
                    "self": "/api/admin/v1/compat-sessions?page[first]=3",
                    "first": "/api/admin/v1/compat-sessions?page[first]=3",
                    "last": "/api/admin/v1/compat-sessions?page[last]=3",
                    "next": "/api/admin/v1/compat-sessions?page[after]=030C1G60R30C1G60R30C1G60R3&page[first]=3"
                  }
                }
              }
            }
          },
          "404": {
            "description": "User was not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "User ID 00000000000000000000000000 not found"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/admin/v1/compat-sessions/{id}": {
      "get": {
        "tags": [
          "compat-session"
        ],
        "summary": "Get a compatibility session",
        "operationId": "getCompatSession",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "title": "The ID of the resource",
              "$ref": "#/components/schemas/ULID"
            },
            "style": "simple"
          }
        ],
        "responses": {
          "200": {
            "description": "Compatibility session was found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SingleResponse_for_CompatSession"
                },
                "example": {
                  "data": {
                    "type": "compat-session",
                    "id": "01040G2081040G2081040G2081",
                    "attributes": {
                      "user_id": "01040G2081040G2081040G2081",
                      "device_id": "AABBCCDDEE",
                      "user_session_id": "0H248H248H248H248H248H248H",
                      "redirect_uri": "https://example.com/redirect",
                      "created_at": "1970-01-01T00:00:00Z",
                      "user_agent": "Mozilla/5.0",
                      "last_active_at": "1970-01-01T00:00:00Z",
                      "last_active_ip": "1.2.3.4",
                      "finished_at": null,
                      "human_name": "Laptop"
                    },
                    "links": {
                      "self": "/api/admin/v1/compat-sessions/01040G2081040G2081040G2081"
                    }
                  },
                  "links": {
                    "self": "/api/admin/v1/compat-sessions/01040G2081040G2081040G2081"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Compatibility session was not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "Compatibility session ID 00000000000000000000000000 not found"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/admin/v1/oauth2-sessions": {
      "get": {
        "tags": [
          "oauth2-session"
        ],
        "summary": "List OAuth 2.0 sessions",
        "description": "Retrieve a list of OAuth 2.0 sessions.\nNote that by default, all sessions, including finished ones are returned, with the oldest first.\nUse the `filter[status]` parameter to filter the sessions by their status and `page[last]` parameter to retrieve the last N sessions.",
        "operationId": "listOAuth2Sessions",
        "parameters": [
          {
            "in": "query",
            "name": "page[before]",
            "description": "Retrieve the items before the given ID",
            "schema": {
              "description": "Retrieve the items before the given ID",
              "$ref": "#/components/schemas/ULID",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "page[after]",
            "description": "Retrieve the items after the given ID",
            "schema": {
              "description": "Retrieve the items after the given ID",
              "$ref": "#/components/schemas/ULID",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "page[first]",
            "description": "Retrieve the first N items",
            "schema": {
              "description": "Retrieve the first N items",
              "type": "integer",
              "format": "uint",
              "minimum": 1.0,
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "page[last]",
            "description": "Retrieve the last N items",
            "schema": {
              "description": "Retrieve the last N items",
              "type": "integer",
              "format": "uint",
              "minimum": 1.0,
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "filter[user]",
            "description": "Retrieve the items for the given user",
            "schema": {
              "description": "Retrieve the items for the given user",
              "$ref": "#/components/schemas/ULID",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "filter[client]",
            "description": "Retrieve the items for the given client",
            "schema": {
              "description": "Retrieve the items for the given client",
              "$ref": "#/components/schemas/ULID",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "filter[client-kind]",
            "description": "Retrieve the items only for a specific client kind",
            "schema": {
              "description": "Retrieve the items only for a specific client kind",
              "$ref": "#/components/schemas/OAuth2ClientKind",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "filter[user-session]",
            "description": "Retrieve the items started from the given browser session",
            "schema": {
              "description": "Retrieve the items started from the given browser session",
              "$ref": "#/components/schemas/ULID",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "filter[scope]",
            "description": "Retrieve the items with the given scope",
            "schema": {
              "description": "Retrieve the items with the given scope",
              "default": [],
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "filter[status]",
            "description": "Retrieve the items with the given status\n\nDefaults to retrieve all sessions, including finished ones.\n\n* `active`: Only retrieve active sessions\n\n* `finished`: Only retrieve finished sessions",
            "schema": {
              "description": "Retrieve the items with the given status\n\nDefaults to retrieve all sessions, including finished ones.\n\n* `active`: Only retrieve active sessions\n\n* `finished`: Only retrieve finished sessions",
              "$ref": "#/components/schemas/OAuth2SessionStatus",
              "nullable": true
            },
            "style": "form"
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated response of OAuth 2.0 sessions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedResponse_for_OAuth2Session"
                },
                "example": {
                  "meta": {
                    "count": 42
                  },
                  "data": [
                    {
                      "type": "oauth2-session",
                      "id": "01040G2081040G2081040G2081",
                      "attributes": {
                        "created_at": "1970-01-01T00:00:00Z",
                        "finished_at": null,
                        "user_id": "02081040G2081040G2081040G2",
                        "user_session_id": "030C1G60R30C1G60R30C1G60R3",
                        "client_id": "040G2081040G2081040G208104",
                        "scope": "openid",
                        "user_agent": "Mozilla/5.0",
                        "last_active_at": "1970-01-01T00:00:00Z",
                        "last_active_ip": "127.0.0.1",
                        "human_name": "Laptop"
                      },
                      "links": {
                        "self": "/api/admin/v1/oauth2-sessions/01040G2081040G2081040G2081"
                      }
                    },
                    {
                      "type": "oauth2-session",
                      "id": "02081040G2081040G2081040G2",
                      "attributes": {
                        "created_at": "1970-01-01T00:00:00Z",
                        "finished_at": null,
                        "user_id": null,
                        "user_session_id": null,
                        "client_id": "050M2GA1850M2GA1850M2GA185",
                        "scope": "urn:mas:admin",
                        "user_agent": null,
                        "last_active_at": null,
                        "last_active_ip": null,
                        "human_name": null
                      },
                      "links": {
                        "self": "/api/admin/v1/oauth2-sessions/02081040G2081040G2081040G2"
                      }
                    },
                    {
                      "type": "oauth2-session",
                      "id": "030C1G60R30C1G60R30C1G60R3",
                      "attributes": {
                        "created_at": "1970-01-01T00:00:00Z",
                        "finished_at": "1970-01-01T00:00:00Z",
                        "user_id": "040G2081040G2081040G208104",
                        "user_session_id": "050M2GA1850M2GA1850M2GA185",
                        "client_id": "060R30C1G60R30C1G60R30C1G6",
                        "scope": "urn:matrix:org.matrix.msc2967.client:api:*",
                        "user_agent": "Mozilla/5.0",
                        "last_active_at": "1970-01-01T00:00:00Z",
                        "last_active_ip": "127.0.0.1",
                        "human_name": null
                      },
                      "links": {
                        "self": "/api/admin/v1/oauth2-sessions/030C1G60R30C1G60R30C1G60R3"
                      }
                    }
                  ],
                  "links": {
                    "self": "/api/admin/v1/oauth2-sessions?page[first]=3",
                    "first": "/api/admin/v1/oauth2-sessions?page[first]=3",
                    "last": "/api/admin/v1/oauth2-sessions?page[last]=3",
                    "next": "/api/admin/v1/oauth2-sessions?page[after]=030C1G60R30C1G60R30C1G60R3&page[first]=3"
                  }
                }
              }
            }
          },
          "404": {
            "description": "User was not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "User ID 00000000000000000000000000 not found"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "Invalid scope \"not a valid scope\" in filter parameters"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/admin/v1/oauth2-sessions/{id}": {
      "get": {
        "tags": [
          "oauth2-session"
        ],
        "summary": "Get an OAuth 2.0 session",
        "operationId": "getOAuth2Session",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "title": "The ID of the resource",
              "$ref": "#/components/schemas/ULID"
            },
            "style": "simple"
          }
        ],
        "responses": {
          "200": {
            "description": "OAuth 2.0 session was found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SingleResponse_for_OAuth2Session"
                },
                "example": {
                  "data": {
                    "type": "oauth2-session",
                    "id": "01040G2081040G2081040G2081",
                    "attributes": {
                      "created_at": "1970-01-01T00:00:00Z",
                      "finished_at": null,
                      "user_id": "02081040G2081040G2081040G2",
                      "user_session_id": "030C1G60R30C1G60R30C1G60R3",
                      "client_id": "040G2081040G2081040G208104",
                      "scope": "openid",
                      "user_agent": "Mozilla/5.0",
                      "last_active_at": "1970-01-01T00:00:00Z",
                      "last_active_ip": "127.0.0.1",
                      "human_name": "Laptop"
                    },
                    "links": {
                      "self": "/api/admin/v1/oauth2-sessions/01040G2081040G2081040G2081"
                    }
                  },
                  "links": {
                    "self": "/api/admin/v1/oauth2-sessions/01040G2081040G2081040G2081"
                  }
                }
              }
            }
          },
          "404": {
            "description": "OAuth 2.0 session was not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "OAuth 2.0 session ID 00000000000000000000000000 not found"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/admin/v1/policy-data": {
      "post": {
        "tags": [
          "policy-data"
        ],
        "summary": "Set the current policy data",
        "operationId": "setPolicyData",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetPolicyDataRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Policy data was successfully set",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SingleResponse_for_PolicyData"
                },
                "example": {
                  "data": {
                    "type": "policy-data",
                    "id": "01040G2081040G2081040G2081",
                    "attributes": {
                      "created_at": "1970-01-01T00:00:00Z",
                      "data": {
                        "hello": "world",
                        "foo": 42,
                        "bar": true
                      }
                    },
                    "links": {
                      "self": "/api/admin/v1/policy-data/01040G2081040G2081040G2081"
                    }
                  },
                  "links": {
                    "self": "/api/admin/v1/policy-data/01040G2081040G2081040G2081"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid policy data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "Failed to instanciate policy with the provided data"
                    },
                    {
                      "title": "invalid policy data"
                    },
                    {
                      "title": "Failed to merge policy data objects"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/admin/v1/policy-data/latest": {
      "get": {
        "tags": [
          "policy-data"
        ],
        "summary": "Get the latest policy data",
        "operationId": "getLatestPolicyData",
        "responses": {
          "200": {
            "description": "Latest policy data was found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SingleResponse_for_PolicyData"
                },
                "example": {
                  "data": {
                    "type": "policy-data",
                    "id": "01040G2081040G2081040G2081",
                    "attributes": {
                      "created_at": "1970-01-01T00:00:00Z",
                      "data": {
                        "hello": "world",
                        "foo": 42,
                        "bar": true
                      }
                    },
                    "links": {
                      "self": "/api/admin/v1/policy-data/01040G2081040G2081040G2081"
                    }
                  },
                  "links": {
                    "self": "/api/admin/v1/policy-data/01040G2081040G2081040G2081"
                  }
                }
              }
            }
          },
          "404": {
            "description": "No policy data was found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "No policy data found"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/admin/v1/policy-data/{id}": {
      "get": {
        "tags": [
          "policy-data"
        ],
        "summary": "Get policy data by ID",
        "operationId": "getPolicyData",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "title": "The ID of the resource",
              "$ref": "#/components/schemas/ULID"
            },
            "style": "simple"
          }
        ],
        "responses": {
          "200": {
            "description": "Policy data was found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SingleResponse_for_PolicyData"
                },
                "example": {
                  "data": {
                    "type": "policy-data",
                    "id": "01040G2081040G2081040G2081",
                    "attributes": {
                      "created_at": "1970-01-01T00:00:00Z",
                      "data": {
                        "hello": "world",
                        "foo": 42,
                        "bar": true
                      }
                    },
                    "links": {
                      "self": "/api/admin/v1/policy-data/01040G2081040G2081040G2081"
                    }
                  },
                  "links": {
                    "self": "/api/admin/v1/policy-data/01040G2081040G2081040G2081"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Policy data was not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "Policy data with ID 00000000000000000000000000 not found"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/admin/v1/users": {
      "get": {
        "tags": [
          "user"
        ],
        "summary": "List users",
        "operationId": "listUsers",
        "parameters": [
          {
            "in": "query",
            "name": "page[before]",
            "description": "Retrieve the items before the given ID",
            "schema": {
              "description": "Retrieve the items before the given ID",
              "$ref": "#/components/schemas/ULID",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "page[after]",
            "description": "Retrieve the items after the given ID",
            "schema": {
              "description": "Retrieve the items after the given ID",
              "$ref": "#/components/schemas/ULID",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "page[first]",
            "description": "Retrieve the first N items",
            "schema": {
              "description": "Retrieve the first N items",
              "type": "integer",
              "format": "uint",
              "minimum": 1.0,
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "page[last]",
            "description": "Retrieve the last N items",
            "schema": {
              "description": "Retrieve the last N items",
              "type": "integer",
              "format": "uint",
              "minimum": 1.0,
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "filter[admin]",
            "description": "Retrieve users with (or without) the `admin` flag set",
            "schema": {
              "description": "Retrieve users with (or without) the `admin` flag set",
              "type": "boolean",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "filter[status]",
            "description": "Retrieve the items with the given status\n\nDefaults to retrieve all users, including locked ones.\n\n* `active`: Only retrieve active users\n\n* `locked`: Only retrieve locked users (includes deactivated users)\n\n* `deactivated`: Only retrieve deactivated users",
            "schema": {
              "description": "Retrieve the items with the given status\n\nDefaults to retrieve all users, including locked ones.\n\n* `active`: Only retrieve active users\n\n* `locked`: Only retrieve locked users (includes deactivated users)\n\n* `deactivated`: Only retrieve deactivated users",
              "$ref": "#/components/schemas/UserStatus",
              "nullable": true
            },
            "style": "form"
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated response of users",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedResponse_for_User"
                },
                "example": {
                  "meta": {
                    "count": 42
                  },
                  "data": [
                    {
                      "type": "user",
                      "id": "01040G2081040G2081040G2081",
                      "attributes": {
                        "username": "alice",
                        "created_at": "1970-01-01T00:00:00Z",
                        "locked_at": null,
                        "deactivated_at": null,
                        "admin": false
                      },
                      "links": {
                        "self": "/api/admin/v1/users/01040G2081040G2081040G2081"
                      }
                    },
                    {
                      "type": "user",
                      "id": "02081040G2081040G2081040G2",
                      "attributes": {
                        "username": "bob",
                        "created_at": "1970-01-01T00:00:00Z",
                        "locked_at": null,
                        "deactivated_at": null,
                        "admin": true
                      },
                      "links": {
                        "self": "/api/admin/v1/users/02081040G2081040G2081040G2"
                      }
                    },
                    {
                      "type": "user",
                      "id": "030C1G60R30C1G60R30C1G60R3",
                      "attributes": {
                        "username": "charlie",
                        "created_at": "1970-01-01T00:00:00Z",
                        "locked_at": "1970-01-01T00:00:00Z",
                        "deactivated_at": null,
                        "admin": false
                      },
                      "links": {
                        "self": "/api/admin/v1/users/030C1G60R30C1G60R30C1G60R3"
                      }
                    }
                  ],
                  "links": {
                    "self": "/api/admin/v1/users?page[first]=3",
                    "first": "/api/admin/v1/users?page[first]=3",
                    "last": "/api/admin/v1/users?page[last]=3",
                    "next": "/api/admin/v1/users?page[after]=030C1G60R30C1G60R30C1G60R3&page[first]=3"
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "user"
        ],
        "summary": "Create a new user",
        "operationId": "createUser",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddUserRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "User was created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SingleResponse_for_User"
                },
                "example": {
                  "data": {
                    "type": "user",
                    "id": "01040G2081040G2081040G2081",
                    "attributes": {
                      "username": "alice",
                      "created_at": "1970-01-01T00:00:00Z",
                      "locked_at": null,
                      "deactivated_at": null,
                      "admin": false
                    },
                    "links": {
                      "self": "/api/admin/v1/users/01040G2081040G2081040G2081"
                    }
                  },
                  "links": {
                    "self": "/api/admin/v1/users/01040G2081040G2081040G2081"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Username is not valid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "Username is not valid"
                    }
                  ]
                }
              }
            }
          },
          "409": {
            "description": "Username is reserved by the homeserver",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "Username is reserved by the homeserver"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/admin/v1/users/{id}": {
      "get": {
        "tags": [
          "user"
        ],
        "summary": "Get a user",
        "operationId": "getUser",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "title": "The ID of the resource",
              "$ref": "#/components/schemas/ULID"
            },
            "style": "simple"
          }
        ],
        "responses": {
          "200": {
            "description": "User was found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SingleResponse_for_User"
                },
                "example": {
                  "data": {
                    "type": "user",
                    "id": "01040G2081040G2081040G2081",
                    "attributes": {
                      "username": "alice",
                      "created_at": "1970-01-01T00:00:00Z",
                      "locked_at": null,
                      "deactivated_at": null,
                      "admin": false
                    },
                    "links": {
                      "self": "/api/admin/v1/users/01040G2081040G2081040G2081"
                    }
                  },
                  "links": {
                    "self": "/api/admin/v1/users/01040G2081040G2081040G2081"
                  }
                }
              }
            }
          },
          "404": {
            "description": "User was not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "User ID 00000000000000000000000000 not found"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/admin/v1/users/{id}/set-password": {
      "post": {
        "tags": [
          "user"
        ],
        "summary": "Set the password for a user",
        "operationId": "setUserPassword",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "title": "The ID of the resource",
              "$ref": "#/components/schemas/ULID"
            },
            "style": "simple"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetUserPasswordRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Password was set"
          },
          "400": {
            "description": "Password is too weak",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "Password is too weak"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Password auth is disabled in the server configuration",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "Password auth is disabled"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "User was not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "User ID 00000000000000000000000000 not found"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/admin/v1/users/by-username/{username}": {
      "get": {
        "tags": [
          "user"
        ],
        "summary": "Get a user by its username (localpart)",
        "operationId": "getUserByUsername",
        "parameters": [
          {
            "in": "path",
            "name": "username",
            "description": "The username (localpart) of the user to get",
            "required": true,
            "schema": {
              "description": "The username (localpart) of the user to get",
              "type": "string"
            },
            "style": "simple"
          }
        ],
        "responses": {
          "200": {
            "description": "User was found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SingleResponse_for_User"
                },
                "example": {
                  "data": {
                    "type": "user",
                    "id": "01040G2081040G2081040G2081",
                    "attributes": {
                      "username": "alice",
                      "created_at": "1970-01-01T00:00:00Z",
                      "locked_at": null,
                      "deactivated_at": null,
                      "admin": false
                    },
                    "links": {
                      "self": "/api/admin/v1/users/01040G2081040G2081040G2081"
                    }
                  },
                  "links": {
                    "self": "/api/admin/v1/users/by-username/alice"
                  }
                }
              }
            }
          },
          "404": {
            "description": "User was not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "User with username \"alice\" not found"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/admin/v1/users/{id}/set-admin": {
      "post": {
        "tags": [
          "user"
        ],
        "summary": "Set whether a user can request admin",
        "description": "Calling this endpoint will not have any effect on existing sessions, meaning that their existing sessions will keep admin access if they were granted it.",
        "operationId": "userSetAdmin",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "title": "The ID of the resource",
              "$ref": "#/components/schemas/ULID"
            },
            "style": "simple"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserSetAdminRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "User had admin privileges set",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SingleResponse_for_User"
                },
                "example": {
                  "data": {
                    "type": "user",
                    "id": "02081040G2081040G2081040G2",
                    "attributes": {
                      "username": "bob",
                      "created_at": "1970-01-01T00:00:00Z",
                      "locked_at": null,
                      "deactivated_at": null,
                      "admin": true
                    },
                    "links": {
                      "self": "/api/admin/v1/users/02081040G2081040G2081040G2"
                    }
                  },
                  "links": {
                    "self": "/api/admin/v1/users/02081040G2081040G2081040G2/set-admin"
                  }
                }
              }
            }
          },
          "404": {
            "description": "User ID not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "User ID 00000000000000000000000000 not found"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/admin/v1/users/{id}/deactivate": {
      "post": {
        "tags": [
          "user"
        ],
        "summary": "Deactivate a user",
        "description": "Calling this endpoint will lock and deactivate the user, preventing them from doing any action.\nThis invalidates any existing session, and will ask the homeserver to make them leave all rooms.",
        "operationId": "deactivateUser",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "title": "The ID of the resource",
              "$ref": "#/components/schemas/ULID"
            },
            "style": "simple"
          }
        ],
        "responses": {
          "200": {
            "description": "User was deactivated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SingleResponse_for_User"
                },
                "example": {
                  "data": {
                    "type": "user",
                    "id": "030C1G60R30C1G60R30C1G60R3",
                    "attributes": {
                      "username": "charlie",
                      "created_at": "1970-01-01T00:00:00Z",
                      "locked_at": "1970-01-01T00:00:00Z",
                      "deactivated_at": null,
                      "admin": false
                    },
                    "links": {
                      "self": "/api/admin/v1/users/030C1G60R30C1G60R30C1G60R3"
                    }
                  },
                  "links": {
                    "self": "/api/admin/v1/users/030C1G60R30C1G60R30C1G60R3/deactivate"
                  }
                }
              }
            }
          },
          "404": {
            "description": "User ID not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "User ID 00000000000000000000000000 not found"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/admin/v1/users/{id}/lock": {
      "post": {
        "tags": [
          "user"
        ],
        "summary": "Lock a user",
        "description": "Calling this endpoint will lock the user, preventing them from doing any action.\nThis DOES NOT invalidate any existing session, meaning that all their existing sessions will work again as soon as they get unlocked.",
        "operationId": "lockUser",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "title": "The ID of the resource",
              "$ref": "#/components/schemas/ULID"
            },
            "style": "simple"
          }
        ],
        "responses": {
          "200": {
            "description": "User was locked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SingleResponse_for_User"
                },
                "example": {
                  "data": {
                    "type": "user",
                    "id": "030C1G60R30C1G60R30C1G60R3",
                    "attributes": {
                      "username": "charlie",
                      "created_at": "1970-01-01T00:00:00Z",
                      "locked_at": "1970-01-01T00:00:00Z",
                      "deactivated_at": null,
                      "admin": false
                    },
                    "links": {
                      "self": "/api/admin/v1/users/030C1G60R30C1G60R30C1G60R3"
                    }
                  },
                  "links": {
                    "self": "/api/admin/v1/users/030C1G60R30C1G60R30C1G60R3/lock"
                  }
                }
              }
            }
          },
          "404": {
            "description": "User ID not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "User ID 00000000000000000000000000 not found"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/admin/v1/users/{id}/unlock": {
      "post": {
        "tags": [
          "user"
        ],
        "summary": "Unlock a user",
        "operationId": "unlockUser",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "title": "The ID of the resource",
              "$ref": "#/components/schemas/ULID"
            },
            "style": "simple"
          }
        ],
        "responses": {
          "200": {
            "description": "User was unlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SingleResponse_for_User"
                },
                "example": {
                  "data": {
                    "type": "user",
                    "id": "01040G2081040G2081040G2081",
                    "attributes": {
                      "username": "alice",
                      "created_at": "1970-01-01T00:00:00Z",
                      "locked_at": null,
                      "deactivated_at": null,
                      "admin": false
                    },
                    "links": {
                      "self": "/api/admin/v1/users/01040G2081040G2081040G2081"
                    }
                  },
                  "links": {
                    "self": "/api/admin/v1/users/01040G2081040G2081040G2081/unlock"
                  }
                }
              }
            }
          },
          "404": {
            "description": "User ID not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "User ID 00000000000000000000000000 not found"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/admin/v1/user-emails": {
      "get": {
        "tags": [
          "user-email"
        ],
        "summary": "List user emails",
        "description": "Retrieve a list of user emails.",
        "operationId": "listUserEmails",
        "parameters": [
          {
            "in": "query",
            "name": "page[before]",
            "description": "Retrieve the items before the given ID",
            "schema": {
              "description": "Retrieve the items before the given ID",
              "$ref": "#/components/schemas/ULID",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "page[after]",
            "description": "Retrieve the items after the given ID",
            "schema": {
              "description": "Retrieve the items after the given ID",
              "$ref": "#/components/schemas/ULID",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "page[first]",
            "description": "Retrieve the first N items",
            "schema": {
              "description": "Retrieve the first N items",
              "type": "integer",
              "format": "uint",
              "minimum": 1.0,
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "page[last]",
            "description": "Retrieve the last N items",
            "schema": {
              "description": "Retrieve the last N items",
              "type": "integer",
              "format": "uint",
              "minimum": 1.0,
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "filter[user]",
            "description": "Retrieve the items for the given user",
            "schema": {
              "description": "Retrieve the items for the given user",
              "$ref": "#/components/schemas/ULID",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "filter[email]",
            "description": "Retrieve the user email with the given email address",
            "schema": {
              "description": "Retrieve the user email with the given email address",
              "type": "string",
              "nullable": true
            },
            "style": "form"
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated response of user emails",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedResponse_for_UserEmail"
                },
                "example": {
                  "meta": {
                    "count": 42
                  },
                  "data": [
                    {
                      "type": "user-email",
                      "id": "01040G2081040G2081040G2081",
                      "attributes": {
                        "created_at": "1970-01-01T00:00:00Z",
                        "user_id": "02081040G2081040G2081040G2",
                        "email": "alice@example.com"
                      },
                      "links": {
                        "self": "/api/admin/v1/user-emails/01040G2081040G2081040G2081"
                      }
                    }
                  ],
                  "links": {
                    "self": "/api/admin/v1/user-emails?page[first]=1",
                    "first": "/api/admin/v1/user-emails?page[first]=1",
                    "last": "/api/admin/v1/user-emails?page[last]=1",
                    "next": "/api/admin/v1/user-emails?page[after]=01040G2081040G2081040G2081&page[first]=1"
                  }
                }
              }
            }
          },
          "404": {
            "description": "User was not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "User ID 00000000000000000000000000 not found"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "user-email"
        ],
        "summary": "Add a user email",
        "description": "Add an email address to a user.\nNote that this endpoint ignores any policy which would normally prevent the email from being added.",
        "operationId": "addUserEmail",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddUserEmailRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "User email was created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SingleResponse_for_UserEmail"
                },
                "example": {
                  "data": {
                    "type": "user-email",
                    "id": "01040G2081040G2081040G2081",
                    "attributes": {
                      "created_at": "1970-01-01T00:00:00Z",
                      "user_id": "02081040G2081040G2081040G2",
                      "email": "alice@example.com"
                    },
                    "links": {
                      "self": "/api/admin/v1/user-emails/01040G2081040G2081040G2081"
                    }
                  },
                  "links": {
                    "self": "/api/admin/v1/user-emails/01040G2081040G2081040G2081"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Email already in use",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "User email \"alice@example.com\" already in use"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Email is not valid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "Email \"not a valid email\" is not valid"
                    },
                    {
                      "title": "Missing domain or user"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "User was not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "User ID 00000000000000000000000000 not found"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/admin/v1/user-emails/{id}": {
      "get": {
        "tags": [
          "user-email"
        ],
        "summary": "Get a user email",
        "operationId": "getUserEmail",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "title": "The ID of the resource",
              "$ref": "#/components/schemas/ULID"
            },
            "style": "simple"
          }
        ],
        "responses": {
          "200": {
            "description": "User email was found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SingleResponse_for_UserEmail"
                },
                "example": {
                  "data": {
                    "type": "user-email",
                    "id": "01040G2081040G2081040G2081",
                    "attributes": {
                      "created_at": "1970-01-01T00:00:00Z",
                      "user_id": "02081040G2081040G2081040G2",
                      "email": "alice@example.com"
                    },
                    "links": {
                      "self": "/api/admin/v1/user-emails/01040G2081040G2081040G2081"
                    }
                  },
                  "links": {
                    "self": "/api/admin/v1/user-emails/01040G2081040G2081040G2081"
                  }
                }
              }
            }
          },
          "404": {
            "description": "User email was not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "User email ID 00000000000000000000000000 not found"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "user-email"
        ],
        "summary": "Delete a user email",
        "operationId": "deleteUserEmail",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "title": "The ID of the resource",
              "$ref": "#/components/schemas/ULID"
            },
            "style": "simple"
          }
        ],
        "responses": {
          "204": {
            "description": "User email was found"
          },
          "404": {
            "description": "User email was not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "User email ID 00000000000000000000000000 not found"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/admin/v1/user-sessions": {
      "get": {
        "tags": [
          "user-session"
        ],
        "summary": "List user sessions",
        "description": "Retrieve a list of user sessions (browser sessions).\nNote that by default, all sessions, including finished ones are returned, with the oldest first.\nUse the `filter[status]` parameter to filter the sessions by their status and `page[last]` parameter to retrieve the last N sessions.",
        "operationId": "listUserSessions",
        "parameters": [
          {
            "in": "query",
            "name": "page[before]",
            "description": "Retrieve the items before the given ID",
            "schema": {
              "description": "Retrieve the items before the given ID",
              "$ref": "#/components/schemas/ULID",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "page[after]",
            "description": "Retrieve the items after the given ID",
            "schema": {
              "description": "Retrieve the items after the given ID",
              "$ref": "#/components/schemas/ULID",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "page[first]",
            "description": "Retrieve the first N items",
            "schema": {
              "description": "Retrieve the first N items",
              "type": "integer",
              "format": "uint",
              "minimum": 1.0,
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "page[last]",
            "description": "Retrieve the last N items",
            "schema": {
              "description": "Retrieve the last N items",
              "type": "integer",
              "format": "uint",
              "minimum": 1.0,
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "filter[user]",
            "description": "Retrieve the items for the given user",
            "schema": {
              "description": "Retrieve the items for the given user",
              "$ref": "#/components/schemas/ULID",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "filter[status]",
            "description": "Retrieve the items with the given status\n\nDefaults to retrieve all sessions, including finished ones.\n\n* `active`: Only retrieve active sessions\n\n* `finished`: Only retrieve finished sessions",
            "schema": {
              "description": "Retrieve the items with the given status\n\nDefaults to retrieve all sessions, including finished ones.\n\n* `active`: Only retrieve active sessions\n\n* `finished`: Only retrieve finished sessions",
              "$ref": "#/components/schemas/UserSessionStatus",
              "nullable": true
            },
            "style": "form"
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated response of user sessions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedResponse_for_UserSession"
                },
                "example": {
                  "meta": {
                    "count": 42
                  },
                  "data": [
                    {
                      "type": "user-session",
                      "id": "01040G2081040G2081040G2081",
                      "attributes": {
                        "created_at": "1970-01-01T00:00:00Z",
                        "finished_at": null,
                        "user_id": "02081040G2081040G2081040G2",
                        "user_agent": "Mozilla/5.0",
                        "last_active_at": "1970-01-01T00:00:00Z",
                        "last_active_ip": "127.0.0.1"
                      },
                      "links": {
                        "self": "/api/admin/v1/user-sessions/01040G2081040G2081040G2081"
                      }
                    },
                    {
                      "type": "user-session",
                      "id": "02081040G2081040G2081040G2",
                      "attributes": {
                        "created_at": "1970-01-01T00:00:00Z",
                        "finished_at": null,
                        "user_id": "030C1G60R30C1G60R30C1G60R3",
                        "user_agent": null,
                        "last_active_at": null,
                        "last_active_ip": null
                      },
                      "links": {
                        "self": "/api/admin/v1/user-sessions/02081040G2081040G2081040G2"
                      }
                    },
                    {
                      "type": "user-session",
                      "id": "030C1G60R30C1G60R30C1G60R3",
                      "attributes": {
                        "created_at": "1970-01-01T00:00:00Z",
                        "finished_at": "1970-01-01T00:00:00Z",
                        "user_id": "040G2081040G2081040G208104",
                        "user_agent": "Mozilla/5.0",
                        "last_active_at": "1970-01-01T00:00:00Z",
                        "last_active_ip": "127.0.0.1"
                      },
                      "links": {
                        "self": "/api/admin/v1/user-sessions/030C1G60R30C1G60R30C1G60R3"
                      }
                    }
                  ],
                  "links": {
                    "self": "/api/admin/v1/user-sessions?page[first]=3",
                    "first": "/api/admin/v1/user-sessions?page[first]=3",
                    "last": "/api/admin/v1/user-sessions?page[last]=3",
                    "next": "/api/admin/v1/user-sessions?page[after]=030C1G60R30C1G60R30C1G60R3&page[first]=3"
                  }
                }
              }
            }
          },
          "404": {
            "description": "User was not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "User ID 00000000000000000000000000 not found"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/admin/v1/user-sessions/{id}": {
      "get": {
        "tags": [
          "user-session"
        ],
        "summary": "Get a user session",
        "operationId": "getUserSession",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "title": "The ID of the resource",
              "$ref": "#/components/schemas/ULID"
            },
            "style": "simple"
          }
        ],
        "responses": {
          "200": {
            "description": "User session was found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SingleResponse_for_UserSession"
                },
                "example": {
                  "data": {
                    "type": "user-session",
                    "id": "01040G2081040G2081040G2081",
                    "attributes": {
                      "created_at": "1970-01-01T00:00:00Z",
                      "finished_at": null,
                      "user_id": "02081040G2081040G2081040G2",
                      "user_agent": "Mozilla/5.0",
                      "last_active_at": "1970-01-01T00:00:00Z",
                      "last_active_ip": "127.0.0.1"
                    },
                    "links": {
                      "self": "/api/admin/v1/user-sessions/01040G2081040G2081040G2081"
                    }
                  },
                  "links": {
                    "self": "/api/admin/v1/user-sessions/01040G2081040G2081040G2081"
                  }
                }
              }
            }
          },
          "404": {
            "description": "User session was not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "User session ID 00000000000000000000000000 not found"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/admin/v1/upstream-oauth-links": {
      "get": {
        "tags": [
          "upstream-oauth-link"
        ],
        "summary": "List upstream OAuth 2.0 links",
        "description": "Retrieve a list of upstream OAuth 2.0 links.",
        "operationId": "listUpstreamOAuthLinks",
        "parameters": [
          {
            "in": "query",
            "name": "page[before]",
            "description": "Retrieve the items before the given ID",
            "schema": {
              "description": "Retrieve the items before the given ID",
              "$ref": "#/components/schemas/ULID",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "page[after]",
            "description": "Retrieve the items after the given ID",
            "schema": {
              "description": "Retrieve the items after the given ID",
              "$ref": "#/components/schemas/ULID",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "page[first]",
            "description": "Retrieve the first N items",
            "schema": {
              "description": "Retrieve the first N items",
              "type": "integer",
              "format": "uint",
              "minimum": 1.0,
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "page[last]",
            "description": "Retrieve the last N items",
            "schema": {
              "description": "Retrieve the last N items",
              "type": "integer",
              "format": "uint",
              "minimum": 1.0,
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "filter[user]",
            "description": "Retrieve the items for the given user",
            "schema": {
              "description": "Retrieve the items for the given user",
              "$ref": "#/components/schemas/ULID",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "filter[provider]",
            "description": "Retrieve the items for the given provider",
            "schema": {
              "description": "Retrieve the items for the given provider",
              "$ref": "#/components/schemas/ULID",
              "nullable": true
            },
            "style": "form"
          },
          {
            "in": "query",
            "name": "filter[subject]",
            "description": "Retrieve the items with the given subject",
            "schema": {
              "description": "Retrieve the items with the given subject",
              "type": "string",
              "nullable": true
            },
            "style": "form"
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated response of upstream OAuth 2.0 links",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedResponse_for_UpstreamOAuthLink"
                },
                "example": {
                  "meta": {
                    "count": 42
                  },
                  "data": [
                    {
                      "type": "upstream-oauth-link",
                      "id": "01040G2081040G2081040G2081",
                      "attributes": {
                        "created_at": "1970-01-01T00:00:00Z",
                        "provider_id": "02081040G2081040G2081040G2",
                        "subject": "john-42",
                        "user_id": "030C1G60R30C1G60R30C1G60R3",
                        "human_account_name": "john.doe@example.com"
                      },
                      "links": {
                        "self": "/api/admin/v1/upstream-oauth-links/01040G2081040G2081040G2081"
                      }
                    },
                    {
                      "type": "upstream-oauth-link",
                      "id": "02081040G2081040G2081040G2",
                      "attributes": {
                        "created_at": "1970-01-01T00:00:00Z",
                        "provider_id": "030C1G60R30C1G60R30C1G60R3",
                        "subject": "jane-123",
                        "user_id": null,
                        "human_account_name": null
                      },
                      "links": {
                        "self": "/api/admin/v1/upstream-oauth-links/02081040G2081040G2081040G2"
                      }
                    },
                    {
                      "type": "upstream-oauth-link",
                      "id": "030C1G60R30C1G60R30C1G60R3",
                      "attributes": {
                        "created_at": "1970-01-01T00:00:00Z",
                        "provider_id": "040G2081040G2081040G208104",
                        "subject": "bob@social.example.com",
                        "user_id": "050M2GA1850M2GA1850M2GA185",
                        "human_account_name": "bob"
                      },
                      "links": {
                        "self": "/api/admin/v1/upstream-oauth-links/030C1G60R30C1G60R30C1G60R3"
                      }
                    }
                  ],
                  "links": {
                    "self": "/api/admin/v1/upstream-oauth-links?page[first]=3",
                    "first": "/api/admin/v1/upstream-oauth-links?page[first]=3",
                    "last": "/api/admin/v1/upstream-oauth-links?page[last]=3",
                    "next": "/api/admin/v1/upstream-oauth-links?page[after]=030C1G60R30C1G60R30C1G60R3&page[first]=3"
                  }
                }
              }
            }
          },
          "404": {
            "description": "User or provider was not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "User ID 00000000000000000000000000 not found"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "upstream-oauth-link"
        ],
        "summary": "Add an upstream OAuth 2.0 link",
        "operationId": "addUpstreamOAuthLink",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddUpstreamOauthLinkRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "An existing Upstream OAuth 2.0 link was associated to a user",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SingleResponse_for_UpstreamOAuthLink"
                },
                "example": {
                  "data": {
                    "type": "upstream-oauth-link",
                    "id": "01040G2081040G2081040G2081",
                    "attributes": {
                      "created_at": "1970-01-01T00:00:00Z",
                      "provider_id": "02081040G2081040G2081040G2",
                      "subject": "john-42",
                      "user_id": "030C1G60R30C1G60R30C1G60R3",
                      "human_account_name": "john.doe@example.com"
                    },
                    "links": {
                      "self": "/api/admin/v1/upstream-oauth-links/01040G2081040G2081040G2081"
                    }
                  },
                  "links": {
                    "self": "/api/admin/v1/upstream-oauth-links/01040G2081040G2081040G2081"
                  }
                }
              }
            }
          },
          "201": {
            "description": "A new Upstream OAuth 2.0 link was created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SingleResponse_for_UpstreamOAuthLink"
                },
                "example": {
                  "data": {
                    "type": "upstream-oauth-link",
                    "id": "01040G2081040G2081040G2081",
                    "attributes": {
                      "created_at": "1970-01-01T00:00:00Z",
                      "provider_id": "02081040G2081040G2081040G2",
                      "subject": "john-42",
                      "user_id": "030C1G60R30C1G60R30C1G60R3",
                      "human_account_name": "john.doe@example.com"
                    },
                    "links": {
                      "self": "/api/admin/v1/upstream-oauth-links/01040G2081040G2081040G2081"
                    }
                  },
                  "links": {
                    "self": "/api/admin/v1/upstream-oauth-links/01040G2081040G2081040G2081"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The subject from the provider is already linked to another user",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "Upstream Oauth 2.0 Provider ID 01040G2081040G2081040G2081 with subject subject1 is already linked to a user"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "User or provider was not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "User ID 00000000000000000000000000 not found"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/admin/v1/upstream-oauth-links/{id}": {
      "get": {
        "tags": [
          "upstream-oauth-link"
        ],
        "summary": "Get an upstream OAuth 2.0 link",
        "operationId": "getUpstreamOAuthLink",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "title": "The ID of the resource",
              "$ref": "#/components/schemas/ULID"
            },
            "style": "simple"
          }
        ],
        "responses": {
          "200": {
            "description": "Upstream OAuth 2.0 link was found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SingleResponse_for_UpstreamOAuthLink"
                },
                "example": {
                  "data": {
                    "type": "upstream-oauth-link",
                    "id": "01040G2081040G2081040G2081",
                    "attributes": {
                      "created_at": "1970-01-01T00:00:00Z",
                      "provider_id": "02081040G2081040G2081040G2",
                      "subject": "john-42",
                      "user_id": "030C1G60R30C1G60R30C1G60R3",
                      "human_account_name": "john.doe@example.com"
                    },
                    "links": {
                      "self": "/api/admin/v1/upstream-oauth-links/01040G2081040G2081040G2081"
                    }
                  },
                  "links": {
                    "self": "/api/admin/v1/upstream-oauth-links/01040G2081040G2081040G2081"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Upstream OAuth 2.0 link was not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "Upstream OAuth 2.0 Link ID 00000000000000000000000000 not found"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "upstream-oauth-link"
        ],
        "summary": "Delete an upstream OAuth 2.0 link",
        "operationId": "deleteUpstreamOAuthLink",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "title": "The ID of the resource",
              "$ref": "#/components/schemas/ULID"
            },
            "style": "simple"
          }
        ],
        "responses": {
          "204": {
            "description": "Upstream OAuth 2.0 link was deleted"
          },
          "404": {
            "description": "Upstream OAuth 2.0 link was not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "errors": [
                    {
                      "title": "Upstream OAuth 2.0 Link ID 00000000000000000000000000 not found"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "oauth2": {
        "type": "oauth2",
        "flows": {
          "clientCredentials": {
            "refreshUrl": "./oauth2/token",
            "tokenUrl": "./oauth2/token",
            "scopes": {
              "urn:mas:admin": "Grant access to the admin API"
            }
          },
          "authorizationCode": {
            "authorizationUrl": "./authorize",
            "tokenUrl": "./oauth2/token",
            "refreshUrl": "./oauth2/token",
            "scopes": {
              "urn:mas:admin": "Grant access to the admin API"
            }
          }
        }
      },
      "token": {
        "type": "http",
        "scheme": "bearer",
        "description": "An access token with access to the admin API"
      }
    },
    "schemas": {
      "PaginationParams": {
        "type": "object",
        "properties": {
          "page[before]": {
            "description": "Retrieve the items before the given ID",
            "$ref": "#/components/schemas/ULID",
            "nullable": true
          },
          "page[after]": {
            "description": "Retrieve the items after the given ID",
            "$ref": "#/components/schemas/ULID",
            "nullable": true
          },
          "page[first]": {
            "description": "Retrieve the first N items",
            "type": "integer",
            "format": "uint",
            "minimum": 1.0,
            "nullable": true
          },
          "page[last]": {
            "description": "Retrieve the last N items",
            "type": "integer",
            "format": "uint",
            "minimum": 1.0,
            "nullable": true
          }
        }
      },
      "ULID": {
        "title": "ULID",
        "description": "A ULID as per https://github.com/ulid/spec",
        "examples": [
          "01ARZ3NDEKTSV4RRFFQ69G5FAV",
          "01J41912SC8VGAQDD50F6APK91"
        ],
        "type": "string",
        "pattern": "^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}$"
      },
      "CompatSessionFilter": {
        "type": "object",
        "properties": {
          "filter[user]": {
            "description": "Retrieve the items for the given user",
            "$ref": "#/components/schemas/ULID",
            "nullable": true
          },
          "filter[user-session]": {
            "description": "Retrieve the items started from the given browser session",
            "$ref": "#/components/schemas/ULID",
            "nullable": true
          },
          "filter[status]": {
            "description": "Retrieve the items with the given status\n\nDefaults to retrieve all sessions, including finished ones.\n\n* `active`: Only retrieve active sessions\n\n* `finished`: Only retrieve finished sessions",
            "$ref": "#/components/schemas/CompatSessionStatus",
            "nullable": true
          }
        }
      },
      "CompatSessionStatus": {
        "type": "string",
        "enum": [
          "active",
          "finished"
        ]
      },
      "PaginatedResponse_for_CompatSession": {
        "description": "A top-level response with a page of resources",
        "type": "object",
        "required": [
          "data",
          "links",
          "meta"
        ],
        "properties": {
          "meta": {
            "description": "Response metadata",
            "$ref": "#/components/schemas/PaginationMeta"
          },
          "data": {
            "description": "The list of resources",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SingleResource_for_CompatSession"
            }
          },
          "links": {
            "description": "Related links",
            "$ref": "#/components/schemas/PaginationLinks"
          }
        }
      },
      "PaginationMeta": {
        "type": "object",
        "required": [
          "count"
        ],
        "properties": {
          "count": {
            "description": "The total number of results",
            "type": "integer",
            "format": "uint",
            "minimum": 0.0
          }
        }
      },
      "SingleResource_for_CompatSession": {
        "description": "A single resource, with its type, ID, attributes and related links",
        "type": "object",
        "required": [
          "attributes",
          "id",
          "links",
          "type"
        ],
        "properties": {
          "type": {
            "description": "The type of the resource",
            "type": "string"
          },
          "id": {
            "description": "The ID of the resource",
            "$ref": "#/components/schemas/ULID"
          },
          "attributes": {
            "description": "The attributes of the resource",
            "$ref": "#/components/schemas/CompatSession"
          },
          "links": {
            "description": "Related links",
            "$ref": "#/components/schemas/SelfLinks"
          }
        }
      },
      "CompatSession": {
        "description": "A compatibility session for legacy clients",
        "type": "object",
        "required": [
          "created_at",
          "device_id",
          "user_id",
          "user_session_id"
        ],
        "properties": {
          "user_id": {
            "description": "The ID of the user that owns this session",
            "$ref": "#/components/schemas/ULID"
          },
          "device_id": {
            "description": "The Matrix device ID of this session",
            "$ref": "#/components/schemas/DeviceID"
          },
          "user_session_id": {
            "description": "The ID of the user session that started this session, if any",
            "$ref": "#/components/schemas/ULID"
          },
          "redirect_uri": {
            "description": "The redirect URI used to login in the client, if it was an SSO login",
            "type": "string",
            "format": "uri",
            "nullable": true
          },
          "created_at": {
            "description": "The time this session was created",
            "type": "string",
            "format": "date-time"
          },
          "user_agent": {
            "description": "The user agent string that started this session, if any",
            "type": "string",
            "nullable": true
          },
          "last_active_at": {
            "description": "The time this session was last active",
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_active_ip": {
            "description": "The last IP address recorded for this session",
            "type": "string",
            "format": "ip",
            "nullable": true
          },
          "finished_at": {
            "description": "The time this session was finished",
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "human_name": {
            "description": "The user-provided name, if any",
            "type": "string",
            "nullable": true
          }
        }
      },
      "DeviceID": {
        "title": "Device ID",
        "examples": [
          "AABBCCDDEE",
          "FFGGHHIIJJ"
        ],
        "type": "string",
        "pattern": "^[A-Za-z0-9._~!$&'()*+,;=:&/-]+$"
      },
      "SelfLinks": {
        "description": "Related links",
        "type": "object",
        "required": [
          "self"
        ],
        "properties": {
          "self": {
            "description": "The canonical link to the current resource",
            "type": "string"
          }
        }
      },
      "PaginationLinks": {
        "description": "Related links",
        "type": "object",
        "required": [
          "first",
          "last",
          "self"
        ],
        "properties": {
          "self": {
            "description": "The canonical link to the current page",
            "type": "string"
          },
          "first": {
            "description": "The link to the first page of results",
            "type": "string"
          },
          "last": {
            "description": "The link to the last page of results",
            "type": "string"
          },
          "next": {
            "description": "The link to the next page of results\n\nOnly present if there is a next page",
            "type": "string",
            "nullable": true
          },
          "prev": {
            "description": "The link to the previous page of results\n\nOnly present if there is a previous page",
            "type": "string",
            "nullable": true
          }
        }
      },
      "ErrorResponse": {
        "description": "A top-level response with a list of errors",
        "type": "object",
        "required": [
          "errors"
        ],
        "properties": {
          "errors": {
            "description": "The list of errors",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Error": {
        "description": "A single error",
        "type": "object",
        "required": [
          "title"
        ],
        "properties": {
          "title": {
            "description": "A human-readable title for the error",
            "type": "string"
          }
        }
      },
      "UlidInPath": {
        "type": "object",
        "required": [
          "id"
        ],
        "properties": {
          "id": {
            "title": "The ID of the resource",
            "$ref": "#/components/schemas/ULID"
          }
        }
      },
      "SingleResponse_for_CompatSession": {
        "description": "A top-level response with a single resource",
        "type": "object",
        "required": [
          "data",
          "links"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/SingleResource_for_CompatSession"
          },
          "links": {
            "$ref": "#/components/schemas/SelfLinks"
          }
        }
      },
      "OAuth2SessionFilter": {
        "type": "object",
        "properties": {
          "filter[user]": {
            "description": "Retrieve the items for the given user",
            "$ref": "#/components/schemas/ULID",
            "nullable": true
          },
          "filter[client]": {
            "description": "Retrieve the items for the given client",
            "$ref": "#/components/schemas/ULID",
            "nullable": true
          },
          "filter[client-kind]": {
            "description": "Retrieve the items only for a specific client kind",
            "$ref": "#/components/schemas/OAuth2ClientKind",
            "nullable": true
          },
          "filter[user-session]": {
            "description": "Retrieve the items started from the given browser session",
            "$ref": "#/components/schemas/ULID",
            "nullable": true
          },
          "filter[scope]": {
            "description": "Retrieve the items with the given scope",
            "default": [],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "filter[status]": {
            "description": "Retrieve the items with the given status\n\nDefaults to retrieve all sessions, including finished ones.\n\n* `active`: Only retrieve active sessions\n\n* `finished`: Only retrieve finished sessions",
            "$ref": "#/components/schemas/OAuth2SessionStatus",
            "nullable": true
          }
        }
      },
      "OAuth2ClientKind": {
        "type": "string",
        "enum": [
          "dynamic",
          "static"
        ]
      },
      "OAuth2SessionStatus": {
        "type": "string",
        "enum": [
          "active",
          "finished"
        ]
      },
      "PaginatedResponse_for_OAuth2Session": {
        "description": "A top-level response with a page of resources",
        "type": "object",
        "required": [
          "data",
          "links",
          "meta"
        ],
        "properties": {
          "meta": {
            "description": "Response metadata",
            "$ref": "#/components/schemas/PaginationMeta"
          },
          "data": {
            "description": "The list of resources",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SingleResource_for_OAuth2Session"
            }
          },
          "links": {
            "description": "Related links",
            "$ref": "#/components/schemas/PaginationLinks"
          }
        }
      },
      "SingleResource_for_OAuth2Session": {
        "description": "A single resource, with its type, ID, attributes and related links",
        "type": "object",
        "required": [
          "attributes",
          "id",
          "links",
          "type"
        ],
        "properties": {
          "type": {
            "description": "The type of the resource",
            "type": "string"
          },
          "id": {
            "description": "The ID of the resource",
            "$ref": "#/components/schemas/ULID"
          },
          "attributes": {
            "description": "The attributes of the resource",
            "$ref": "#/components/schemas/OAuth2Session"
          },
          "links": {
            "description": "Related links",
            "$ref": "#/components/schemas/SelfLinks"
          }
        }
      },
      "OAuth2Session": {
        "description": "A OAuth 2.0 session",
        "type": "object",
        "required": [
          "client_id",
          "created_at",
          "scope"
        ],
        "properties": {
          "created_at": {
            "description": "When the object was created",
            "type": "string",
            "format": "date-time"
          },
          "finished_at": {
            "description": "When the session was finished",
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "user_id": {
            "description": "The ID of the user who owns the session",
            "$ref": "#/components/schemas/ULID",
            "nullable": true
          },
          "user_session_id": {
            "description": "The ID of the browser session which started this session",
            "$ref": "#/components/schemas/ULID",
            "nullable": true
          },
          "client_id": {
            "description": "The ID of the client which requested this session",
            "$ref": "#/components/schemas/ULID"
          },
          "scope": {
            "description": "The scope granted for this session",
            "type": "string"
          },
          "user_agent": {
            "description": "The user agent string of the client which started this session",
            "type": "string",
            "nullable": true
          },
          "last_active_at": {
            "description": "The last time the session was active",
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_active_ip": {
            "description": "The last IP address used by the session",
            "type": "string",
            "format": "ip",
            "nullable": true
          },
          "human_name": {
            "description": "The user-provided name, if any",
            "type": "string",
            "nullable": true
          }
        }
      },
      "SingleResponse_for_OAuth2Session": {
        "description": "A top-level response with a single resource",
        "type": "object",
        "required": [
          "data",
          "links"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/SingleResource_for_OAuth2Session"
          },
          "links": {
            "$ref": "#/components/schemas/SelfLinks"
          }
        }
      },
      "SetPolicyDataRequest": {
        "title": "JSON payload for the `POST /api/admin/v1/policy-data`",
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "examples": [
              {
                "hello": "world",
                "foo": 42,
                "bar": true
              }
            ]
          }
        }
      },
      "SingleResponse_for_PolicyData": {
        "description": "A top-level response with a single resource",
        "type": "object",
        "required": [
          "data",
          "links"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/SingleResource_for_PolicyData"
          },
          "links": {
            "$ref": "#/components/schemas/SelfLinks"
          }
        }
      },
      "SingleResource_for_PolicyData": {
        "description": "A single resource, with its type, ID, attributes and related links",
        "type": "object",
        "required": [
          "attributes",
          "id",
          "links",
          "type"
        ],
        "properties": {
          "type": {
            "description": "The type of the resource",
            "type": "string"
          },
          "id": {
            "description": "The ID of the resource",
            "$ref": "#/components/schemas/ULID"
          },
          "attributes": {
            "description": "The attributes of the resource",
            "$ref": "#/components/schemas/PolicyData"
          },
          "links": {
            "description": "Related links",
            "$ref": "#/components/schemas/SelfLinks"
          }
        }
      },
      "PolicyData": {
        "description": "The policy data",
        "type": "object",
        "required": [
          "created_at",
          "data"
        ],
        "properties": {
          "created_at": {
            "description": "The creation date of the policy data",
            "type": "string",
            "format": "date-time"
          },
          "data": {
            "description": "The policy data content"
          }
        }
      },
      "UserFilter": {
        "type": "object",
        "properties": {
          "filter[admin]": {
            "description": "Retrieve users with (or without) the `admin` flag set",
            "type": "boolean",
            "nullable": true
          },
          "filter[status]": {
            "description": "Retrieve the items with the given status\n\nDefaults to retrieve all users, including locked ones.\n\n* `active`: Only retrieve active users\n\n* `locked`: Only retrieve locked users (includes deactivated users)\n\n* `deactivated`: Only retrieve deactivated users",
            "$ref": "#/components/schemas/UserStatus",
            "nullable": true
          }
        }
      },
      "UserStatus": {
        "type": "string",
        "enum": [
          "active",
          "locked",
          "deactivated"
        ]
      },
      "PaginatedResponse_for_User": {
        "description": "A top-level response with a page of resources",
        "type": "object",
        "required": [
          "data",
          "links",
          "meta"
        ],
        "properties": {
          "meta": {
            "description": "Response metadata",
            "$ref": "#/components/schemas/PaginationMeta"
          },
          "data": {
            "description": "The list of resources",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SingleResource_for_User"
            }
          },
          "links": {
            "description": "Related links",
            "$ref": "#/components/schemas/PaginationLinks"
          }
        }
      },
      "SingleResource_for_User": {
        "description": "A single resource, with its type, ID, attributes and related links",
        "type": "object",
        "required": [
          "attributes",
          "id",
          "links",
          "type"
        ],
        "properties": {
          "type": {
            "description": "The type of the resource",
            "type": "string"
          },
          "id": {
            "description": "The ID of the resource",
            "$ref": "#/components/schemas/ULID"
          },
          "attributes": {
            "description": "The attributes of the resource",
            "$ref": "#/components/schemas/User"
          },
          "links": {
            "description": "Related links",
            "$ref": "#/components/schemas/SelfLinks"
          }
        }
      },
      "User": {
        "description": "A user",
        "type": "object",
        "required": [
          "admin",
          "created_at",
          "username"
        ],
        "properties": {
          "username": {
            "description": "The username (localpart) of the user",
            "type": "string"
          },
          "created_at": {
            "description": "When the user was created",
            "type": "string",
            "format": "date-time"
          },
          "locked_at": {
            "description": "When the user was locked. If null, the user is not locked.",
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "deactivated_at": {
            "description": "When the user was deactivated. If null, the user is not deactivated.",
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "admin": {
            "description": "Whether the user can request admin privileges.",
            "type": "boolean"
          }
        }
      },
      "AddUserRequest": {
        "title": "JSON payload for the `POST /api/admin/v1/users` endpoint",
        "type": "object",
        "required": [
          "username"
        ],
        "properties": {
          "username": {
            "description": "The username of the user to add.",
            "type": "string"
          },
          "skip_homeserver_check": {
            "description": "Skip checking with the homeserver whether the username is available.\n\nUse this with caution! The main reason to use this, is when a user used by an application service needs to exist in MAS to craft special tokens (like with admin access) for them",
            "default": false,
            "type": "boolean"
          }
        }
      },
      "SingleResponse_for_User": {
        "description": "A top-level response with a single resource",
        "type": "object",
        "required": [
          "data",
          "links"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/SingleResource_for_User"
          },
          "links": {
            "$ref": "#/components/schemas/SelfLinks"
          }
        }
      },
      "SetUserPasswordRequest": {
        "title": "JSON payload for the `POST /api/admin/v1/users/:id/set-password` endpoint",
        "type": "object",
        "required": [
          "password"
        ],
        "properties": {
          "password": {
            "description": "The password to set for the user",
            "examples": [
              "hunter2"
            ],
            "type": "string"
          },
          "skip_password_check": {
            "description": "Skip the password complexity check",
            "type": "boolean",
            "nullable": true
          }
        }
      },
      "UsernamePathParam": {
        "type": "object",
        "required": [
          "username"
        ],
        "properties": {
          "username": {
            "description": "The username (localpart) of the user to get",
            "type": "string"
          }
        }
      },
      "UserSetAdminRequest": {
        "title": "JSON payload for the `POST /api/admin/v1/users/:id/set-admin` endpoint",
        "type": "object",
        "required": [
          "admin"
        ],
        "properties": {
          "admin": {
            "description": "Whether the user can request admin privileges.",
            "type": "boolean"
          }
        }
      },
      "UserEmailFilter": {
        "type": "object",
        "properties": {
          "filter[user]": {
            "description": "Retrieve the items for the given user",
            "$ref": "#/components/schemas/ULID",
            "nullable": true
          },
          "filter[email]": {
            "description": "Retrieve the user email with the given email address",
            "type": "string",
            "nullable": true
          }
        }
      },
      "PaginatedResponse_for_UserEmail": {
        "description": "A top-level response with a page of resources",
        "type": "object",
        "required": [
          "data",
          "links",
          "meta"
        ],
        "properties": {
          "meta": {
            "description": "Response metadata",
            "$ref": "#/components/schemas/PaginationMeta"
          },
          "data": {
            "description": "The list of resources",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SingleResource_for_UserEmail"
            }
          },
          "links": {
            "description": "Related links",
            "$ref": "#/components/schemas/PaginationLinks"
          }
        }
      },
      "SingleResource_for_UserEmail": {
        "description": "A single resource, with its type, ID, attributes and related links",
        "type": "object",
        "required": [
          "attributes",
          "id",
          "links",
          "type"
        ],
        "properties": {
          "type": {
            "description": "The type of the resource",
            "type": "string"
          },
          "id": {
            "description": "The ID of the resource",
            "$ref": "#/components/schemas/ULID"
          },
          "attributes": {
            "description": "The attributes of the resource",
            "$ref": "#/components/schemas/UserEmail"
          },
          "links": {
            "description": "Related links",
            "$ref": "#/components/schemas/SelfLinks"
          }
        }
      },
      "UserEmail": {
        "description": "An email address for a user",
        "type": "object",
        "required": [
          "created_at",
          "email",
          "user_id"
        ],
        "properties": {
          "created_at": {
            "description": "When the object was created",
            "type": "string",
            "format": "date-time"
          },
          "user_id": {
            "description": "The ID of the user who owns this email address",
            "$ref": "#/components/schemas/ULID"
          },
          "email": {
            "description": "The email address",
            "type": "string"
          }
        }
      },
      "AddUserEmailRequest": {
        "title": "JSON payload for the `POST /api/admin/v1/user-emails`",
        "type": "object",
        "required": [
          "email",
          "user_id"
        ],
        "properties": {
          "user_id": {
            "description": "The ID of the user to which the email should be added.",
            "$ref": "#/components/schemas/ULID"
          },
          "email": {
            "description": "The email address of the user to add.",
            "type": "string",
            "format": "email"
          }
        }
      },
      "SingleResponse_for_UserEmail": {
        "description": "A top-level response with a single resource",
        "type": "object",
        "required": [
          "data",
          "links"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/SingleResource_for_UserEmail"
          },
          "links": {
            "$ref": "#/components/schemas/SelfLinks"
          }
        }
      },
      "UserSessionFilter": {
        "type": "object",
        "properties": {
          "filter[user]": {
            "description": "Retrieve the items for the given user",
            "$ref": "#/components/schemas/ULID",
            "nullable": true
          },
          "filter[status]": {
            "description": "Retrieve the items with the given status\n\nDefaults to retrieve all sessions, including finished ones.\n\n* `active`: Only retrieve active sessions\n\n* `finished`: Only retrieve finished sessions",
            "$ref": "#/components/schemas/UserSessionStatus",
            "nullable": true
          }
        }
      },
      "UserSessionStatus": {
        "type": "string",
        "enum": [
          "active",
          "finished"
        ]
      },
      "PaginatedResponse_for_UserSession": {
        "description": "A top-level response with a page of resources",
        "type": "object",
        "required": [
          "data",
          "links",
          "meta"
        ],
        "properties": {
          "meta": {
            "description": "Response metadata",
            "$ref": "#/components/schemas/PaginationMeta"
          },
          "data": {
            "description": "The list of resources",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SingleResource_for_UserSession"
            }
          },
          "links": {
            "description": "Related links",
            "$ref": "#/components/schemas/PaginationLinks"
          }
        }
      },
      "SingleResource_for_UserSession": {
        "description": "A single resource, with its type, ID, attributes and related links",
        "type": "object",
        "required": [
          "attributes",
          "id",
          "links",
          "type"
        ],
        "properties": {
          "type": {
            "description": "The type of the resource",
            "type": "string"
          },
          "id": {
            "description": "The ID of the resource",
            "$ref": "#/components/schemas/ULID"
          },
          "attributes": {
            "description": "The attributes of the resource",
            "$ref": "#/components/schemas/UserSession"
          },
          "links": {
            "description": "Related links",
            "$ref": "#/components/schemas/SelfLinks"
          }
        }
      },
      "UserSession": {
        "description": "The browser (cookie) session for a user",
        "type": "object",
        "required": [
          "created_at",
          "user_id"
        ],
        "properties": {
          "created_at": {
            "description": "When the object was created",
            "type": "string",
            "format": "date-time"
          },
          "finished_at": {
            "description": "When the session was finished",
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "user_id": {
            "description": "The ID of the user who owns the session",
            "$ref": "#/components/schemas/ULID"
          },
          "user_agent": {
            "description": "The user agent string of the client which started this session",
            "type": "string",
            "nullable": true
          },
          "last_active_at": {
            "description": "The last time the session was active",
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_active_ip": {
            "description": "The last IP address used by the session",
            "type": "string",
            "format": "ip",
            "nullable": true
          }
        }
      },
      "SingleResponse_for_UserSession": {
        "description": "A top-level response with a single resource",
        "type": "object",
        "required": [
          "data",
          "links"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/SingleResource_for_UserSession"
          },
          "links": {
            "$ref": "#/components/schemas/SelfLinks"
          }
        }
      },
      "UpstreamOAuthLinkFilter": {
        "type": "object",
        "properties": {
          "filter[user]": {
            "description": "Retrieve the items for the given user",
            "$ref": "#/components/schemas/ULID",
            "nullable": true
          },
          "filter[provider]": {
            "description": "Retrieve the items for the given provider",
            "$ref": "#/components/schemas/ULID",
            "nullable": true
          },
          "filter[subject]": {
            "description": "Retrieve the items with the given subject",
            "type": "string",
            "nullable": true
          }
        }
      },
      "PaginatedResponse_for_UpstreamOAuthLink": {
        "description": "A top-level response with a page of resources",
        "type": "object",
        "required": [
          "data",
          "links",
          "meta"
        ],
        "properties": {
          "meta": {
            "description": "Response metadata",
            "$ref": "#/components/schemas/PaginationMeta"
          },
          "data": {
            "description": "The list of resources",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SingleResource_for_UpstreamOAuthLink"
            }
          },
          "links": {
            "description": "Related links",
            "$ref": "#/components/schemas/PaginationLinks"
          }
        }
      },
      "SingleResource_for_UpstreamOAuthLink": {
        "description": "A single resource, with its type, ID, attributes and related links",
        "type": "object",
        "required": [
          "attributes",
          "id",
          "links",
          "type"
        ],
        "properties": {
          "type": {
            "description": "The type of the resource",
            "type": "string"
          },
          "id": {
            "description": "The ID of the resource",
            "$ref": "#/components/schemas/ULID"
          },
          "attributes": {
            "description": "The attributes of the resource",
            "$ref": "#/components/schemas/UpstreamOAuthLink"
          },
          "links": {
            "description": "Related links",
            "$ref": "#/components/schemas/SelfLinks"
          }
        }
      },
      "UpstreamOAuthLink": {
        "description": "An upstream OAuth 2.0 link",
        "type": "object",
        "required": [
          "created_at",
          "provider_id",
          "subject"
        ],
        "properties": {
          "created_at": {
            "description": "When the object was created",
            "type": "string",
            "format": "date-time"
          },
          "provider_id": {
            "description": "The ID of the provider",
            "$ref": "#/components/schemas/ULID"
          },
          "subject": {
            "description": "The subject of the upstream account, unique per provider",
            "type": "string"
          },
          "user_id": {
            "description": "The ID of the user who owns this link, if any",
            "$ref": "#/components/schemas/ULID",
            "nullable": true
          },
          "human_account_name": {
            "description": "A human-readable name of the upstream account",
            "type": "string",
            "nullable": true
          }
        }
      },
      "AddUpstreamOauthLinkRequest": {
        "title": "JSON payload for the `POST /api/admin/v1/upstream-oauth-links`",
        "type": "object",
        "required": [
          "provider_id",
          "subject",
          "user_id"
        ],
        "properties": {
          "user_id": {
            "description": "The ID of the user to which the link should be added.",
            "$ref": "#/components/schemas/ULID"
          },
          "provider_id": {
            "description": "The ID of the upstream provider to which the link is for.",
            "$ref": "#/components/schemas/ULID"
          },
          "subject": {
            "description": "The subject (sub) claim of the user on the provider.",
            "type": "string"
          },
          "human_account_name": {
            "description": "A human readable account name.",
            "type": "string",
            "nullable": true
          }
        }
      },
      "SingleResponse_for_UpstreamOAuthLink": {
        "description": "A top-level response with a single resource",
        "type": "object",
        "required": [
          "data",
          "links"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/SingleResource_for_UpstreamOAuthLink"
          },
          "links": {
            "$ref": "#/components/schemas/SelfLinks"
          }
        }
      }
    }
  },
  "security": [
    {
      "oauth2": [
        "urn:mas:admin"
      ]
    },
    {
      "bearer": [
        "urn:mas:admin"
      ]
    }
  ],
  "tags": [
    {
      "name": "compat-session",
      "description": "Manage compatibility sessions from legacy clients"
    },
    {
      "name": "policy-data",
      "description": "Manage the dynamic policy data"
    },
    {
      "name": "oauth2-session",
      "description": "Manage OAuth2 sessions"
    },
    {
      "name": "user",
      "description": "Manage users"
    },
    {
      "name": "user-email",
      "description": "Manage emails associated with users"
    },
    {
      "name": "user-session",
      "description": "Manage browser sessions of users"
    },
    {
      "name": "upstream-oauth-link",
      "description": "Manage links between local users and identities from upstream OAuth 2.0 providers"
    }
  ]
}
