{
  "openapi": "3.1.0",
  "info": {
    "title": "NextExplorer API",
    "version": "unversioned",
    "description": "Everything the interface does, it does over this API: there is no reduced\nAPI for automation.\n\n**Signing in.** A script should use an API token, from Settings → API tokens,\nin `Authorization: Bearer nxe_…`. A `read` token reaches reads only; no\ntoken reaches the account, administration, the terminal or the editor\nintegrations. The interface uses a session cookie from `POST /api/auth/login`.\nWho may call each operation is in its security requirements and, in words, in\n`x-access`.\n\n**Paths.** Files are named by where they are: a volume path\n(`Documents/2026/report.pdf`), `personal/…` for the account’s own folder, an\nassigned volume’s label, or `share/<token>/…` inside a link.\n\n**Errors** are JSON and carry a `requestId` that also appears in the server\nlog. **Nothing is ever written over:** a name already taken becomes `name (1)`.\n\n**Not versioned.** This is the interface’s own API and changes with it; an\ninstance serves the description of its own release at `/api/openapi.json`.",
    "license": {
      "name": "MIT",
      "identifier": "MIT"
    }
  },
  "servers": [
    {
      "url": "/",
      "description": "The instance serving this description."
    }
  ],
  "tags": [
    {
      "name": "Accounts and signing in",
      "description": "Sessions, passwords, second factors and passkeys."
    },
    {
      "name": "API tokens",
      "description": "Credentials for scripts, managed from a session."
    },
    {
      "name": "Browsing",
      "description": "Volumes, folders and what is known about a file."
    },
    {
      "name": "Search",
      "description": "Names and contents."
    },
    {
      "name": "Files",
      "description": "Making, renaming, copying, moving, deleting and downloading."
    },
    {
      "name": "Editing",
      "description": "Text files, read and saved."
    },
    {
      "name": "Previews",
      "description": "Thumbnails, media and what the viewer shows."
    },
    {
      "name": "Archives",
      "description": "Looking inside, taking out, making and unpacking."
    },
    {
      "name": "Uploads",
      "description": "In one request, or resumable over TUS."
    },
    {
      "name": "Folder sizes",
      "description": "What a folder holds, from the folder-size index."
    },
    {
      "name": "Sharing",
      "description": "Links and shares, made and managed by their owner."
    },
    {
      "name": "Shared links",
      "description": "What somebody holding a link can do with it."
    },
    {
      "name": "Trash",
      "description": "What was deleted, and bringing it back."
    },
    {
      "name": "Versions",
      "description": "Earlier contents of a file."
    },
    {
      "name": "Favourites",
      "description": "Folders kept at hand."
    },
    {
      "name": "Settings",
      "description": "The installation’s and the account’s."
    },
    {
      "name": "Accounts (administration)",
      "description": "Accounts, and the volumes assigned to them."
    },
    {
      "name": "Administration",
      "description": "The activity log, the server’s files, the terminal."
    },
    {
      "name": "ONLYOFFICE",
      "description": "Mounted only where ONLYOFFICE is configured."
    },
    {
      "name": "Collabora",
      "description": "Mounted only where Collabora is configured."
    },
    {
      "name": "Health",
      "description": "For probes; outside `/api`."
    }
  ],
  "security": [
    {
      "session": []
    },
    {
      "apiToken": []
    }
  ],
  "paths": {
    "/api/auth/status": {
      "get": {
        "operationId": "getAuthStatus",
        "summary": "What the sign-in screen needs to know",
        "description": "Whether the installation still needs its first account, which ways in are offered, and who this browser is, if anybody. Answered to anybody.",
        "tags": ["Accounts and signing in"],
        "security": [],
        "x-access": "public",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "requiresSetup": {
                      "type": "boolean",
                      "description": "No account exists yet: `POST /api/auth/setup` creates the first."
                    },
                    "strategies": {
                      "type": "object",
                      "properties": {
                        "local": {
                          "type": "boolean"
                        },
                        "oidc": {
                          "type": "boolean"
                        },
                        "passkey": {
                          "type": "boolean"
                        }
                      }
                    },
                    "totpPending": {
                      "type": "boolean",
                      "description": "A password was accepted and the code is still awaited."
                    },
                    "authEnabled": {
                      "type": "boolean"
                    },
                    "authMode": {
                      "type": "string",
                      "enum": ["local", "oidc", "both"]
                    },
                    "authenticated": {
                      "type": "boolean"
                    },
                    "user": {
                      "anyOf": [
                        {
                          "$ref": "#/components/schemas/User"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "oidc": {
                      "type": "object",
                      "properties": {
                        "enabled": {
                          "type": "boolean"
                        },
                        "issuer": {
                          "type": ["string", "null"]
                        },
                        "scopes": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "status": {
                          "type": "string",
                          "description": "What configuring the provider concluded."
                        }
                      }
                    }
                  },
                  "required": [
                    "requiresSetup",
                    "strategies",
                    "authEnabled",
                    "authMode",
                    "authenticated"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/auth/setup": {
      "post": {
        "operationId": "setUpFirstAccount",
        "summary": "Create the first account, an administrator",
        "description": "Only while no account exists. Signs the new account in.",
        "tags": ["Accounts and signing in"],
        "security": [],
        "x-access": "public",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "username": {
                    "type": "string",
                    "description": "Defaults to what is before the @."
                  },
                  "password": {
                    "type": "string",
                    "format": "password"
                  }
                },
                "required": ["email", "password"]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created and signed in.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user": {
                      "$ref": "#/components/schemas/User"
                    }
                  },
                  "required": ["user"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          }
        }
      }
    },
    "/api/auth/login": {
      "post": {
        "operationId": "signIn",
        "summary": "Sign in with a password",
        "description": "Answers the account and sets the session cookie. An account with a second factor answers `{ \"totpRequired\": true }` instead, and the session holds the sign-in for five minutes until the code arrives.",
        "tags": ["Accounts and signing in"],
        "security": [],
        "x-access": "public",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "identifier": {
                    "type": "string",
                    "description": "An email address or a username."
                  },
                  "email": {
                    "type": "string",
                    "description": "Older name for `identifier`.",
                    "deprecated": true
                  },
                  "username": {
                    "type": "string",
                    "description": "Older name for `identifier`.",
                    "deprecated": true
                  },
                  "password": {
                    "type": "string",
                    "format": "password"
                  }
                },
                "required": ["password"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Signed in, or halfway there.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "user": {
                          "$ref": "#/components/schemas/User"
                        }
                      },
                      "required": ["user"]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "totpRequired": {
                          "const": true
                        }
                      },
                      "required": ["totpRequired"],
                      "description": "The password was right; finish at `POST /api/auth/login/totp`."
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          }
        }
      }
    },
    "/api/auth/login/totp": {
      "post": {
        "operationId": "signInSecondStep",
        "summary": "Finish signing in with a code",
        "description": "The six digits from the authenticator, or one recovery code. A wrong code counts against the same lockout as a wrong password (`AUTH_INVALID_TOTP_CODE`).",
        "tags": ["Accounts and signing in"],
        "security": [],
        "x-access": "public",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string",
                    "description": "Six digits, or a recovery code."
                  }
                },
                "required": ["code"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Signed in.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user": {
                      "$ref": "#/components/schemas/User"
                    },
                    "usedRecoveryCode": {
                      "type": "boolean"
                    },
                    "recoveryCodesLeft": {
                      "type": ["integer", "null"]
                    }
                  },
                  "required": ["user"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          }
        }
      }
    },
    "/api/auth/login/passkey/start": {
      "post": {
        "operationId": "startPasskeySignIn",
        "summary": "Begin signing in with a passkey",
        "description": "The challenge inside `options` is spent by the matching finish.",
        "tags": ["Accounts and signing in"],
        "security": [],
        "x-access": "public",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PasskeyOptions"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          }
        }
      }
    },
    "/api/auth/login/passkey/finish": {
      "post": {
        "operationId": "finishPasskeySignIn",
        "summary": "Sign in with the passkey’s answer",
        "description": "Every refusal is `401` with `AUTH_PASSKEY_REJECTED`, whatever the reason. A passkey that was not unlocked on an account with a second factor answers `{ \"totpRequired\": true }`.",
        "tags": ["Accounts and signing in"],
        "security": [],
        "x-access": "public",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "response": {
                    "type": "object",
                    "properties": {},
                    "additionalProperties": true,
                    "description": "What `navigator.credentials.get` returned."
                  }
                },
                "required": ["response"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "user": {
                          "$ref": "#/components/schemas/User"
                        }
                      },
                      "required": ["user"]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "totpRequired": {
                          "const": true
                        }
                      },
                      "required": ["totpRequired"],
                      "description": "The password was right; finish at `POST /api/auth/login/totp`."
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          }
        }
      }
    },
    "/api/auth/logout": {
      "post": {
        "operationId": "signOut",
        "summary": "Sign out this session",
        "description": "Ends the application’s session. Signing out at the identity provider as well is `GET /logout`, which a browser navigates to.",
        "tags": ["Accounts and signing in"],
        "security": [],
        "x-access": "public",
        "responses": {
          "204": {
            "description": "Signed out."
          }
        }
      }
    },
    "/api/auth/me": {
      "get": {
        "operationId": "whoAmI",
        "summary": "The account this request is made as",
        "description": "`{ \"user\": null }` when nobody is signed in. The one account route an API token may call.",
        "tags": ["Accounts and signing in"],
        "security": [],
        "x-access": "public",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user": {
                      "anyOf": [
                        {
                          "$ref": "#/components/schemas/User"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": ["user"]
                }
              }
            }
          }
        }
      }
    },
    "/api/auth/methods": {
      "get": {
        "operationId": "listSignInMethods",
        "summary": "The ways this account signs in",
        "tags": ["Accounts and signing in"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "methods": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "type": {
                            "type": "string",
                            "examples": ["local_password", "oidc"]
                          },
                          "provider": {
                            "type": "string"
                          },
                          "lastUsedAt": {
                            "type": ["string", "null"],
                            "format": "date-time"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  },
                  "required": ["methods"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      }
    },
    "/api/auth/password": {
      "post": {
        "operationId": "changePassword",
        "summary": "Change this account’s password",
        "description": "Signs out every other session of the account, and moves this one to a new cookie, which the response sets.",
        "tags": ["Accounts and signing in"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "currentPassword": {
                    "type": "string",
                    "description": "The account’s current password.",
                    "format": "password"
                  },
                  "newPassword": {
                    "type": "string",
                    "format": "password"
                  }
                },
                "required": ["currentPassword", "newPassword"]
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Changed."
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          }
        }
      }
    },
    "/api/auth/password/add": {
      "post": {
        "operationId": "addPassword",
        "summary": "Give a password to an account that signs in elsewhere",
        "description": "For an account made through the identity provider. `409` when it has one.",
        "tags": ["Accounts and signing in"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "password": {
                    "type": "string",
                    "format": "password"
                  }
                },
                "required": ["password"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": ["message"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          }
        }
      }
    },
    "/api/auth/totp": {
      "get": {
        "operationId": "getSecondFactor",
        "summary": "Whether this account asks for a code",
        "tags": ["Accounts and signing in"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "enabled": {
                      "type": "boolean"
                    },
                    "pending": {
                      "type": "boolean",
                      "description": "Started and not yet confirmed."
                    },
                    "confirmedAt": {
                      "type": ["string", "null"],
                      "format": "date-time"
                    },
                    "recoveryCodesLeft": {
                      "type": "integer"
                    }
                  },
                  "required": ["enabled", "pending", "recoveryCodesLeft"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      },
      "delete": {
        "operationId": "turnOffSecondFactor",
        "summary": "Stop asking this account for a code",
        "tags": ["Accounts and signing in"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "password": {
                    "type": "string",
                    "description": "The account’s current password.",
                    "format": "password"
                  }
                },
                "required": ["password"]
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Off."
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          }
        }
      }
    },
    "/api/auth/totp/start": {
      "post": {
        "operationId": "startSecondFactor",
        "summary": "Draw a secret for an authenticator",
        "description": "From a session opened with the password. Nothing is asked of the account until `confirm` proves the phone holds the same secret.",
        "tags": ["Accounts and signing in"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "secret": {
                      "type": "string",
                      "description": "Base32."
                    },
                    "uri": {
                      "type": "string",
                      "description": "`otpauth://…`, for a QR code."
                    }
                  },
                  "required": ["secret", "uri"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          }
        }
      }
    },
    "/api/auth/totp/confirm": {
      "post": {
        "operationId": "confirmSecondFactor",
        "summary": "Turn the second factor on with a first code",
        "description": "Answers the recovery codes, once.",
        "tags": ["Accounts and signing in"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string",
                    "description": "Six digits."
                  }
                },
                "required": ["code"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "recoveryCodes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": ["recoveryCodes"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          }
        }
      }
    },
    "/api/auth/totp/recovery-codes": {
      "post": {
        "operationId": "replaceRecoveryCodes",
        "summary": "Draw new recovery codes",
        "description": "The old ones stop working.",
        "tags": ["Accounts and signing in"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "password": {
                    "type": "string",
                    "description": "The account’s current password.",
                    "format": "password"
                  }
                },
                "required": ["password"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "recoveryCodes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": ["recoveryCodes"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          }
        }
      }
    },
    "/api/auth/passkeys": {
      "get": {
        "operationId": "listPasskeys",
        "summary": "The passkeys on this account",
        "tags": ["Accounts and signing in"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "passkeys": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Passkey"
                      }
                    }
                  },
                  "required": ["passkeys"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      }
    },
    "/api/auth/passkeys/register/start": {
      "post": {
        "operationId": "startPasskeyRegistration",
        "summary": "Begin adding a passkey",
        "description": "From a session opened with the password.",
        "tags": ["Accounts and signing in"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PasskeyOptions"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          }
        }
      }
    },
    "/api/auth/passkeys/register/finish": {
      "post": {
        "operationId": "finishPasskeyRegistration",
        "summary": "Keep the passkey the browser just made",
        "tags": ["Accounts and signing in"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "response": {
                    "type": "object",
                    "properties": {},
                    "additionalProperties": true,
                    "description": "What `navigator.credentials.create` returned."
                  },
                  "name": {
                    "type": "string",
                    "description": "What to call it."
                  }
                },
                "required": ["response"]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Kept.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "passkey": {
                      "$ref": "#/components/schemas/Passkey"
                    }
                  },
                  "required": ["passkey"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          }
        }
      }
    },
    "/api/auth/passkeys/{id}": {
      "patch": {
        "operationId": "renamePasskey",
        "summary": "Rename a passkey",
        "tags": ["Accounts and signing in"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The passkey.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  }
                },
                "required": ["name"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "passkey": {
                      "$ref": "#/components/schemas/Passkey"
                    }
                  },
                  "required": ["passkey"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      },
      "delete": {
        "operationId": "removePasskey",
        "summary": "Remove a passkey",
        "tags": ["Accounts and signing in"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The passkey.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "description": "The password, when the account has one.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "password": {
                    "type": "string",
                    "description": "The account’s current password.",
                    "format": "password"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Removed."
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          }
        }
      }
    },
    "/api/auth/tokens": {
      "get": {
        "operationId": "listApiTokens",
        "summary": "The live API tokens of this account",
        "tags": ["API tokens"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tokens": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ApiToken"
                      }
                    }
                  },
                  "required": ["tokens"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      },
      "post": {
        "operationId": "issueApiToken",
        "summary": "Issue an API token",
        "description": "The only time `secret` exists: it is stored hashed. Fifty per account; asks for the password when the account has one.",
        "tags": ["API tokens"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "scope": {
                    "type": "string",
                    "enum": ["read", "write"],
                    "default": "read"
                  },
                  "expiresInDays": {
                    "type": ["integer", "null"],
                    "description": "Up to 3650; null for one that lasts until revoked.",
                    "minimum": 1,
                    "maximum": 3650
                  },
                  "password": {
                    "type": "string",
                    "description": "The account’s current password.",
                    "format": "password"
                  }
                },
                "required": ["name"]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Issued.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "token": {
                      "$ref": "#/components/schemas/ApiToken"
                    },
                    "secret": {
                      "type": "string",
                      "description": "`nxe_…`, shown this once."
                    }
                  },
                  "required": ["token", "secret"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          }
        }
      }
    },
    "/api/auth/tokens/{id}": {
      "patch": {
        "operationId": "renameApiToken",
        "summary": "Rename an API token",
        "tags": ["API tokens"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The token’s id, not its secret.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  }
                },
                "required": ["name"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "token": {
                      "$ref": "#/components/schemas/ApiToken"
                    }
                  },
                  "required": ["token"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      },
      "delete": {
        "operationId": "revokeApiToken",
        "summary": "Revoke an API token",
        "description": "It stops working on the next request. Asks for nothing, so a leak can be stopped at once.",
        "tags": ["API tokens"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The token’s id, not its secret.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Revoked."
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/auth/oidc/login": {
      "get": {
        "operationId": "signInWithProvider",
        "summary": "Go to the identity provider",
        "description": "A browser navigation, answered with a redirect; `404` where no provider is configured.",
        "tags": ["Accounts and signing in"],
        "security": [],
        "x-access": "public",
        "parameters": [
          {
            "name": "redirect",
            "in": "query",
            "required": false,
            "description": "Where to land afterwards, inside this application.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "prompt",
            "in": "query",
            "required": false,
            "description": "Passed on to the provider — `login`, `consent`, `select_account`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "To the provider."
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "502": {
            "$ref": "#/components/responses/E502"
          },
          "503": {
            "$ref": "#/components/responses/E503"
          }
        }
      }
    },
    "/api/auth/oidc/mobile/login": {
      "get": {
        "operationId": "signInWithProviderFromApp",
        "summary": "Go to the identity provider, for the mobile application",
        "description": "PKCE: the application later trades the code it receives at `POST /api/auth/oidc/exchange`.",
        "tags": ["Accounts and signing in"],
        "security": [],
        "x-access": "public",
        "parameters": [
          {
            "name": "code_challenge",
            "in": "query",
            "required": true,
            "description": "S256 challenge.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "code_challenge_method",
            "in": "query",
            "required": false,
            "description": "Only `S256`.",
            "schema": {
              "type": "string",
              "enum": ["S256"]
            }
          },
          {
            "name": "redirect_uri",
            "in": "query",
            "required": false,
            "description": "One of `OIDC_MOBILE_REDIRECT_URIS`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "To the provider."
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "502": {
            "$ref": "#/components/responses/E502"
          },
          "503": {
            "$ref": "#/components/responses/E503"
          }
        }
      }
    },
    "/api/auth/oidc/mobile/complete": {
      "get": {
        "operationId": "returnToApp",
        "summary": "Back from the provider, on the way to the mobile application",
        "tags": ["Accounts and signing in"],
        "security": [],
        "x-access": "public",
        "responses": {
          "302": {
            "description": "To the application’s redirect URI, with `code` or `error`."
          },
          "400": {
            "$ref": "#/components/responses/E400"
          }
        }
      }
    },
    "/api/auth/oidc/exchange": {
      "post": {
        "operationId": "exchangeMobileCode",
        "summary": "Trade the mobile application’s code for a session",
        "tags": ["Accounts and signing in"],
        "security": [],
        "x-access": "public",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string"
                  },
                  "code_verifier": {
                    "type": "string"
                  }
                },
                "required": ["code", "code_verifier"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Signed in.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user": {
                      "$ref": "#/components/schemas/User"
                    }
                  },
                  "required": ["user"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          }
        }
      }
    },
    "/api/volumes": {
      "get": {
        "operationId": "listVolumes",
        "summary": "The places this account can start from",
        "description": "The volume’s top folders, the personal folder when there is one, and for somebody given assigned volumes, those instead.",
        "tags": ["Browsing"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string"
                      },
                      "path": {
                        "type": "string"
                      },
                      "kind": {
                        "type": "string",
                        "enum": ["volume", "personal"]
                      },
                      "readOnly": {
                        "type": ["string", "null"],
                        "description": "Why nothing can be written in it, for the mark beside its name: `storage` for a read-only mount, `permission` for a folder the server may not write in, `access` when a rule or its assignment keeps this account to reading. Null when something can be written.",
                        "enum": ["storage", "permission", "access", null]
                      }
                    },
                    "required": ["name", "path", "kind"]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          }
        }
      }
    },
    "/api/browse/{path}": {
      "get": {
        "operationId": "browse",
        "summary": "What a folder holds, and what this caller may do there",
        "description": "`path` is a volume path (`Documents/2026`), `personal/…` for the personal folder, or an assigned volume’s label. Hidden files are listed when the account has asked to see them.",
        "tags": ["Browsing"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "path",
            "in": "path",
            "required": true,
            "description": "The path, slashes included; empty for the top.",
            "schema": {
              "type": "string"
            },
            "allowReserved": true
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Item"
                      }
                    },
                    "access": {
                      "$ref": "#/components/schemas/Access"
                    },
                    "current": {
                      "type": "object",
                      "properties": {
                        "isDirectory": {
                          "type": "boolean"
                        }
                      }
                    },
                    "path": {
                      "type": "string",
                      "description": "The folder, as it was resolved."
                    }
                  },
                  "required": ["items", "access", "path"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/usage/{path}": {
      "get": {
        "operationId": "getVolumeUsage",
        "summary": "How full the file system under a path is",
        "tags": ["Browsing"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "path",
            "in": "path",
            "required": true,
            "description": "The path, slashes included; empty for the top.",
            "schema": {
              "type": "string"
            },
            "allowReserved": true
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "path": {
                      "type": "string"
                    },
                    "size": {
                      "type": "number"
                    },
                    "used": {
                      "type": "number"
                    },
                    "free": {
                      "type": "number"
                    },
                    "total": {
                      "type": "number"
                    },
                    "percentUsed": {
                      "type": "number"
                    }
                  },
                  "required": ["path"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/metadata/{path}": {
      "get": {
        "operationId": "getMetadata",
        "summary": "What is known about one file or folder",
        "description": "For a folder, the total of what is inside it, counted now and stopped at a bound (`truncated`). For an image, a video or a document, what reading it says — dimensions, duration, pages.",
        "tags": ["Browsing"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "path",
            "in": "path",
            "required": true,
            "description": "The file or folder.",
            "schema": {
              "type": "string"
            },
            "allowReserved": true
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "path": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "kind": {
                      "type": "string"
                    },
                    "size": {
                      "type": "number"
                    },
                    "dateModified": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "dateCreated": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "directory": {
                      "type": "object",
                      "properties": {
                        "totalSize": {
                          "type": "number"
                        },
                        "fileCount": {
                          "type": "integer"
                        },
                        "dirCount": {
                          "type": "integer"
                        },
                        "truncated": {
                          "type": "boolean"
                        }
                      }
                    }
                  },
                  "required": ["path", "name", "kind"],
                  "additionalProperties": true
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/search": {
      "get": {
        "operationId": "search",
        "summary": "Find files by name and by what they say",
        "description": "Names first, closest match first; then documents that contain the term, the most relevant first. The term is a word or the beginning of one, three characters at least; `*` and `?` make it a pattern for names. `truncated` says the search ran out of time before looking everywhere, `complete` that the page is the whole answer.",
        "tags": ["Search"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "What to look for.",
            "schema": {
              "type": "string",
              "minLength": 3
            }
          },
          {
            "name": "path",
            "in": "query",
            "required": false,
            "description": "Where to start; the top when absent.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "How many, up to 500.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "path": {
                            "type": "string"
                          },
                          "kind": {
                            "type": "string",
                            "enum": ["file", "dir"]
                          },
                          "matchLine": {
                            "type": "string",
                            "description": "The line that holds the term, for a match inside a file."
                          },
                          "matchLineNumber": {
                            "type": "integer"
                          },
                          "matchedName": {
                            "type": "boolean"
                          },
                          "matchedContent": {
                            "type": "boolean"
                          }
                        },
                        "required": ["name", "path", "kind"]
                      }
                    },
                    "truncated": {
                      "type": "boolean"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "complete": {
                      "type": "boolean"
                    }
                  },
                  "required": ["items", "truncated", "limit", "complete"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/permissions/{path}": {
      "get": {
        "operationId": "getFilePermissions",
        "summary": "Owner, group and mode of a file on the server",
        "tags": ["Browsing"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "path",
            "in": "path",
            "required": true,
            "description": "The file or folder.",
            "schema": {
              "type": "string"
            },
            "allowReserved": true
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "path": {
                      "type": "string"
                    },
                    "mode": {
                      "type": "integer",
                      "description": "The full `st_mode`."
                    },
                    "owner": {
                      "type": "string"
                    },
                    "group": {
                      "type": "string"
                    },
                    "uid": {
                      "type": "integer"
                    },
                    "gid": {
                      "type": "integer"
                    },
                    "isDirectory": {
                      "type": "boolean"
                    }
                  },
                  "required": ["path", "mode"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/permissions/chmod": {
      "post": {
        "operationId": "changeFileMode",
        "summary": "Change the mode of a file on the server",
        "tags": ["Administration"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string"
                  },
                  "mode": {
                    "type": "string",
                    "description": "Octal, as `chmod` takes it — `644`, `0755`."
                  },
                  "recursive": {
                    "type": "boolean"
                  }
                },
                "required": ["path", "mode"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "path": {
                      "type": "string"
                    },
                    "mode": {
                      "type": "integer"
                    }
                  },
                  "required": ["success", "path", "mode"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/permissions/chown": {
      "post": {
        "operationId": "changeFileOwner",
        "summary": "Change the owner or group of a file on the server",
        "description": "Usually refused unless the server runs as root.",
        "tags": ["Administration"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string"
                  },
                  "owner": {
                    "type": "string"
                  },
                  "group": {
                    "type": "string"
                  }
                },
                "required": ["path"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "path": {
                      "type": "string"
                    }
                  },
                  "required": ["success", "path"],
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/folder-size/{path}": {
      "get": {
        "operationId": "getFolderSize",
        "summary": "How much a folder holds, from the index",
        "description": "`404` when folder sizes are off.",
        "tags": ["Folder sizes"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "path",
            "in": "path",
            "required": true,
            "description": "The folder.",
            "schema": {
              "type": "string"
            },
            "allowReserved": true
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FolderSize"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/folder-size/batch": {
      "post": {
        "operationId": "getFolderSizes",
        "summary": "Sizes of several folders at once",
        "tags": ["Folder sizes"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "paths": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "required": ["paths"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/FolderSize"
                      }
                    },
                    "truncated": {
                      "type": "boolean",
                      "description": "More paths were asked for than one call answers."
                    }
                  },
                  "required": ["results", "truncated"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/folder-size/refresh/{path}": {
      "post": {
        "operationId": "refreshFolderSize",
        "summary": "Count a folder again",
        "description": "Queued; `400` until the index has finished its first pass.",
        "tags": ["Folder sizes"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "path",
            "in": "path",
            "required": true,
            "description": "The folder.",
            "schema": {
              "type": "string"
            },
            "allowReserved": true
          }
        ],
        "responses": {
          "202": {
            "description": "Queued.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/thumbnails/{path}": {
      "get": {
        "operationId": "getThumbnail",
        "summary": "Where the thumbnail of an image or video is, once it exists",
        "description": "`thumbnail` is a URL under `/static/thumbnails`, or empty while it is being made (`202`, `pending`).",
        "tags": ["Previews"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "path",
            "in": "path",
            "required": true,
            "description": "The file.",
            "schema": {
              "type": "string"
            },
            "allowReserved": true
          },
          {
            "name": "background",
            "in": "query",
            "required": false,
            "description": "`1` for a prefetch that may wait behind what is on screen.",
            "schema": {
              "type": "string",
              "enum": ["1"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "thumbnail": {
                      "type": "string"
                    },
                    "pending": {
                      "type": "boolean"
                    }
                  },
                  "required": ["thumbnail"]
                }
              }
            }
          },
          "202": {
            "description": "Being made.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "thumbnail": {
                      "type": "string"
                    },
                    "pending": {
                      "type": "boolean"
                    },
                    "queued": {
                      "type": "boolean"
                    }
                  },
                  "required": ["thumbnail"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/preview": {
      "get": {
        "operationId": "getPreview",
        "summary": "A file’s content, for showing it",
        "description": "Images, video, audio and PDF, with `Range` for media. `415` for a kind that has no preview.",
        "tags": ["Previews"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "path",
            "in": "query",
            "required": true,
            "description": "The file.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "required": false,
            "description": "Part of it, for media.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The file, with its own content type.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "206": {
            "description": "The part asked for.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "415": {
            "$ref": "#/components/responses/E415"
          },
          "416": {
            "description": "The range is outside the file."
          }
        }
      }
    },
    "/api/media/tracks": {
      "get": {
        "operationId": "getMediaTracks",
        "summary": "The video, audio and subtitle tracks of a media file",
        "tags": ["Previews"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "path",
            "in": "query",
            "required": true,
            "description": "The file.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "available": {
                      "type": "boolean",
                      "description": "Whether the tracks could be read at all."
                    },
                    "video": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      }
                    },
                    "audio": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      }
                    },
                    "subtitles": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      }
                    }
                  },
                  "required": ["available"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "415": {
            "$ref": "#/components/responses/E415"
          }
        }
      }
    },
    "/api/media/subtitle": {
      "get": {
        "operationId": "getSubtitle",
        "summary": "One subtitle track, as WebVTT",
        "tags": ["Previews"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "path",
            "in": "query",
            "required": true,
            "description": "The media file.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "stream",
            "in": "query",
            "required": false,
            "description": "A track inside the file, from `/api/media/tracks`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "file",
            "in": "query",
            "required": false,
            "description": "A subtitle file beside it, by name.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The track.",
            "content": {
              "text/vtt": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "415": {
            "$ref": "#/components/responses/E415"
          }
        }
      }
    },
    "/api/download": {
      "post": {
        "operationId": "download",
        "summary": "Download a file, or several as one zip",
        "description": "One file comes back as itself; several, or a folder, as a zip made as it is sent. The one POST a `read` API token may make.",
        "tags": ["Files"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "basePath": {
                    "type": "string",
                    "description": "The folder the names are relative to, which the zip starts from."
                  },
                  "currentPath": {
                    "type": "string",
                    "description": "Older name for `basePath`.",
                    "deprecated": true
                  },
                  "path": {
                    "type": "string",
                    "description": "One path."
                  },
                  "paths": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "path": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The file, or a zip.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/zip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/files/file": {
      "post": {
        "operationId": "createFile",
        "summary": "Create an empty file",
        "description": "Under `name (1)` when the name is taken; nothing is ever written over.",
        "tags": ["Files"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "The folder."
                  },
                  "destination": {
                    "type": "string",
                    "description": "Older name for `path`.",
                    "deprecated": true
                  },
                  "name": {
                    "type": "string"
                  }
                },
                "required": ["name"]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "item": {
                      "$ref": "#/components/schemas/Item"
                    }
                  },
                  "required": ["success", "item"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        }
      }
    },
    "/api/files/folder": {
      "post": {
        "operationId": "createFolder",
        "summary": "Create a folder",
        "tags": ["Files"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "The folder to create it in."
                  },
                  "destination": {
                    "type": "string",
                    "description": "Older name for `path`.",
                    "deprecated": true
                  },
                  "name": {
                    "type": "string"
                  }
                },
                "required": ["name"]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "item": {
                      "$ref": "#/components/schemas/Item"
                    }
                  },
                  "required": ["success", "item"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        }
      }
    },
    "/api/files/office-document": {
      "post": {
        "operationId": "createOfficeDocument",
        "summary": "Create a new document from a template",
        "tags": ["Files"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "The folder."
                  },
                  "format": {
                    "type": "string",
                    "enum": ["docx", "xlsx", "pptx", "pdf", "txt", "md", "csv"]
                  },
                  "name": {
                    "type": "string",
                    "description": "What to call it; a name is chosen when absent."
                  }
                },
                "required": ["format"]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "item": {
                      "$ref": "#/components/schemas/Item"
                    }
                  },
                  "required": ["success", "item"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/files/rename": {
      "post": {
        "operationId": "rename",
        "summary": "Rename a file or folder",
        "description": "Favourites, shares, recent destinations and folder preferences bound to the old path follow it.",
        "tags": ["Files"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "The folder it is in."
                  },
                  "name": {
                    "type": "string"
                  },
                  "newName": {
                    "type": "string"
                  }
                },
                "required": ["name", "newName"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "item": {
                      "$ref": "#/components/schemas/Item"
                    }
                  },
                  "required": ["success", "item"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        }
      }
    },
    "/api/files/copy": {
      "post": {
        "operationId": "copy",
        "summary": "Copy files and folders into a folder",
        "description": "A name already taken there becomes `name (1)`.",
        "tags": ["Files"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "path": {
                          "type": "string",
                          "description": "The folder it is in."
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": ["path", "name"]
                    }
                  },
                  "destination": {
                    "type": "string"
                  }
                },
                "required": ["items", "destination"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Progress as it goes, and what landed where.",
            "content": {
              "application/x-ndjson": {
                "schema": {
                  "description": "One line; the stream is a sequence of these.",
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "const": "start"
                        }
                      },
                      "required": ["type"],
                      "additionalProperties": true
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "const": "progress"
                        }
                      },
                      "required": ["type"],
                      "additionalProperties": true
                    },
                    {
                      "allOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "const": "done"
                            }
                          },
                          "required": ["type"]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "success": {
                              "type": "boolean"
                            },
                            "destination": {
                              "type": "string"
                            },
                            "items": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "from": {
                                    "type": "string"
                                  },
                                  "to": {
                                    "type": "string"
                                  }
                                }
                              }
                            }
                          },
                          "additionalProperties": true
                        }
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "const": "error"
                        },
                        "message": {
                          "type": "string"
                        },
                        "code": {
                          "type": "string"
                        }
                      },
                      "required": ["type", "message"],
                      "additionalProperties": true
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "507": {
            "$ref": "#/components/responses/E507"
          }
        }
      }
    },
    "/api/files/move": {
      "post": {
        "operationId": "move",
        "summary": "Move files and folders into a folder",
        "description": "What was bound to the old paths follows them.",
        "tags": ["Files"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "path": {
                          "type": "string",
                          "description": "The folder it is in."
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": ["path", "name"]
                    }
                  },
                  "destination": {
                    "type": "string"
                  }
                },
                "required": ["items", "destination"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Progress as it goes, and what landed where.",
            "content": {
              "application/x-ndjson": {
                "schema": {
                  "description": "One line; the stream is a sequence of these.",
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "const": "start"
                        }
                      },
                      "required": ["type"],
                      "additionalProperties": true
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "const": "progress"
                        }
                      },
                      "required": ["type"],
                      "additionalProperties": true
                    },
                    {
                      "allOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "const": "done"
                            }
                          },
                          "required": ["type"]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "success": {
                              "type": "boolean"
                            },
                            "destination": {
                              "type": "string"
                            },
                            "items": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "from": {
                                    "type": "string"
                                  },
                                  "to": {
                                    "type": "string"
                                  }
                                }
                              }
                            }
                          },
                          "additionalProperties": true
                        }
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "const": "error"
                        },
                        "message": {
                          "type": "string"
                        },
                        "code": {
                          "type": "string"
                        }
                      },
                      "required": ["type", "message"],
                      "additionalProperties": true
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "507": {
            "$ref": "#/components/responses/E507"
          }
        }
      }
    },
    "/api/files/recent-destinations": {
      "get": {
        "operationId": "listRecentDestinations",
        "summary": "Folders this account recently copied or moved into",
        "description": "Only those it can still reach.",
        "tags": ["Files"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": ["items"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          }
        }
      }
    },
    "/api/files/delete-impact": {
      "post": {
        "operationId": "describeDeletion",
        "summary": "What deleting a selection would affect, before doing it",
        "description": "The shares it would end, and for each item whether it goes to the trash or is removed.",
        "tags": ["Files"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "path": {
                          "type": "string",
                          "description": "The folder it is in."
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": ["path", "name"]
                    }
                  }
                },
                "required": ["items"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "shareCount": {
                      "type": "integer"
                    },
                    "shares": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      }
                    },
                    "trash": {
                      "type": "object",
                      "properties": {
                        "enabled": {
                          "type": "boolean"
                        },
                        "retentionDays": {
                          "type": "integer"
                        },
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "path": {
                                "type": "string"
                              },
                              "disposition": {
                                "type": "string",
                                "examples": ["trash", "delete"]
                              },
                              "reason": {
                                "type": ["string", "null"]
                              },
                              "shareCount": {
                                "type": "integer"
                              }
                            }
                          }
                        }
                      }
                    }
                  },
                  "required": ["shareCount"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      }
    },
    "/api/files": {
      "delete": {
        "operationId": "delete",
        "summary": "Delete files and folders",
        "description": "To the trash where it is on, unless `permanent`. What was bound to the paths — favourites, shares, preferences — is forgotten for everybody.",
        "tags": ["Files"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "path": {
                          "type": "string",
                          "description": "The folder it is in."
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": ["path", "name"]
                    }
                  },
                  "permanent": {
                    "type": "boolean"
                  }
                },
                "required": ["items"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "examples": ["trashed", "deleted", "failed"]
                          },
                          "trashItemId": {
                            "type": "string"
                          },
                          "error": {
                            "type": "string"
                          }
                        },
                        "required": ["path", "status"],
                        "additionalProperties": true
                      }
                    }
                  },
                  "required": ["success", "items"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/files/delete-stream": {
      "post": {
        "operationId": "deleteWithProgress",
        "summary": "Delete a selection, reporting as it goes",
        "description": "The same as `DELETE /api/files`, for selections large enough to want a progress bar.",
        "tags": ["Files"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "path": {
                          "type": "string",
                          "description": "The folder it is in."
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": ["path", "name"]
                    }
                  },
                  "permanent": {
                    "type": "boolean"
                  }
                },
                "required": ["items"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Progress, then the outcome per item.",
            "content": {
              "application/x-ndjson": {
                "schema": {
                  "description": "One line; the stream is a sequence of these.",
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "const": "start"
                        }
                      },
                      "required": ["type"],
                      "additionalProperties": true
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "const": "progress"
                        }
                      },
                      "required": ["type"],
                      "additionalProperties": true
                    },
                    {
                      "allOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "const": "done"
                            }
                          },
                          "required": ["type"]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "success": {
                              "type": "boolean"
                            },
                            "items": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "path": {
                                    "type": "string"
                                  },
                                  "status": {
                                    "type": "string",
                                    "examples": ["trashed", "deleted", "failed"]
                                  },
                                  "trashItemId": {
                                    "type": "string"
                                  },
                                  "error": {
                                    "type": "string"
                                  }
                                },
                                "required": ["path", "status"],
                                "additionalProperties": true
                              }
                            }
                          }
                        }
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "const": "error"
                        },
                        "message": {
                          "type": "string"
                        },
                        "code": {
                          "type": "string"
                        }
                      },
                      "required": ["type", "message"],
                      "additionalProperties": true
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          }
        }
      }
    },
    "/api/editor": {
      "get": {
        "operationId": "readText",
        "summary": "Read a text file",
        "description": "Carries an `ETag`; sent back in `If-None-Match` while the file is unchanged, the answer is `304` and the file is not read. Over 32 KB it is compressed when the request allows.",
        "tags": ["Editing"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "path",
            "in": "query",
            "required": true,
            "description": "The file.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-None-Match",
            "in": "header",
            "required": false,
            "description": "The ETag of the copy held.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "content": {
                      "type": "string"
                    }
                  },
                  "required": ["content"]
                }
              }
            }
          },
          "304": {
            "description": "Unchanged since the copy held."
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "415": {
            "$ref": "#/components/responses/E415"
          }
        }
      },
      "post": {
        "operationId": "readTextByPost",
        "summary": "Read a text file, the path in the body",
        "description": "The same answer as `GET`, kept for clients written against it.",
        "tags": ["Editing"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string"
                  }
                },
                "required": ["path"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "content": {
                      "type": "string"
                    }
                  },
                  "required": ["content"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "415": {
            "$ref": "#/components/responses/E415"
          }
        }
      },
      "put": {
        "operationId": "saveText",
        "summary": "Save a text file",
        "description": "In the encoding the file already had. The previous content is kept as a version where versions are on. Answers with the `ETag` the next read will carry.",
        "tags": ["Editing"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string"
                  },
                  "content": {
                    "type": "string"
                  }
                },
                "required": ["path", "content"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  },
                  "required": ["success"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        }
      }
    },
    "/api/raw": {
      "get": {
        "operationId": "readRawText",
        "summary": "A text file’s content alone",
        "tags": ["Editing"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "path",
            "in": "query",
            "required": true,
            "description": "The file.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-None-Match",
            "in": "header",
            "required": false,
            "description": "The ETag of the copy held.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The text.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "304": {
            "description": "Unchanged since the copy held."
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "415": {
            "$ref": "#/components/responses/E415"
          }
        }
      }
    },
    "/api/archive/list": {
      "get": {
        "operationId": "listArchive",
        "summary": "What is inside an archive, one folder at a time",
        "description": "Needs 7-Zip on the server. `outside` counts entries left out because their names point outside the archive.",
        "tags": ["Archives"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "path",
            "in": "query",
            "required": true,
            "description": "The archive.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "inside",
            "in": "query",
            "required": false,
            "description": "A folder inside it; the top when absent.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "path": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "inside": {
                      "type": "string"
                    },
                    "entries": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "path": {
                            "type": "string"
                          },
                          "isDirectory": {
                            "type": "boolean"
                          },
                          "size": {
                            "type": ["number", "null"]
                          },
                          "modified": {
                            "type": ["string", "null"]
                          },
                          "encrypted": {
                            "type": "boolean"
                          }
                        },
                        "required": ["name", "path", "isDirectory"]
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "outside": {
                      "type": "integer"
                    }
                  },
                  "required": ["path", "entries", "total", "outside"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          },
          "422": {
            "$ref": "#/components/responses/E422"
          },
          "503": {
            "$ref": "#/components/responses/E503"
          }
        }
      }
    },
    "/api/archive/entry": {
      "get": {
        "operationId": "readArchiveEntry",
        "summary": "One file out of an archive, without unpacking the rest",
        "description": "Always an attachment, always `nosniff`: nothing out of an archive is opened as a page here.",
        "tags": ["Archives"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "path",
            "in": "query",
            "required": true,
            "description": "The archive.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "entry",
            "in": "query",
            "required": true,
            "description": "The entry, by the name the listing gave.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The entry.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "422": {
            "$ref": "#/components/responses/E422"
          },
          "503": {
            "$ref": "#/components/responses/E503"
          }
        }
      }
    },
    "/api/archive/extract": {
      "post": {
        "operationId": "extractFromArchive",
        "summary": "Take part of an archive out onto the volume",
        "description": "Into the archive’s own folder, or `destination`. A folder stands for everything under it; nothing is replaced, so an entry may land under another name, which `done` gives.",
        "tags": ["Archives"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string"
                  },
                  "entries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "destination": {
                    "type": "string"
                  }
                },
                "required": ["path", "entries"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Progress, then where each entry landed.",
            "content": {
              "application/x-ndjson": {
                "schema": {
                  "description": "One line; the stream is a sequence of these.",
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "const": "start"
                        }
                      },
                      "required": ["type"],
                      "additionalProperties": true
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "const": "progress"
                        }
                      },
                      "required": ["type"],
                      "additionalProperties": true
                    },
                    {
                      "allOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "const": "done"
                            }
                          },
                          "required": ["type"]
                        },
                        {
                          "type": "object",
                          "properties": {},
                          "additionalProperties": true
                        }
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "const": "error"
                        },
                        "message": {
                          "type": "string"
                        },
                        "code": {
                          "type": "string"
                        }
                      },
                      "required": ["type", "message"],
                      "additionalProperties": true
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          },
          "422": {
            "$ref": "#/components/responses/E422"
          },
          "503": {
            "$ref": "#/components/responses/E503"
          }
        }
      }
    },
    "/api/files/zip/compress": {
      "post": {
        "operationId": "compress",
        "summary": "Make a zip of a selection",
        "tags": ["Archives"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "path": {
                          "type": "string",
                          "description": "The folder it is in."
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": ["path", "name"]
                    }
                  },
                  "destination": {
                    "type": "string",
                    "description": "The folder to put it in; the first item’s when absent."
                  },
                  "name": {
                    "type": "string",
                    "description": "Without `.zip`."
                  }
                },
                "required": ["items"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Progress, then the archive made.",
            "content": {
              "application/x-ndjson": {
                "schema": {
                  "description": "One line; the stream is a sequence of these.",
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "const": "start"
                        }
                      },
                      "required": ["type"],
                      "additionalProperties": true
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "const": "progress"
                        }
                      },
                      "required": ["type"],
                      "additionalProperties": true
                    },
                    {
                      "allOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "const": "done"
                            }
                          },
                          "required": ["type"]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "success": {
                              "type": "boolean"
                            },
                            "item": {
                              "$ref": "#/components/schemas/Item"
                            }
                          }
                        }
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "const": "error"
                        },
                        "message": {
                          "type": "string"
                        },
                        "code": {
                          "type": "string"
                        }
                      },
                      "required": ["type", "message"],
                      "additionalProperties": true
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/files/zip/extract": {
      "post": {
        "operationId": "extract",
        "summary": "Unpack a whole archive",
        "tags": ["Archives"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "The archive."
                  },
                  "destination": {
                    "type": "string",
                    "description": "`folder` for a new folder named after it, `current` beside it.",
                    "enum": ["folder", "current"],
                    "default": "folder"
                  },
                  "password": {
                    "type": "string",
                    "description": "For an archive behind one.",
                    "format": "password"
                  }
                },
                "required": ["path"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Progress, then what was made.",
            "content": {
              "application/x-ndjson": {
                "schema": {
                  "description": "One line; the stream is a sequence of these.",
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "const": "start"
                        }
                      },
                      "required": ["type"],
                      "additionalProperties": true
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "const": "progress"
                        }
                      },
                      "required": ["type"],
                      "additionalProperties": true
                    },
                    {
                      "allOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "const": "done"
                            }
                          },
                          "required": ["type"]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "success": {
                              "type": "boolean"
                            },
                            "item": {
                              "$ref": "#/components/schemas/Item"
                            },
                            "items": {
                              "type": "array",
                              "items": {
                                "$ref": "#/components/schemas/Item"
                              }
                            }
                          }
                        }
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "const": "error"
                        },
                        "message": {
                          "type": "string"
                        },
                        "code": {
                          "type": "string"
                        }
                      },
                      "required": ["type", "message"],
                      "additionalProperties": true
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/upload": {
      "post": {
        "operationId": "upload",
        "summary": "Send files in one request",
        "description": "For clients that do not speak TUS, or where chunked uploads are off. Each file under `name (1)` when its name is taken. `413` names the limit that refused it.",
        "tags": ["Uploads"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "uploadTo": {
                    "type": "string",
                    "description": "The folder."
                  },
                  "relativePath": {
                    "type": "string",
                    "description": "Where within it, for a folder sent file by file."
                  },
                  "filedata": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "binary"
                    }
                  }
                },
                "required": ["filedata"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string"
                      },
                      "path": {
                        "type": "string"
                      },
                      "dateModified": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "size": {
                        "type": "number"
                      },
                      "kind": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          },
          "507": {
            "$ref": "#/components/responses/E507"
          }
        }
      }
    },
    "/api/upload/folder-session": {
      "post": {
        "operationId": "startFolderUpload",
        "summary": "Reserve the name a folder upload will land under",
        "description": "Before any file of it is sent, so every file of one dropped folder goes to the same place even when the name was taken.",
        "tags": ["Uploads"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "uploadTo": {
                    "type": "string"
                  },
                  "sourceRoot": {
                    "type": "string",
                    "description": "The dropped folder’s name."
                  }
                },
                "required": ["sourceRoot"]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Reserved.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "targetRoot": {
                      "type": "string",
                      "description": "The name it will land under."
                    }
                  },
                  "required": ["targetRoot"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      }
    },
    "/api/upload/finalizations": {
      "get": {
        "operationId": "listUploadFinalizations",
        "summary": "Uploads received and not yet in place",
        "tags": ["Uploads"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      }
                    }
                  },
                  "required": ["items"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          }
        }
      }
    },
    "/api/upload/tus": {
      "post": {
        "operationId": "createUpload",
        "summary": "Start a resumable upload",
        "description": "[TUS](https://tus.io) creation. `Upload-Metadata` carries `filename`, `uploadTo` and `relativePath`, each base64. The upload’s URL is in `Location`. Needs `UPLOAD_CHUNKED_ENABLED`.",
        "tags": ["Uploads"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "Tus-Resumable",
            "in": "header",
            "required": true,
            "description": "`1.0.0`.",
            "schema": {
              "type": "string",
              "const": "1.0.0"
            }
          },
          {
            "name": "Upload-Length",
            "in": "header",
            "required": true,
            "description": "The whole size in bytes.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "Upload-Metadata",
            "in": "header",
            "required": true,
            "description": "Comma-separated `key base64value` pairs.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Created.",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "description": "The upload’s URL."
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        }
      },
      "options": {
        "operationId": "describeUploads",
        "summary": "What this TUS server supports",
        "tags": ["Uploads"],
        "security": [],
        "x-access": "public",
        "responses": {
          "200": {
            "description": "Its `Tus-*` headers."
          },
          "204": {
            "description": "Its `Tus-*` headers."
          }
        }
      }
    },
    "/api/upload/tus/{id}": {
      "head": {
        "operationId": "getUploadOffset",
        "summary": "How much of an upload has arrived",
        "description": "`Upload-Offset` says where to carry on from. Complete only once the file is in its folder; `423` with `Upload-Finalize-Error` while it cannot be placed.",
        "tags": ["Uploads"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Tus-Resumable",
            "in": "header",
            "required": true,
            "description": "`1.0.0`.",
            "schema": {
              "type": "string",
              "const": "1.0.0"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "`Upload-Offset` and `Upload-Length`."
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "423": {
            "$ref": "#/components/responses/E423"
          }
        }
      },
      "patch": {
        "operationId": "sendUploadBytes",
        "summary": "Send the next bytes of an upload",
        "tags": ["Uploads"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Tus-Resumable",
            "in": "header",
            "required": true,
            "description": "`1.0.0`.",
            "schema": {
              "type": "string",
              "const": "1.0.0"
            }
          },
          {
            "name": "Upload-Offset",
            "in": "header",
            "required": true,
            "description": "Where these bytes start.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/offset+octet-stream": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Received; `Upload-Offset` is the new position."
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "500": {
            "$ref": "#/components/responses/E500"
          },
          "507": {
            "$ref": "#/components/responses/E507"
          }
        }
      },
      "delete": {
        "operationId": "cancelUpload",
        "summary": "Abandon an upload",
        "tags": ["Uploads"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Tus-Resumable",
            "in": "header",
            "required": true,
            "description": "`1.0.0`.",
            "schema": {
              "type": "string",
              "const": "1.0.0"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Abandoned."
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/shares": {
      "get": {
        "operationId": "listShares",
        "summary": "The shares this account made",
        "tags": ["Sharing"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "shares": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Share"
                      }
                    }
                  },
                  "required": ["shares"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          }
        }
      },
      "post": {
        "operationId": "createShare",
        "summary": "Share a file or folder",
        "description": "Answers the share with `shareUrl`, built from `PUBLIC_URL` when it is set and from the request’s host otherwise.",
        "tags": ["Sharing"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "sourcePath": {
                    "type": "string",
                    "description": "What to share, as the account names it."
                  },
                  "accessMode": {
                    "type": "string",
                    "enum": ["readonly", "readwrite"],
                    "default": "readonly"
                  },
                  "allowDelete": {
                    "type": "boolean"
                  },
                  "allowCreateFolder": {
                    "type": "boolean"
                  },
                  "allowCreateFile": {
                    "type": "boolean"
                  },
                  "allowUpload": {
                    "type": "boolean"
                  },
                  "allowDownload": {
                    "type": "boolean"
                  },
                  "versionsVisible": {
                    "type": "boolean"
                  },
                  "versionsDownload": {
                    "type": "boolean"
                  },
                  "sharingType": {
                    "type": "string",
                    "description": "`anyone` for a public link, `users` for named accounts.",
                    "enum": ["anyone", "users"],
                    "default": "anyone"
                  },
                  "userIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "With `sharingType: users`."
                  },
                  "password": {
                    "type": ["string", "null"],
                    "description": "Asked of anybody opening it; null to take it off.",
                    "format": "password"
                  },
                  "expiresAt": {
                    "type": ["string", "null"],
                    "description": "When it stops working; null for never.",
                    "format": "date-time"
                  },
                  "label": {
                    "type": ["string", "null"]
                  }
                },
                "required": ["sourcePath"]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Shared.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Share"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/shares/shared-with-me": {
      "get": {
        "operationId": "listSharesWithMe",
        "summary": "What other accounts shared with this one",
        "tags": ["Sharing"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "shares": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Share"
                      }
                    }
                  },
                  "required": ["shares"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          }
        }
      }
    },
    "/api/shares/{id}": {
      "get": {
        "operationId": "getShare",
        "summary": "One share, with how it has been used",
        "tags": ["Sharing"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The share’s id — not its token.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Share"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "stats": {
                          "type": "object",
                          "properties": {
                            "accessCount": {
                              "type": "integer"
                            },
                            "downloadCount": {
                              "type": "integer"
                            },
                            "lastAccessedAt": {
                              "type": ["string", "null"],
                              "format": "date-time"
                            },
                            "lastAccessIp": {
                              "type": ["string", "null"]
                            },
                            "lastDownloadedAt": {
                              "type": ["string", "null"],
                              "format": "date-time"
                            },
                            "lastDownloadIp": {
                              "type": ["string", "null"]
                            },
                            "guestSessionCount": {
                              "type": "integer"
                            }
                          },
                          "additionalProperties": true
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      },
      "put": {
        "operationId": "updateShare",
        "summary": "Change a share",
        "description": "Only the fields sent change.",
        "tags": ["Sharing"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The share’s id — not its token.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "accessMode": {
                    "type": "string",
                    "enum": ["readonly", "readwrite"],
                    "default": "readonly"
                  },
                  "allowDelete": {
                    "type": "boolean"
                  },
                  "allowCreateFolder": {
                    "type": "boolean"
                  },
                  "allowCreateFile": {
                    "type": "boolean"
                  },
                  "allowUpload": {
                    "type": "boolean"
                  },
                  "allowDownload": {
                    "type": "boolean"
                  },
                  "versionsVisible": {
                    "type": "boolean"
                  },
                  "versionsDownload": {
                    "type": "boolean"
                  },
                  "sharingType": {
                    "type": "string",
                    "description": "`anyone` for a public link, `users` for named accounts.",
                    "enum": ["anyone", "users"],
                    "default": "anyone"
                  },
                  "userIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "With `sharingType: users`."
                  },
                  "password": {
                    "type": ["string", "null"],
                    "description": "Asked of anybody opening it; null to take it off.",
                    "format": "password"
                  },
                  "expiresAt": {
                    "type": ["string", "null"],
                    "description": "When it stops working; null for never.",
                    "format": "date-time"
                  },
                  "label": {
                    "type": ["string", "null"]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Share"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      },
      "delete": {
        "operationId": "deleteShare",
        "summary": "Stop sharing",
        "description": "The link stops working at once, and the guest sessions it opened end.",
        "tags": ["Sharing"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The share’s id — not its token.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Stopped."
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/share/{token}": {
      "get": {
        "operationId": "openSharedFile",
        "summary": "The file a link shares, directly",
        "description": "For a link to a single file. Behind a password, only with the guest session it earned.",
        "tags": ["Shared links"],
        "security": [{}],
        "x-access": "share",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "What the link carries.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Guest-Session",
            "in": "header",
            "required": false,
            "description": "The guest session the link earned.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The file, with its own content type.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/share/{token}/info": {
      "get": {
        "operationId": "describeLink",
        "summary": "What a link is, before opening it",
        "description": "Enough for the page that asks for a password, and nothing about where it points.",
        "tags": ["Shared links"],
        "security": [{}],
        "x-access": "share",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "What the link carries.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "shareToken": {
                      "type": "string"
                    },
                    "label": {
                      "type": ["string", "null"]
                    },
                    "isDirectory": {
                      "type": "boolean"
                    },
                    "hasPassword": {
                      "type": "boolean"
                    },
                    "requiresPassword": {
                      "type": "boolean",
                      "description": "This caller still has to give it."
                    },
                    "sharingType": {
                      "type": "string",
                      "enum": ["anyone", "users"]
                    },
                    "expiresAt": {
                      "type": ["string", "null"],
                      "format": "date-time"
                    },
                    "isExpired": {
                      "type": "boolean"
                    }
                  },
                  "required": ["shareToken", "isDirectory", "requiresPassword"]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/share/{token}/access": {
      "get": {
        "operationId": "openLink",
        "summary": "Open a link that asks for no password",
        "description": "Answers a guest session to send with what follows. A link behind a password answers `401` until `verify`.",
        "tags": ["Shared links"],
        "security": [{}],
        "x-access": "share",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "What the link carries.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "share": {
                      "type": "object",
                      "properties": {
                        "shareToken": {
                          "type": "string"
                        },
                        "label": {
                          "type": ["string", "null"]
                        },
                        "sourcePath": {
                          "type": "string",
                          "description": "`share/<token>`: where to browse from."
                        },
                        "accessMode": {
                          "type": "string",
                          "enum": ["readonly", "readwrite"]
                        },
                        "allowDownload": {
                          "type": "boolean"
                        },
                        "isDirectory": {
                          "type": "boolean"
                        }
                      }
                    },
                    "guestSessionId": {
                      "type": "string"
                    }
                  },
                  "required": ["share"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/share/{token}/verify": {
      "post": {
        "operationId": "unlockLink",
        "summary": "Give a link’s password",
        "description": "Rate limited. Answers the guest session the password earned.",
        "tags": ["Shared links"],
        "security": [{}],
        "x-access": "share",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "What the link carries.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "password": {
                    "type": "string",
                    "format": "password"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "guestSessionId": {
                      "type": "string"
                    }
                  },
                  "required": ["success", "guestSessionId"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          }
        }
      }
    },
    "/api/share/{token}/browse/{path}": {
      "get": {
        "operationId": "browseLink",
        "summary": "What a shared folder holds",
        "tags": ["Shared links"],
        "security": [
          {
            "guestSession": []
          },
          {
            "session": []
          }
        ],
        "x-access": "shareVisitor",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "What the link carries.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "path",
            "in": "path",
            "required": true,
            "description": "Inside the shared folder; empty for its top.",
            "schema": {
              "type": "string"
            },
            "allowReserved": true
          },
          {
            "name": "X-Guest-Session",
            "in": "header",
            "required": false,
            "description": "The guest session the link earned.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Item"
                      }
                    },
                    "access": {
                      "$ref": "#/components/schemas/Access"
                    },
                    "current": {
                      "type": "object",
                      "properties": {
                        "isDirectory": {
                          "type": "boolean"
                        }
                      }
                    },
                    "path": {
                      "type": "string",
                      "description": "`share/<token>/…`"
                    },
                    "shareInfo": {
                      "type": "object",
                      "properties": {
                        "label": {
                          "type": ["string", "null"]
                        },
                        "sourceFolderName": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "required": ["items", "access", "path"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/share/{token}/file": {
      "get": {
        "operationId": "downloadSharedFile",
        "summary": "The file a link shares",
        "tags": ["Shared links"],
        "security": [{}],
        "x-access": "share",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "What the link carries.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Guest-Session",
            "in": "header",
            "required": false,
            "description": "The guest session the link earned.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "required": false,
            "description": "Part of it.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The file.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "206": {
            "description": "The part asked for.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/share/{token}/file/{path}": {
      "get": {
        "operationId": "downloadFileInLink",
        "summary": "A file inside a shared folder",
        "tags": ["Shared links"],
        "security": [{}],
        "x-access": "share",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "What the link carries.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "path",
            "in": "path",
            "required": true,
            "description": "The file, inside the shared folder.",
            "schema": {
              "type": "string"
            },
            "allowReserved": true
          },
          {
            "name": "X-Guest-Session",
            "in": "header",
            "required": false,
            "description": "The guest session the link earned.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "required": false,
            "description": "Part of it.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The file.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "206": {
            "description": "The part asked for.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/share/{token}/editor": {
      "get": {
        "operationId": "readSharedText",
        "summary": "The text of a file a link shares",
        "description": "Its `ETag` also changes when what the link allows does.",
        "tags": ["Shared links"],
        "security": [{}],
        "x-access": "share",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "What the link carries.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Guest-Session",
            "in": "header",
            "required": false,
            "description": "The guest session the link earned.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-None-Match",
            "in": "header",
            "required": false,
            "description": "The ETag of the copy held.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "path": {
                      "type": "string"
                    },
                    "content": {
                      "type": "string"
                    },
                    "canDownload": {
                      "type": "boolean"
                    },
                    "canWrite": {
                      "type": "boolean"
                    }
                  },
                  "required": ["name", "content", "canWrite"]
                }
              }
            }
          },
          "304": {
            "description": "Unchanged."
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "415": {
            "$ref": "#/components/responses/E415"
          }
        }
      },
      "put": {
        "operationId": "saveSharedText",
        "summary": "Save the text of a file a link shares",
        "description": "Only through a writable link.",
        "tags": ["Shared links"],
        "security": [{}],
        "x-access": "share",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "What the link carries.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Guest-Session",
            "in": "header",
            "required": false,
            "description": "The guest session the link earned.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "content": {
                    "type": "string"
                  }
                },
                "required": ["content"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  },
                  "required": ["success"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        }
      }
    },
    "/api/share/{token}/editor/{path}": {
      "get": {
        "operationId": "readTextInLink",
        "summary": "The text of a file inside a shared folder",
        "tags": ["Shared links"],
        "security": [{}],
        "x-access": "share",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "What the link carries.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "path",
            "in": "path",
            "required": true,
            "description": "The file, inside the shared folder.",
            "schema": {
              "type": "string"
            },
            "allowReserved": true
          },
          {
            "name": "X-Guest-Session",
            "in": "header",
            "required": false,
            "description": "The guest session the link earned.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "path": {
                      "type": "string"
                    },
                    "content": {
                      "type": "string"
                    },
                    "canDownload": {
                      "type": "boolean"
                    },
                    "canWrite": {
                      "type": "boolean"
                    }
                  },
                  "required": ["name", "content", "canWrite"]
                }
              }
            }
          },
          "304": {
            "description": "Unchanged."
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "415": {
            "$ref": "#/components/responses/E415"
          }
        }
      },
      "put": {
        "operationId": "saveTextInLink",
        "summary": "Save a text file inside a shared folder",
        "tags": ["Shared links"],
        "security": [{}],
        "x-access": "share",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "What the link carries.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "path",
            "in": "path",
            "required": true,
            "description": "The file, inside the shared folder.",
            "schema": {
              "type": "string"
            },
            "allowReserved": true
          },
          {
            "name": "X-Guest-Session",
            "in": "header",
            "required": false,
            "description": "The guest session the link earned.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "content": {
                    "type": "string"
                  }
                },
                "required": ["content"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  },
                  "required": ["success"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        }
      }
    },
    "/api/trash": {
      "get": {
        "operationId": "listTrash",
        "summary": "What this account deleted, and can still bring back",
        "tags": ["Trash"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "enabled": {
                      "type": "boolean"
                    },
                    "retentionDays": {
                      "type": "integer"
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TrashItem"
                      }
                    }
                  },
                  "required": ["enabled", "items"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          }
        }
      }
    },
    "/api/trash/restore": {
      "post": {
        "operationId": "restoreFromTrash",
        "summary": "Put deleted items back where they were",
        "description": "Under `name (1)` when the name has been taken since.",
        "tags": ["Trash"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "shares": {
                    "type": "boolean",
                    "description": "Bring back the shares that ended with the deletion."
                  }
                },
                "required": ["ids"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "entry": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "examples": ["restored", "missing", "conflict", "failed"]
                          },
                          "name": {
                            "type": "string"
                          },
                          "restoredName": {
                            "type": "string",
                            "description": "The name it came back under, when the old one was taken."
                          },
                          "renamed": {
                            "type": "boolean"
                          },
                          "path": {
                            "type": "string",
                            "description": "The folder it came back into."
                          },
                          "reason": {
                            "type": ["string", "null"]
                          }
                        },
                        "required": ["status"],
                        "additionalProperties": true
                      }
                    }
                  },
                  "required": ["items"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      }
    },
    "/api/trash/restore-to": {
      "post": {
        "operationId": "restoreFromTrashTo",
        "summary": "Bring deleted items back somewhere else",
        "tags": ["Trash"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "destination": {
                    "type": "string"
                  },
                  "shares": {
                    "type": "boolean",
                    "description": "Bring back the shares that ended with the deletion."
                  }
                },
                "required": ["ids", "destination"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Progress as the copy goes, then what came back where. One JSON object per line.",
            "content": {
              "application/x-ndjson": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string",
                      "enum": ["start", "progress", "done", "error"]
                    }
                  },
                  "required": ["type"],
                  "additionalProperties": true,
                  "description": "One line; the stream is a sequence of these."
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/trash/items/{id}/entries": {
      "get": {
        "operationId": "listTrashedFolder",
        "summary": "What a deleted folder held",
        "tags": ["Trash"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The trashed item.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "path",
            "in": "query",
            "required": false,
            "description": "A folder inside it; its top when absent.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "item": {
                      "$ref": "#/components/schemas/TrashItem"
                    },
                    "path": {
                      "type": "string"
                    },
                    "entries": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "kind": {
                            "type": "string"
                          },
                          "size": {
                            "type": ["number", "null"]
                          },
                          "modifiedAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "shareCount": {
                            "type": "integer"
                          }
                        },
                        "required": ["name", "kind"]
                      }
                    }
                  },
                  "required": ["item", "entries"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/trash/items/{id}/text": {
      "get": {
        "operationId": "readTrashedText",
        "summary": "The text of a deleted file, or of a file inside a deleted folder",
        "tags": ["Trash"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The trashed item.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "path",
            "in": "query",
            "required": false,
            "description": "Inside a deleted folder.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "size": {
                      "type": "number"
                    },
                    "modifiedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "content": {
                      "type": "string"
                    }
                  },
                  "required": ["content"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          },
          "415": {
            "$ref": "#/components/responses/E415"
          }
        }
      }
    },
    "/api/trash/items/{id}/restore": {
      "post": {
        "operationId": "restoreFromTrashedFolder",
        "summary": "Bring back part of a deleted folder",
        "tags": ["Trash"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The trashed item.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "paths": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "description": "Inside the folder."
                    }
                  },
                  "shares": {
                    "type": "boolean",
                    "description": "Bring back the shares that ended with the deletion."
                  }
                },
                "required": ["paths"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "entry": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "examples": ["restored", "missing", "conflict", "failed"]
                          },
                          "name": {
                            "type": "string"
                          },
                          "restoredName": {
                            "type": "string",
                            "description": "The name it came back under, when the old one was taken."
                          },
                          "renamed": {
                            "type": "boolean"
                          },
                          "path": {
                            "type": "string",
                            "description": "The folder it came back into."
                          },
                          "reason": {
                            "type": ["string", "null"]
                          }
                        },
                        "required": ["status"],
                        "additionalProperties": true
                      }
                    }
                  },
                  "required": ["items"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/trash/items/{id}/restore-to": {
      "post": {
        "operationId": "restoreFromTrashedFolderTo",
        "summary": "Bring back part of a deleted folder, somewhere else",
        "tags": ["Trash"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The trashed item.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "paths": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "destination": {
                    "type": "string"
                  },
                  "shares": {
                    "type": "boolean",
                    "description": "Bring back the shares that ended with the deletion."
                  }
                },
                "required": ["paths", "destination"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Progress as the copy goes, then what came back where. One JSON object per line.",
            "content": {
              "application/x-ndjson": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string",
                      "enum": ["start", "progress", "done", "error"]
                    }
                  },
                  "required": ["type"],
                  "additionalProperties": true,
                  "description": "One line; the stream is a sequence of these."
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/trash/delete": {
      "post": {
        "operationId": "purgeFromTrash",
        "summary": "Remove items from the trash for good",
        "tags": ["Trash"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "forgetUnavailable": {
                    "type": "boolean",
                    "description": "Also forget items whose storage is not there any more."
                  }
                },
                "required": ["ids"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "reason": {
                            "type": ["string", "null"]
                          }
                        },
                        "required": ["status"],
                        "additionalProperties": true
                      }
                    }
                  },
                  "required": ["items"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      }
    },
    "/api/trash/empty": {
      "post": {
        "operationId": "emptyTrash",
        "summary": "Empty this account’s trash",
        "tags": ["Trash"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "purged": {
                      "type": "integer"
                    },
                    "unavailable": {
                      "type": "integer"
                    },
                    "failed": {
                      "type": "integer"
                    }
                  },
                  "required": ["purged"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          }
        }
      }
    },
    "/api/trash/zones": {
      "get": {
        "operationId": "listTrashZones",
        "summary": "Every place the trash keeps things, and what it holds",
        "tags": ["Trash"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "zones": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TrashZone"
                      }
                    }
                  },
                  "required": ["zones"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      }
    },
    "/api/trash/verify": {
      "post": {
        "operationId": "verifyTrash",
        "summary": "Check that what the trash records matches what is on disk",
        "tags": ["Trash"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "zones": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "zoneId": {
                            "type": "string"
                          }
                        },
                        "required": ["zoneId"],
                        "additionalProperties": true
                      }
                    }
                  },
                  "required": ["zones"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      }
    },
    "/api/trash/maintenance": {
      "post": {
        "operationId": "runTrashMaintenance",
        "summary": "Run the trash’s upkeep now",
        "description": "What the daily pass does: expire, keep within budget, finish or undo what a crash interrupted.",
        "tags": ["Trash"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "zones": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "zoneId": {
                            "type": "string"
                          }
                        },
                        "required": ["zoneId"],
                        "additionalProperties": true
                      }
                    }
                  },
                  "required": ["zones"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      }
    },
    "/api/versions": {
      "get": {
        "operationId": "listVersions",
        "summary": "The earlier versions of a file",
        "tags": ["Versions"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "path",
            "in": "query",
            "required": true,
            "description": "The file.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "enabled": {
                      "type": "boolean"
                    },
                    "file": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string"
                        },
                        "path": {
                          "type": "string"
                        },
                        "size": {
                          "type": "number"
                        },
                        "modifiedAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "author": {
                          "type": ["object", "null"],
                          "properties": {
                            "id": {
                              "type": ["string", "null"]
                            },
                            "label": {
                              "type": "string"
                            }
                          }
                        },
                        "source": {
                          "type": ["string", "null"]
                        }
                      }
                    },
                    "versions": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Version"
                      }
                    },
                    "totalBytes": {
                      "type": "number"
                    },
                    "rights": {
                      "type": "object",
                      "properties": {
                        "see": {
                          "type": "boolean"
                        },
                        "download": {
                          "type": "boolean"
                        },
                        "restore": {
                          "type": "boolean"
                        },
                        "remove": {
                          "type": "boolean"
                        }
                      }
                    }
                  },
                  "required": ["enabled", "versions"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/versions/{id}/content": {
      "get": {
        "operationId": "downloadVersion",
        "summary": "An earlier version’s content",
        "tags": ["Versions"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The version.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "path",
            "in": "query",
            "required": true,
            "description": "The file.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The content.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/versions/{id}/text": {
      "get": {
        "operationId": "readVersionText",
        "summary": "An earlier version’s text",
        "tags": ["Versions"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The version.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "path",
            "in": "query",
            "required": true,
            "description": "The file.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "size": {
                      "type": "number"
                    },
                    "modifiedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "content": {
                      "type": "string"
                    }
                  },
                  "required": ["content"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          },
          "415": {
            "$ref": "#/components/responses/E415"
          }
        }
      }
    },
    "/api/versions/{id}/restore": {
      "post": {
        "operationId": "restoreVersion",
        "summary": "Make an earlier version the current one",
        "description": "What it replaces is kept as a version in its turn.",
        "tags": ["Versions"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The version.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "The file whose versions these are."
                  }
                },
                "required": ["path"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "path": {
                      "type": "string"
                    }
                  },
                  "required": ["status", "path"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        }
      }
    },
    "/api/versions/{id}/copy": {
      "post": {
        "operationId": "copyVersion",
        "summary": "Save an earlier version as a new file",
        "tags": ["Versions"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The version.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "The file whose versions these are."
                  },
                  "destination": {
                    "type": "string",
                    "description": "The folder."
                  },
                  "name": {
                    "type": "string"
                  }
                },
                "required": ["path", "destination"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "path": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    }
                  },
                  "required": ["path", "name"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/versions/{id}/replace": {
      "post": {
        "operationId": "replaceWithVersion",
        "summary": "Write an earlier version over another file",
        "description": "What is replaced is kept as a version of that file.",
        "tags": ["Versions"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The version.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "The file whose versions these are."
                  },
                  "target": {
                    "type": "string",
                    "description": "The file to replace."
                  }
                },
                "required": ["path", "target"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "path": {
                      "type": "string"
                    }
                  },
                  "required": ["status", "path"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/versions/{id}": {
      "patch": {
        "operationId": "updateVersion",
        "summary": "Name or pin a version",
        "tags": ["Versions"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The version.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "The file whose versions these are."
                  },
                  "label": {
                    "type": ["string", "null"]
                  },
                  "pinned": {
                    "type": "boolean"
                  }
                },
                "required": ["path"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Version"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/versions/delete": {
      "post": {
        "operationId": "deleteVersions",
        "summary": "Remove versions of a file",
        "tags": ["Versions"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "The file whose versions these are."
                  },
                  "ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "all": {
                    "type": "boolean"
                  }
                },
                "required": ["path"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "deleted": {
                      "type": "integer"
                    }
                  },
                  "required": ["items", "deleted"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/versions/admin/files": {
      "get": {
        "operationId": "listVersionedFiles",
        "summary": "Every file with versions kept, across the instance",
        "tags": ["Versions"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "parameters": [
          {
            "name": "zone",
            "in": "query",
            "required": false,
            "description": "One zone.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "description": "Whether the file is still there.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Part of a name or path.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Default `bytes`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "How many.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "From where.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "files": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "relativePath": {
                            "type": "string"
                          },
                          "folder": {
                            "type": "string"
                          },
                          "path": {
                            "type": ["string", "null"]
                          },
                          "state": {
                            "type": "string"
                          },
                          "versions": {
                            "type": "integer"
                          },
                          "bytes": {
                            "type": "number"
                          },
                          "newest": {
                            "type": ["string", "null"],
                            "format": "date-time"
                          },
                          "zone": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "kind": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              }
                            }
                          }
                        },
                        "required": ["id", "name"]
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "totalBytes": {
                      "type": "number"
                    },
                    "totalVersions": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    },
                    "zones": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "kind": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "states": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "sorts": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": ["files", "total"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      }
    },
    "/api/versions/admin/files/{id}": {
      "get": {
        "operationId": "getVersionedFile",
        "summary": "One file’s kept versions, for an administrator",
        "tags": ["Versions"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The file’s record.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "file": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "relativePath": {
                          "type": "string"
                        },
                        "path": {
                          "type": ["string", "null"]
                        },
                        "state": {
                          "type": "string"
                        },
                        "zone": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "kind": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    },
                    "versions": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Version"
                      }
                    },
                    "totalBytes": {
                      "type": "number"
                    }
                  },
                  "required": ["file", "versions"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/versions/admin/files/{id}/delete": {
      "post": {
        "operationId": "deleteVersionsOfFile",
        "summary": "Remove kept versions of a file, for an administrator",
        "tags": ["Versions"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The file’s record.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "all": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "deleted": {
                      "type": "integer"
                    },
                    "remaining": {
                      "type": "integer"
                    }
                  },
                  "required": ["items", "deleted"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/favorites": {
      "get": {
        "operationId": "listFavorites",
        "summary": "This account’s favourites, in order",
        "tags": ["Favourites"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Favorite"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          }
        }
      },
      "post": {
        "operationId": "addFavorite",
        "summary": "Add a favourite",
        "description": "Adding a path already there updates it.",
        "tags": ["Favourites"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string"
                  },
                  "label": {
                    "type": "string"
                  },
                  "icon": {
                    "type": "string"
                  },
                  "color": {
                    "type": ["string", "null"]
                  }
                },
                "required": ["path"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Favorite"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      },
      "delete": {
        "operationId": "removeFavorite",
        "summary": "Remove a favourite",
        "description": "Answers what is left.",
        "tags": ["Favourites"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string"
                  }
                },
                "required": ["path"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Favorite"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          }
        }
      }
    },
    "/api/favorites/reorder": {
      "patch": {
        "operationId": "reorderFavorites",
        "summary": "Put the favourites in a new order",
        "tags": ["Favourites"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "order": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "description": "A favourite’s id."
                    }
                  }
                },
                "required": ["order"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Favorite"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          }
        }
      }
    },
    "/api/favorites/{id}": {
      "patch": {
        "operationId": "updateFavorite",
        "summary": "Change a favourite",
        "tags": ["Favourites"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The favourite.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "label": {
                    "type": "string"
                  },
                  "icon": {
                    "type": "string"
                  },
                  "color": {
                    "type": ["string", "null"]
                  },
                  "position": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Favorite"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/settings": {
      "get": {
        "operationId": "getSettings",
        "summary": "The settings this account may see",
        "tags": ["Settings"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "branding": {
                      "type": "object",
                      "properties": {
                        "appName": {
                          "type": "string"
                        },
                        "appLogoUrl": {
                          "type": "string"
                        },
                        "showPoweredBy": {
                          "type": "boolean"
                        }
                      },
                      "additionalProperties": true
                    },
                    "user": {
                      "type": "object",
                      "properties": {},
                      "additionalProperties": true,
                      "description": "This account’s own preferences: sorting and view per folder, hidden files."
                    },
                    "uploads": {
                      "type": "object",
                      "properties": {},
                      "additionalProperties": true,
                      "description": "Chunked uploads."
                    },
                    "thumbnails": {
                      "type": "object",
                      "properties": {},
                      "additionalProperties": true,
                      "description": "Whether, how large, how good, how many at once."
                    },
                    "access": {
                      "type": "object",
                      "properties": {
                        "rules": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "path": {
                                "type": "string"
                              },
                              "recursive": {
                                "type": "boolean"
                              },
                              "permissions": {
                                "type": "string",
                                "enum": ["rw", "ro", "hidden"]
                              },
                              "appliesToAdmins": {
                                "type": "boolean",
                                "description": "Whether this rule holds administrators too. Left unsaid, a rule stored before this existed keeps what it did: a hidden one held them, a read-only one did not."
                              }
                            },
                            "additionalProperties": true
                          }
                        },
                        "applyToAdmins": {
                          "type": "boolean",
                          "description": "Hold administrators to every rule, whatever each rule says."
                        }
                      }
                    },
                    "folderSize": {
                      "type": "object",
                      "properties": {},
                      "additionalProperties": true,
                      "description": "Mode and excluded folders — those from the environment cannot be changed here."
                    },
                    "searchIndex": {
                      "type": "object",
                      "properties": {},
                      "additionalProperties": true,
                      "description": "Whether the index is on, and excluded folders."
                    },
                    "trash": {
                      "type": "object",
                      "properties": {},
                      "additionalProperties": true,
                      "description": "Retention and budget."
                    },
                    "versions": {
                      "type": "object",
                      "properties": {},
                      "additionalProperties": true,
                      "description": "How versions are thinned and kept."
                    },
                    "activity": {
                      "type": "object",
                      "properties": {
                        "enabled": {
                          "type": "boolean"
                        },
                        "retentionDays": {
                          "type": "integer"
                        }
                      }
                    }
                  },
                  "description": "Every section is answered to an administrator; to anybody else, only `branding` and `user`. A section sent replaces what it names and leaves the rest."
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          }
        }
      },
      "patch": {
        "operationId": "updateSettings",
        "summary": "Change settings",
        "description": "An account’s own `user` preferences, by anybody; every other section, by an administrator — `403` otherwise, and nothing is changed.",
        "tags": ["Settings"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "branding": {
                    "type": "object",
                    "properties": {
                      "appName": {
                        "type": "string"
                      },
                      "appLogoUrl": {
                        "type": "string"
                      },
                      "showPoweredBy": {
                        "type": "boolean"
                      }
                    },
                    "additionalProperties": true
                  },
                  "user": {
                    "type": "object",
                    "properties": {},
                    "additionalProperties": true,
                    "description": "This account’s own preferences: sorting and view per folder, hidden files."
                  },
                  "uploads": {
                    "type": "object",
                    "properties": {},
                    "additionalProperties": true,
                    "description": "Chunked uploads."
                  },
                  "thumbnails": {
                    "type": "object",
                    "properties": {},
                    "additionalProperties": true,
                    "description": "Whether, how large, how good, how many at once."
                  },
                  "access": {
                    "type": "object",
                    "properties": {
                      "rules": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "path": {
                              "type": "string"
                            },
                            "recursive": {
                              "type": "boolean"
                            },
                            "permissions": {
                              "type": "string",
                              "enum": ["rw", "ro", "hidden"]
                            },
                            "appliesToAdmins": {
                              "type": "boolean",
                              "description": "Whether this rule holds administrators too. Left unsaid, a rule stored before this existed keeps what it did: a hidden one held them, a read-only one did not."
                            }
                          },
                          "additionalProperties": true
                        }
                      },
                      "applyToAdmins": {
                        "type": "boolean",
                        "description": "Hold administrators to every rule, whatever each rule says."
                      }
                    }
                  },
                  "folderSize": {
                    "type": "object",
                    "properties": {},
                    "additionalProperties": true,
                    "description": "Mode and excluded folders — those from the environment cannot be changed here."
                  },
                  "searchIndex": {
                    "type": "object",
                    "properties": {},
                    "additionalProperties": true,
                    "description": "Whether the index is on, and excluded folders."
                  },
                  "trash": {
                    "type": "object",
                    "properties": {},
                    "additionalProperties": true,
                    "description": "Retention and budget."
                  },
                  "versions": {
                    "type": "object",
                    "properties": {},
                    "additionalProperties": true,
                    "description": "How versions are thinned and kept."
                  },
                  "activity": {
                    "type": "object",
                    "properties": {
                      "enabled": {
                        "type": "boolean"
                      },
                      "retentionDays": {
                        "type": "integer"
                      }
                    }
                  }
                },
                "description": "Every section is answered to an administrator; to anybody else, only `branding` and `user`. A section sent replaces what it names and leaves the rest."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "branding": {
                      "type": "object",
                      "properties": {
                        "appName": {
                          "type": "string"
                        },
                        "appLogoUrl": {
                          "type": "string"
                        },
                        "showPoweredBy": {
                          "type": "boolean"
                        }
                      },
                      "additionalProperties": true
                    },
                    "user": {
                      "type": "object",
                      "properties": {},
                      "additionalProperties": true,
                      "description": "This account’s own preferences: sorting and view per folder, hidden files."
                    },
                    "uploads": {
                      "type": "object",
                      "properties": {},
                      "additionalProperties": true,
                      "description": "Chunked uploads."
                    },
                    "thumbnails": {
                      "type": "object",
                      "properties": {},
                      "additionalProperties": true,
                      "description": "Whether, how large, how good, how many at once."
                    },
                    "access": {
                      "type": "object",
                      "properties": {
                        "rules": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "path": {
                                "type": "string"
                              },
                              "recursive": {
                                "type": "boolean"
                              },
                              "permissions": {
                                "type": "string",
                                "enum": ["rw", "ro", "hidden"]
                              },
                              "appliesToAdmins": {
                                "type": "boolean",
                                "description": "Whether this rule holds administrators too. Left unsaid, a rule stored before this existed keeps what it did: a hidden one held them, a read-only one did not."
                              }
                            },
                            "additionalProperties": true
                          }
                        },
                        "applyToAdmins": {
                          "type": "boolean",
                          "description": "Hold administrators to every rule, whatever each rule says."
                        }
                      }
                    },
                    "folderSize": {
                      "type": "object",
                      "properties": {},
                      "additionalProperties": true,
                      "description": "Mode and excluded folders — those from the environment cannot be changed here."
                    },
                    "searchIndex": {
                      "type": "object",
                      "properties": {},
                      "additionalProperties": true,
                      "description": "Whether the index is on, and excluded folders."
                    },
                    "trash": {
                      "type": "object",
                      "properties": {},
                      "additionalProperties": true,
                      "description": "Retention and budget."
                    },
                    "versions": {
                      "type": "object",
                      "properties": {},
                      "additionalProperties": true,
                      "description": "How versions are thinned and kept."
                    },
                    "activity": {
                      "type": "object",
                      "properties": {
                        "enabled": {
                          "type": "boolean"
                        },
                        "retentionDays": {
                          "type": "integer"
                        }
                      }
                    }
                  },
                  "description": "Every section is answered to an administrator; to anybody else, only `branding` and `user`. A section sent replaces what it names and leaves the rest."
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      }
    },
    "/api/settings/upload-logo": {
      "post": {
        "operationId": "uploadLogo",
        "summary": "Replace the logo",
        "tags": ["Settings"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "logo": {
                    "type": "string",
                    "description": "PNG, JPEG, SVG or WebP.",
                    "format": "binary"
                  },
                  "branding": {
                    "type": "string",
                    "description": "JSON: the rest of the branding, saved with it."
                  }
                },
                "required": ["logo"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "type": "object",
                      "properties": {
                        "branding": {
                          "type": "object",
                          "properties": {
                            "appName": {
                              "type": "string"
                            },
                            "appLogoUrl": {
                              "type": "string"
                            },
                            "showPoweredBy": {
                              "type": "boolean"
                            }
                          },
                          "additionalProperties": true
                        },
                        "user": {
                          "type": "object",
                          "properties": {},
                          "additionalProperties": true,
                          "description": "This account’s own preferences: sorting and view per folder, hidden files."
                        },
                        "uploads": {
                          "type": "object",
                          "properties": {},
                          "additionalProperties": true,
                          "description": "Chunked uploads."
                        },
                        "thumbnails": {
                          "type": "object",
                          "properties": {},
                          "additionalProperties": true,
                          "description": "Whether, how large, how good, how many at once."
                        },
                        "access": {
                          "type": "object",
                          "properties": {
                            "rules": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "path": {
                                    "type": "string"
                                  },
                                  "recursive": {
                                    "type": "boolean"
                                  },
                                  "permissions": {
                                    "type": "string",
                                    "enum": ["rw", "ro", "hidden"]
                                  },
                                  "appliesToAdmins": {
                                    "type": "boolean",
                                    "description": "Whether this rule holds administrators too. Left unsaid, a rule stored before this existed keeps what it did: a hidden one held them, a read-only one did not."
                                  }
                                },
                                "additionalProperties": true
                              }
                            },
                            "applyToAdmins": {
                              "type": "boolean",
                              "description": "Hold administrators to every rule, whatever each rule says."
                            }
                          }
                        },
                        "folderSize": {
                          "type": "object",
                          "properties": {},
                          "additionalProperties": true,
                          "description": "Mode and excluded folders — those from the environment cannot be changed here."
                        },
                        "searchIndex": {
                          "type": "object",
                          "properties": {},
                          "additionalProperties": true,
                          "description": "Whether the index is on, and excluded folders."
                        },
                        "trash": {
                          "type": "object",
                          "properties": {},
                          "additionalProperties": true,
                          "description": "Retention and budget."
                        },
                        "versions": {
                          "type": "object",
                          "properties": {},
                          "additionalProperties": true,
                          "description": "How versions are thinned and kept."
                        },
                        "activity": {
                          "type": "object",
                          "properties": {
                            "enabled": {
                              "type": "boolean"
                            },
                            "retentionDays": {
                              "type": "integer"
                            }
                          }
                        }
                      },
                      "description": "Every section is answered to an administrator; to anybody else, only `branding` and `user`. A section sent replaces what it names and leaves the rest."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "logoUrl": {
                          "type": "string"
                        }
                      },
                      "required": ["logoUrl"]
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        }
      }
    },
    "/api/settings/access/check-paths": {
      "post": {
        "operationId": "checkAccessRulePaths",
        "summary": "What the paths of access rules name on the disk",
        "description": "For the rule editor, which warns about a path that names nothing. A rule is matched against the path NextExplorer shows, volume first; one typed from the host’s side of a mount (`mnt/torrents`) names nothing, and the folder probably meant comes back as `suggestion`. Nothing is stored or refused.",
        "tags": ["Settings"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "paths": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "At most 200, answered in the same order."
                  }
                },
                "required": ["paths"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "paths": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "As it was sent."
                          },
                          "status": {
                            "type": "string",
                            "description": "`folder` or `file` when it names one, `missing` when it names nothing, `invalid` when it lies outside the volumes, `empty` for no path.",
                            "enum": ["folder", "file", "missing", "invalid", "empty"]
                          },
                          "suggestion": {
                            "type": ["string", "null"],
                            "description": "The folder probably meant, for a `missing` path."
                          }
                        },
                        "required": ["path", "status", "suggestion"]
                      }
                    }
                  },
                  "required": ["paths"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      }
    },
    "/api/branding": {
      "get": {
        "operationId": "getBranding",
        "summary": "Name and logo, for the sign-in page",
        "tags": ["Settings"],
        "security": [],
        "x-access": "public",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "appName": {
                      "type": "string"
                    },
                    "appLogoUrl": {
                      "type": "string"
                    },
                    "showPoweredBy": {
                      "type": "boolean"
                    }
                  },
                  "required": ["appName"]
                }
              }
            }
          }
        }
      }
    },
    "/api/features": {
      "get": {
        "operationId": "getFeatures",
        "summary": "What this installation offers",
        "description": "Which integrations, limits and optional features are on, and which release this is. Answered to anybody: the interface needs it before signing in.",
        "tags": ["Settings"],
        "security": [],
        "x-access": "public",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "public": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "type": ["string", "null"]
                        },
                        "origin": {
                          "type": ["string", "null"]
                        },
                        "origins": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "version": {
                      "type": "object",
                      "properties": {
                        "app": {
                          "type": "string"
                        },
                        "gitCommit": {
                          "type": "string"
                        },
                        "gitBranch": {
                          "type": "string"
                        },
                        "repoUrl": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "required": ["version"],
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/api/capabilities": {
      "get": {
        "operationId": "getCapabilities",
        "summary": "Which optional tools are installed, and what each makes possible",
        "tags": ["Administration"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "capabilities": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "available": {
                            "type": "boolean"
                          },
                          "version": {
                            "type": ["string", "null"],
                            "description": "What the tool says its version is, as it prints it; null when it is missing or its answer does not say."
                          },
                          "enables": {
                            "type": "string"
                          },
                          "install": {
                            "type": "string",
                            "description": "The package that provides it."
                          },
                          "source": {
                            "type": ["string", "null"],
                            "description": "Where ExifTool comes from; null when there is none."
                          },
                          "used": {
                            "type": "boolean"
                          },
                          "missingFormats": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "installMissing": {
                            "type": "string",
                            "description": "The package that adds the formats it lacks."
                          }
                        },
                        "required": ["name", "available"]
                      }
                    }
                  },
                  "required": ["capabilities"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      }
    },
    "/api/users": {
      "get": {
        "operationId": "listUsers",
        "summary": "Every account",
        "tags": ["Accounts (administration)"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "users": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AdminUser"
                      }
                    }
                  },
                  "required": ["users"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      },
      "post": {
        "operationId": "createUser",
        "summary": "Create an account",
        "tags": ["Accounts (administration)"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "username": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string",
                    "format": "password"
                  },
                  "displayName": {
                    "type": "string"
                  },
                  "roles": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": ["admin", "user"]
                    }
                  }
                },
                "required": ["email", "password"]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user": {
                      "$ref": "#/components/schemas/User"
                    }
                  },
                  "required": ["user"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        }
      }
    },
    "/api/users/shareable": {
      "get": {
        "operationId": "listShareableUsers",
        "summary": "The accounts something can be shared with",
        "tags": ["Sharing"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "users": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "email": {
                            "type": ["string", "null"]
                          },
                          "username": {
                            "type": ["string", "null"]
                          },
                          "displayName": {
                            "type": ["string", "null"]
                          }
                        },
                        "required": ["id"]
                      }
                    }
                  },
                  "required": ["users"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          }
        }
      }
    },
    "/api/users/search": {
      "get": {
        "operationId": "searchUsers",
        "summary": "Accounts matching a name, for mentions in an editor",
        "description": "Answered in the field names an office editor expects.",
        "tags": ["Sharing"],
        "security": [
          {
            "session": []
          },
          {
            "apiToken": []
          }
        ],
        "x-access": "account",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Part of a name or an address.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "users": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "UserId": {
                            "type": "string"
                          },
                          "UserFriendlyName": {
                            "type": "string"
                          },
                          "UserEmail": {
                            "type": ["string", "null"]
                          }
                        },
                        "required": ["UserId"]
                      }
                    }
                  },
                  "required": ["users"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          }
        }
      }
    },
    "/api/users/{id}": {
      "patch": {
        "operationId": "updateUser",
        "summary": "Change an account",
        "description": "The last administrator cannot be made an ordinary account.",
        "tags": ["Accounts (administration)"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The account.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "username": {
                    "type": "string"
                  },
                  "displayName": {
                    "type": "string"
                  },
                  "roles": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": ["admin", "user"]
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user": {
                      "$ref": "#/components/schemas/User"
                    }
                  },
                  "required": ["user"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        }
      },
      "delete": {
        "operationId": "deleteUser",
        "summary": "Delete an account",
        "description": "Its sessions and API tokens end with it.",
        "tags": ["Accounts (administration)"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The account.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/users/{id}/password": {
      "post": {
        "operationId": "resetUserPassword",
        "summary": "Set an account’s password",
        "description": "Signs out every session of that account.",
        "tags": ["Accounts (administration)"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The account.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "newPassword": {
                    "type": "string",
                    "format": "password"
                  }
                },
                "required": ["newPassword"]
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Set."
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/users/{id}/lock": {
      "delete": {
        "operationId": "unlockUser",
        "summary": "Lift the lock failed sign-ins put on an account",
        "tags": ["Accounts (administration)"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The account.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Unlocked."
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/users/{id}/two-factor": {
      "delete": {
        "operationId": "removeUserSecondFactor",
        "summary": "Take the second factor off an account that lost it",
        "tags": ["Accounts (administration)"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The account.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Removed."
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/users/{id}/passkeys": {
      "delete": {
        "operationId": "removeUserPasskeys",
        "summary": "Take every passkey off an account",
        "tags": ["Accounts (administration)"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The account.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Removed."
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/users/{userId}/volumes": {
      "get": {
        "operationId": "listUserVolumes",
        "summary": "The volumes assigned to an account",
        "description": "With `USER_VOLUMES` on.",
        "tags": ["Accounts (administration)"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "parameters": [
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "description": "The account.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "volumes": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/UserVolume"
                      }
                    }
                  },
                  "required": ["volumes"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      },
      "post": {
        "operationId": "assignVolume",
        "summary": "Assign a folder of the server to an account",
        "tags": ["Accounts (administration)"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "parameters": [
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "description": "The account.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "label": {
                    "type": "string",
                    "description": "What the account sees it as."
                  },
                  "path": {
                    "type": "string",
                    "description": "An absolute path on the server."
                  },
                  "accessMode": {
                    "type": "string",
                    "enum": ["readonly", "readwrite"],
                    "default": "readwrite"
                  }
                },
                "required": ["label", "path"]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Assigned.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "volume": {
                      "$ref": "#/components/schemas/UserVolume"
                    }
                  },
                  "required": ["volume"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        }
      }
    },
    "/api/users/{userId}/volumes/{volumeId}": {
      "patch": {
        "operationId": "updateAssignedVolume",
        "summary": "Rename an assigned volume or change its access",
        "tags": ["Accounts (administration)"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "parameters": [
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "description": "The account.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "volumeId",
            "in": "path",
            "required": true,
            "description": "The assigned volume.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "label": {
                    "type": "string"
                  },
                  "accessMode": {
                    "type": "string",
                    "enum": ["readonly", "readwrite"]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "volume": {
                      "$ref": "#/components/schemas/UserVolume"
                    }
                  },
                  "required": ["volume"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        }
      },
      "delete": {
        "operationId": "unassignVolume",
        "summary": "Take an assigned volume away",
        "tags": ["Accounts (administration)"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "parameters": [
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "description": "The account.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "volumeId",
            "in": "path",
            "required": true,
            "description": "The assigned volume.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Taken away."
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/admin/browse-directories": {
      "get": {
        "operationId": "browseServerFolders",
        "summary": "Folders of the server, to pick one to assign",
        "tags": ["Accounts (administration)"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "parameters": [
          {
            "name": "path",
            "in": "query",
            "required": false,
            "description": "An absolute path; the volume when absent.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "current": {
                      "type": "string"
                    },
                    "parent": {
                      "type": ["string", "null"]
                    },
                    "directories": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "path": {
                            "type": "string"
                          }
                        },
                        "required": ["name", "path"]
                      }
                    }
                  },
                  "required": ["current", "directories"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/activity": {
      "get": {
        "operationId": "readActivity",
        "summary": "What was recorded, newest first",
        "description": "Carry on from a page with `before` set to its `nextBefore`.",
        "tags": ["Administration"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "parameters": [
          {
            "name": "action",
            "in": "query",
            "required": false,
            "description": "One kind of event, from `actions`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "outcome",
            "in": "query",
            "required": false,
            "description": "`done` or `refused`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "user",
            "in": "query",
            "required": false,
            "description": "One account.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Not before.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Not after.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Words in the target or the detail.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "description": "Where the previous page ended.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "How many.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "events": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ActivityEvent"
                      }
                    },
                    "nextBefore": {
                      "type": ["string", "null"]
                    },
                    "enabled": {
                      "type": "boolean"
                    },
                    "actions": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": ["events", "enabled", "actions"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      },
      "delete": {
        "operationId": "clearActivity",
        "summary": "Empty the activity log",
        "description": "Writes one last line, naming who asked and how many went.",
        "tags": ["Administration"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "removed": {
                      "type": "integer"
                    }
                  },
                  "required": ["removed"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      }
    },
    "/api/activity/address": {
      "get": {
        "operationId": "explainRecordedAddress",
        "summary": "Why the log records the address it records",
        "tags": ["Administration"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "recorded": {
                      "type": ["string", "null"]
                    },
                    "peer": {
                      "type": ["string", "null"]
                    },
                    "trustsPeer": {
                      "type": "boolean"
                    },
                    "trustProxy": {
                      "description": "The rule in force."
                    },
                    "announced": {
                      "type": "object",
                      "properties": {},
                      "additionalProperties": true,
                      "description": "Every forwarding header that arrived."
                    }
                  },
                  "required": ["recorded", "peer", "trustsPeer"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      }
    },
    "/api/terminal/session": {
      "post": {
        "operationId": "openTerminal",
        "summary": "A short-lived ticket for a terminal on the server",
        "description": "For the WebSocket at `/api/terminal`. `503` when the terminal is off.",
        "tags": ["Administration"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "admin",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "cwd": {
                    "type": "string",
                    "description": "A volume path to start in."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "token": {
                      "type": "string"
                    }
                  },
                  "required": ["token"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "503": {
            "$ref": "#/components/responses/E503"
          }
        }
      }
    },
    "/api/openapi.json": {
      "get": {
        "operationId": "describeApi",
        "summary": "This description",
        "description": "For a generated client or an explorer; `info.version` is the release this instance runs.",
        "tags": ["Settings"],
        "security": [],
        "x-access": "public",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "openapi": {
                      "type": "string"
                    },
                    "info": {
                      "type": "object",
                      "properties": {},
                      "additionalProperties": true
                    }
                  },
                  "required": ["openapi", "info"],
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/healthz": {
      "get": {
        "operationId": "isAlive",
        "summary": "Whether the process answers",
        "description": "Before the session store, the identity provider and every route: a probe that waited on those would report them, not this process.",
        "tags": ["Health"],
        "security": [],
        "x-access": "public",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "const": "ok"
                    }
                  },
                  "required": ["status"]
                }
              }
            }
          }
        }
      }
    },
    "/readyz": {
      "get": {
        "operationId": "isReady",
        "summary": "Whether the application has started",
        "tags": ["Health"],
        "security": [],
        "x-access": "public",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "const": "ready"
                    }
                  },
                  "required": ["status"]
                }
              }
            }
          }
        }
      }
    },
    "/api/onlyoffice/config": {
      "post": {
        "operationId": "configureOnlyofficeEditor",
        "summary": "What the ONLYOFFICE editor is opened with",
        "description": "The editor configuration, signed with `ONLYOFFICE_SECRET`, and the session the page reports on. With `versionId`, an earlier version opened to read.",
        "tags": ["ONLYOFFICE"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "The document."
                  },
                  "mode": {
                    "type": "string",
                    "enum": ["edit", "view"],
                    "default": "edit"
                  },
                  "theme": {
                    "type": "string",
                    "description": "The page’s theme, passed on to the editor."
                  },
                  "versionId": {
                    "type": "string"
                  }
                },
                "required": ["path"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "documentServerUrl": {
                      "type": "string"
                    },
                    "config": {
                      "type": "object",
                      "properties": {},
                      "additionalProperties": true,
                      "description": "What `DocsAPI.DocEditor` takes, `token` included."
                    },
                    "forceSaveSessionId": {
                      "type": "string"
                    },
                    "autoSaveIntervalMs": {
                      "type": "number"
                    }
                  },
                  "required": ["documentServerUrl", "config"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "415": {
            "$ref": "#/components/responses/E415"
          }
        }
      }
    },
    "/api/onlyoffice/session-heartbeat": {
      "post": {
        "operationId": "keepOnlyofficeSession",
        "summary": "Say the editor page is still open",
        "tags": ["ONLYOFFICE"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "The document."
                  },
                  "sessionId": {
                    "type": "string",
                    "description": "The editing session, from the configuration."
                  }
                },
                "required": ["path", "sessionId"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "active": {
                      "type": "boolean"
                    }
                  },
                  "required": ["active"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      }
    },
    "/api/onlyoffice/session-end": {
      "post": {
        "operationId": "endOnlyofficeSession",
        "summary": "Say the editor page closed",
        "description": "Asks the document server to save what is pending.",
        "tags": ["ONLYOFFICE"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "The document."
                  },
                  "sessionId": {
                    "type": "string",
                    "description": "The editing session, from the configuration."
                  }
                },
                "required": ["path", "sessionId"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ended": {
                      "type": "boolean"
                    },
                    "flushed": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "type": ["string", "null"]
                    }
                  },
                  "required": ["ended"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      }
    },
    "/api/onlyoffice/force-save": {
      "post": {
        "operationId": "forceSaveOnlyoffice",
        "summary": "Ask the document server to save now",
        "tags": ["ONLYOFFICE"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "The document."
                  },
                  "sessionId": {
                    "type": "string",
                    "description": "The editing session, from the configuration."
                  },
                  "reason": {
                    "type": "string",
                    "enum": ["close", "auto"],
                    "default": "close"
                  }
                },
                "required": ["path", "sessionId"]
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Asked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "queued": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "type": "string"
                    }
                  },
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      }
    },
    "/api/onlyoffice/history": {
      "post": {
        "operationId": "getOnlyofficeHistory",
        "summary": "The versions of a document, as the editor lists them",
        "tags": ["ONLYOFFICE"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "The document."
                  }
                },
                "required": ["path"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "currentVersion": {
                      "type": "integer"
                    },
                    "history": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      }
                    },
                    "canRestore": {
                      "type": "boolean"
                    }
                  },
                  "required": ["currentVersion", "history"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/onlyoffice/history-data": {
      "post": {
        "operationId": "getOnlyofficeHistoryData",
        "summary": "Where the editor reads one earlier version from",
        "tags": ["ONLYOFFICE"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "The document."
                  },
                  "version": {
                    "type": "integer"
                  },
                  "versionId": {
                    "type": "string"
                  }
                },
                "required": ["path", "version"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "What `setHistoryData` takes, signed."
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/onlyoffice/rename": {
      "post": {
        "operationId": "renameFromOnlyoffice",
        "summary": "Rename the document from inside the editor",
        "tags": ["ONLYOFFICE"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "The document."
                  },
                  "sessionId": {
                    "type": "string",
                    "description": "The editing session, from the configuration."
                  },
                  "newName": {
                    "type": "string"
                  }
                },
                "required": ["path", "sessionId", "newName"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "path": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    }
                  },
                  "required": ["path", "name"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          }
        }
      }
    },
    "/api/onlyoffice/save-as": {
      "post": {
        "operationId": "saveAsFromOnlyoffice",
        "summary": "Save a copy the editor made, beside the document",
        "description": "The copy is fetched from the document server, and only from there.",
        "tags": ["ONLYOFFICE"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "The document."
                  },
                  "url": {
                    "type": "string",
                    "description": "On the document server."
                  },
                  "title": {
                    "type": "string"
                  }
                },
                "required": ["path", "url"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "path": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "size": {
                      "type": "number"
                    }
                  },
                  "required": ["path", "name"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      }
    },
    "/api/onlyoffice/storage-file": {
      "post": {
        "operationId": "pickFileForOnlyoffice",
        "summary": "A file the editor inserts or compares, signed for it",
        "tags": ["ONLYOFFICE"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "The document."
                  },
                  "c": {
                    "type": "string",
                    "description": "The editor’s command."
                  }
                },
                "required": ["path"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/onlyoffice/users": {
      "get": {
        "operationId": "listOnlyofficeUsers",
        "summary": "The accounts the editor may mention",
        "tags": ["ONLYOFFICE"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "users": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "email": {
                            "type": ["string", "null"]
                          }
                        },
                        "required": ["id"]
                      }
                    }
                  },
                  "required": ["users"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      }
    },
    "/api/onlyoffice/notify": {
      "post": {
        "operationId": "notifyFromOnlyoffice",
        "summary": "Somebody was mentioned in a comment",
        "description": "Nothing is sent by mail; the answer says so.",
        "tags": ["ONLYOFFICE"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "requestBody": {
          "required": true,
          "description": "At most fifty addresses.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "The document."
                  },
                  "emails": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "required": ["path"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "delivered": {
                      "type": "boolean"
                    }
                  },
                  "required": ["delivered"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      }
    },
    "/api/onlyoffice/activity-version": {
      "get": {
        "operationId": "waitForOnlyofficeActivity",
        "summary": "Wait for a change in the documents being edited",
        "description": "A long poll: answered when something changed after `since`, or when it has waited long enough.",
        "tags": ["ONLYOFFICE"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "parameters": [
          {
            "name": "since",
            "in": "query",
            "required": false,
            "description": "The version already seen.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "version": {
                      "type": "integer"
                    },
                    "changed": {
                      "type": "boolean"
                    }
                  },
                  "required": ["version", "changed"]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          }
        }
      }
    },
    "/api/onlyoffice/file": {
      "get": {
        "operationId": "serveFileToOnlyoffice",
        "summary": "The document, fetched by the document server",
        "description": "Checked against the signed token the document server sends.",
        "tags": ["ONLYOFFICE"],
        "security": [],
        "x-access": "integration",
        "parameters": [
          {
            "name": "path",
            "in": "query",
            "required": true,
            "description": "The document.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "description": "The document server’s signed token.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The document.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/api/onlyoffice/callback": {
      "post": {
        "operationId": "receiveOnlyofficeCallback",
        "summary": "The document server reporting a save",
        "description": "Its callback protocol: `{ \"error\": 0 }` when handled, `{ \"error\": 1 }` otherwise, always with a `200`.",
        "tags": ["ONLYOFFICE"],
        "security": [],
        "x-access": "integration",
        "parameters": [
          {
            "name": "path",
            "in": "query",
            "required": true,
            "description": "The document.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {},
                "additionalProperties": true,
                "description": "As the document server sends it: `status`, `url`, `key`, `token`…"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "integer",
                      "enum": [0, 1]
                    }
                  },
                  "required": ["error"]
                }
              }
            }
          }
        }
      }
    },
    "/api/collabora/config": {
      "post": {
        "operationId": "configureCollaboraEditor",
        "summary": "Where the Collabora editor is opened, and its access token",
        "description": "Reads Collabora’s discovery to find the editor for this kind of file.",
        "tags": ["Collabora"],
        "security": [
          {
            "session": []
          }
        ],
        "x-access": "session",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "The document."
                  },
                  "mode": {
                    "type": "string",
                    "enum": ["edit", "view"],
                    "default": "edit"
                  }
                },
                "required": ["path"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "urlSrc": {
                      "type": "string"
                    },
                    "fileId": {
                      "type": "string"
                    },
                    "accessToken": {
                      "type": "string"
                    },
                    "accessTokenTtl": {
                      "type": "integer",
                      "description": "Milliseconds since the epoch."
                    }
                  },
                  "required": ["urlSrc", "fileId", "accessToken"]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "415": {
            "$ref": "#/components/responses/E415"
          },
          "500": {
            "$ref": "#/components/responses/E500"
          }
        }
      }
    },
    "/api/collabora/wopi/files/{fileId}": {
      "get": {
        "operationId": "wopiCheckFileInfo",
        "summary": "WOPI CheckFileInfo",
        "tags": ["Collabora"],
        "security": [],
        "x-access": "integration",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "required": true,
            "description": "From the configuration.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "access_token",
            "in": "query",
            "required": true,
            "description": "From the configuration.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "BaseFileName": {
                      "type": "string"
                    },
                    "Size": {
                      "type": "number"
                    },
                    "UserCanWrite": {
                      "type": "boolean"
                    }
                  },
                  "required": ["BaseFileName"],
                  "additionalProperties": true
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      },
      "post": {
        "operationId": "wopiLock",
        "summary": "WOPI Lock, Unlock, RefreshLock, UnlockAndRelock and GetLock",
        "description": "Chosen by `X-WOPI-Override`.",
        "tags": ["Collabora"],
        "security": [],
        "x-access": "integration",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "required": true,
            "description": "From the configuration.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "access_token",
            "in": "query",
            "required": true,
            "description": "From the configuration.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-WOPI-Override",
            "in": "header",
            "required": true,
            "description": "The operation.",
            "schema": {
              "type": "string",
              "enum": ["LOCK", "UNLOCK", "REFRESH_LOCK", "UNLOCK_AND_RELOCK", "GET_LOCK"]
            }
          },
          {
            "name": "X-WOPI-Lock",
            "in": "header",
            "required": false,
            "description": "The lock.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Done; `X-WOPI-Lock` where the protocol says."
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "description": "Held under another lock."
          }
        }
      }
    },
    "/api/collabora/wopi/files/{fileId}/contents": {
      "get": {
        "operationId": "wopiGetFile",
        "summary": "WOPI GetFile",
        "tags": ["Collabora"],
        "security": [],
        "x-access": "integration",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "required": true,
            "description": "From the configuration.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "access_token",
            "in": "query",
            "required": true,
            "description": "From the configuration.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The document.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      },
      "post": {
        "operationId": "wopiPutFile",
        "summary": "WOPI PutFile",
        "tags": ["Collabora"],
        "security": [],
        "x-access": "integration",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "required": true,
            "description": "From the configuration.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "access_token",
            "in": "query",
            "required": true,
            "description": "From the configuration.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-WOPI-Lock",
            "in": "header",
            "required": false,
            "description": "The lock held.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/octet-stream": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "description": "Held under another lock."
          },
          "413": {
            "$ref": "#/components/responses/E413"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "User": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "email": {
            "type": ["string", "null"]
          },
          "emailVerified": {
            "type": "boolean"
          },
          "username": {
            "type": ["string", "null"]
          },
          "displayName": {
            "type": ["string", "null"]
          },
          "roles": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": ["admin", "user"]
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "personalFolderName": {
            "type": ["string", "null"],
            "description": "The folder this account owns, once it has been given one."
          },
          "provider": {
            "type": "string",
            "description": "How this session signed in — `local` or `oidc`. On the signed-in account only."
          }
        },
        "required": ["id", "roles"]
      },
      "AdminUser": {
        "allOf": [
          {
            "$ref": "#/components/schemas/User"
          },
          {
            "type": "object",
            "properties": {
              "authMethods": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "method": {
                      "type": "string"
                    },
                    "provider": {
                      "type": ["string", "null"]
                    }
                  }
                }
              },
              "lockedUntil": {
                "type": ["string", "null"],
                "description": "Set while failed sign-ins keep the account locked.",
                "format": "date-time"
              },
              "twoFactorEnabled": {
                "type": "boolean"
              }
            }
          }
        ]
      },
      "Access": {
        "type": "object",
        "properties": {
          "canRead": {
            "type": "boolean"
          },
          "canWrite": {
            "type": "boolean"
          },
          "canUpload": {
            "type": "boolean"
          },
          "canDelete": {
            "type": "boolean"
          },
          "canCreateFolder": {
            "type": "boolean"
          },
          "canCreateFile": {
            "type": "boolean"
          },
          "canShare": {
            "type": "boolean"
          },
          "canDownload": {
            "type": "boolean"
          },
          "canSeeVersions": {
            "type": "boolean"
          },
          "readOnly": {
            "type": ["string", "null"],
            "description": "Why nothing can be written here when the storage itself refuses it, for everyone: `storage` for a read-only mount, `permission` for a folder the server may not write in. The write permissions above are then all false.",
            "enum": ["storage", "permission", null]
          }
        },
        "description": "What this caller may do here — asked before trying, rather than learned from a refusal."
      },
      "Item": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "path": {
            "type": "string",
            "description": "The folder it is in, not including its own name."
          },
          "kind": {
            "type": "string",
            "description": "`directory` for a folder, `volume` at the top, otherwise the extension in lower case — `pdf`, `md`, `unknown`."
          },
          "size": {
            "type": "number",
            "description": "Bytes. For a folder, what the file system reports for the folder itself."
          },
          "dateModified": {
            "type": "string",
            "format": "date-time"
          },
          "access": {
            "$ref": "#/components/schemas/Access"
          },
          "supportsThumbnail": {
            "type": "boolean",
            "description": "A thumbnail can be asked for at `/api/thumbnails/…`."
          },
          "versions": {
            "type": "object",
            "properties": {
              "count": {
                "type": "integer"
              },
              "bytes": {
                "type": "number"
              },
              "newest": {
                "type": ["string", "null"],
                "format": "date-time"
              }
            },
            "description": "Earlier versions kept, where this caller may see them."
          },
          "onlyofficeActivity": {
            "type": "object",
            "properties": {},
            "additionalProperties": true,
            "description": "Somebody has it open in ONLYOFFICE right now."
          }
        },
        "required": ["name", "path", "kind"]
      },
      "Error": {
        "type": "object",
        "properties": {
          "success": {
            "const": false
          },
          "error": {
            "type": "object",
            "properties": {
              "message": {
                "type": "string",
                "description": "A sentence for a person."
              },
              "statusCode": {
                "type": "integer"
              },
              "code": {
                "type": "string",
                "description": "A stable name for the refusal, where there is one — `AUTH_TOKEN_READ_ONLY`, `ARCHIVE_ENCRYPTED`."
              },
              "requestId": {
                "type": "string",
                "description": "Also in the server log: what to quote when something needs explaining."
              },
              "timestamp": {
                "type": "string",
                "format": "date-time"
              },
              "details": {}
            },
            "required": ["message", "statusCode"]
          }
        },
        "required": ["success", "error"]
      },
      "GateRefusal": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string"
          }
        },
        "required": ["error"]
      },
      "Share": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "shareToken": {
            "type": "string",
            "description": "What the link carries."
          },
          "ownerId": {
            "type": "string"
          },
          "sourceSpace": {
            "type": "string",
            "enum": ["volume", "personal", "user_volume"]
          },
          "sourcePath": {
            "type": "string"
          },
          "isDirectory": {
            "type": "boolean"
          },
          "accessMode": {
            "type": "string",
            "enum": ["readonly", "readwrite"]
          },
          "allowDelete": {
            "type": "boolean"
          },
          "allowCreateFolder": {
            "type": "boolean"
          },
          "allowCreateFile": {
            "type": "boolean"
          },
          "allowUpload": {
            "type": "boolean"
          },
          "allowDownload": {
            "type": "boolean"
          },
          "versionsVisible": {
            "type": "boolean"
          },
          "versionsDownload": {
            "type": "boolean"
          },
          "sharingType": {
            "type": "string",
            "enum": ["anyone", "users"]
          },
          "hasPassword": {
            "type": "boolean"
          },
          "expiresAt": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "label": {
            "type": ["string", "null"]
          },
          "accessCount": {
            "type": "integer"
          },
          "downloadCount": {
            "type": "integer"
          },
          "lastAccessedAt": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "lastAccessIp": {
            "type": ["string", "null"]
          },
          "lastDownloadedAt": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "lastDownloadIp": {
            "type": ["string", "null"]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "userIds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The accounts it is shared with, when `sharingType` is `users`."
          },
          "shareUrl": {
            "type": "string",
            "description": "Built from `PUBLIC_URL` when it is set. On creation."
          },
          "directFileUrl": {
            "type": "string",
            "description": "On creation."
          }
        },
        "required": ["id", "shareToken", "sourcePath", "isDirectory", "accessMode", "sharingType"]
      },
      "Version": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "size": {
            "type": "number"
          },
          "modifiedAt": {
            "type": "string",
            "description": "When the file had this content.",
            "format": "date-time"
          },
          "capturedAt": {
            "type": "string",
            "description": "When it was kept.",
            "format": "date-time"
          },
          "author": {
            "type": ["object", "null"],
            "properties": {
              "id": {
                "type": ["string", "null"]
              },
              "label": {
                "type": "string"
              }
            }
          },
          "source": {
            "type": "string",
            "description": "What kept it — a save from the editor, an upload over it, an office session."
          },
          "label": {
            "type": ["string", "null"]
          },
          "pinned": {
            "type": "boolean",
            "description": "Kept whatever thinning would otherwise do."
          },
          "aside": {
            "type": "boolean",
            "description": "Set aside by a co-editor’s save rather than kept on a schedule."
          },
          "available": {
            "type": "boolean"
          }
        },
        "required": ["id", "size", "modifiedAt"]
      },
      "Favorite": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "path": {
            "type": "string"
          },
          "label": {
            "type": ["string", "null"]
          },
          "icon": {
            "type": ["string", "null"]
          },
          "color": {
            "type": ["string", "null"]
          },
          "position": {
            "type": "integer"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": ["id", "path"]
      },
      "ApiToken": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "scope": {
            "type": "string",
            "enum": ["read", "write"]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "lastUsedAt": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "lastUsedIp": {
            "type": ["string", "null"]
          }
        },
        "required": ["id", "name", "scope"]
      },
      "Passkey": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": ["string", "null"]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastUsedAt": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "backedUp": {
            "type": "boolean"
          },
          "transports": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": ["id"]
      },
      "PasskeyOptions": {
        "type": "object",
        "properties": {
          "options": {
            "type": "object",
            "properties": {},
            "description": "What `navigator.credentials` expects, every byte as base64url.",
            "additionalProperties": true
          },
          "origins": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": ["options", "origins"]
      },
      "TrashItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "size": {
            "type": ["number", "null"]
          },
          "deletedAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "deletedBy": {
            "type": ["object", "null"],
            "properties": {
              "id": {
                "type": ["string", "null"]
              },
              "label": {
                "type": "string"
              },
              "isYou": {
                "type": "boolean"
              }
            }
          },
          "location": {
            "type": "object",
            "properties": {
              "kind": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "parent": {
                "type": "string"
              }
            }
          },
          "openPath": {
            "type": ["string", "null"]
          },
          "available": {
            "type": "boolean"
          },
          "shareCount": {
            "type": "integer"
          }
        },
        "required": ["id", "name"]
      },
      "TrashZone": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": ["volume", "personal", "user_volume"]
          },
          "name": {
            "type": "string"
          },
          "available": {
            "type": "boolean"
          },
          "reason": {
            "type": ["string", "null"]
          },
          "itemCount": {
            "type": "integer"
          },
          "usedBytes": {
            "type": "number"
          },
          "versionCount": {
            "type": "integer"
          },
          "versionBytes": {
            "type": "number"
          },
          "budgetBytes": {
            "type": ["number", "null"]
          },
          "freeBytes": {
            "type": ["number", "null"]
          },
          "lastPass": {
            "type": ["object", "null"],
            "properties": {},
            "additionalProperties": true
          },
          "events": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {},
              "additionalProperties": true
            }
          }
        },
        "required": ["id", "kind", "name"]
      },
      "FolderSize": {
        "type": "object",
        "properties": {
          "path": {
            "type": "string"
          },
          "canEnter": {
            "type": "boolean"
          },
          "sizeBytes": {
            "type": ["number", "null"]
          },
          "entryCount": {
            "type": ["integer", "null"]
          },
          "lastUpdated": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "indexed": {
            "type": "boolean"
          },
          "dirty": {
            "type": "boolean",
            "description": "Counted before something changed under it."
          },
          "excluded": {
            "type": "boolean"
          }
        },
        "required": ["path"]
      },
      "ActivityEvent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "action": {
            "type": "string"
          },
          "outcome": {
            "type": "string"
          },
          "userId": {
            "type": ["string", "null"]
          },
          "actor": {
            "type": ["string", "null"]
          },
          "target": {
            "type": ["string", "null"]
          },
          "detail": {
            "type": ["string", "null"],
            "description": "JSON, as recorded."
          },
          "ip": {
            "type": ["string", "null"]
          }
        },
        "required": ["id", "at", "action"]
      },
      "UserVolume": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "userId": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "path": {
            "type": "string",
            "description": "Where it is on the server."
          },
          "accessMode": {
            "type": "string",
            "enum": ["readonly", "readwrite"]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": ["id", "label", "path", "accessMode"]
      }
    },
    "responses": {
      "E400": {
        "description": "The request is not one this operation can act on; the message says why.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E401": {
        "description": "Nobody is signed in, or the credential presented is not usable. The gate in front of every route answers `{ \"error\" }`; a route answers the usual error body.",
        "content": {
          "application/json": {
            "schema": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/Error"
                },
                {
                  "$ref": "#/components/schemas/GateRefusal"
                }
              ]
            }
          }
        }
      },
      "E403": {
        "description": "Signed in, and not allowed — including an API token at a door it never opens.",
        "content": {
          "application/json": {
            "schema": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/Error"
                },
                {
                  "$ref": "#/components/schemas/GateRefusal"
                }
              ]
            }
          }
        }
      },
      "E404": {
        "description": "Not there, or not somewhere this caller may see.",
        "content": {
          "application/json": {
            "schema": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/Error"
                },
                {
                  "$ref": "#/components/schemas/GateRefusal"
                }
              ]
            }
          }
        }
      },
      "E409": {
        "description": "The state of things does not allow it — a name taken, an archive behind a password.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E413": {
        "description": "Too large, or too many.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E415": {
        "description": "Not a kind of file this operation reads.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E422": {
        "description": "Understood, and impossible — a damaged archive.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E423": {
        "description": "Held by something else for the moment.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E429": {
        "description": "Too many attempts; wait before trying again.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E500": {
        "description": "Something failed on the server; the request id is in its log.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E502": {
        "description": "A server this operation relies on — the identity provider — did not answer.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E503": {
        "description": "A tool this operation needs is not installed on this server, or the feature is off.",
        "content": {
          "application/json": {
            "schema": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/Error"
                },
                {
                  "$ref": "#/components/schemas/GateRefusal"
                }
              ]
            }
          }
        }
      },
      "E507": {
        "description": "The volume is full.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "securitySchemes": {
      "session": {
        "type": "apiKey",
        "in": "cookie",
        "name": "connect.sid",
        "description": "The session the interface uses, from `POST /api/auth/login`. As wide as the account it belongs to."
      },
      "apiToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "An API token, `nxe_…`, from Settings → API tokens, in the `Authorization` header and nowhere else. A `read` token reaches reads only (and `POST /api/download`); no token reaches the account, administration, the terminal or an editor integration."
      },
      "guestSession": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Guest-Session",
        "description": "What opening a shared link earns, from `POST /api/share/{token}/verify` or `GET /api/share/{token}/access`. Also accepted as the `guestSession` cookie."
      }
    }
  }
}
