{
  "openapi": "3.1.2",
  "info": {
    "title": "notesapp API",
    "version": "0.1.0",
    "summary": "Application HTTP contract for notesapp.",
    "description": "This document is the authoritative HTTP interface of notesapp. Every application HTTP call in the web app and the sync engine uses an operation generated from this document. Errors use RFC 9457 problem details with a stable application code.",
    "license": {
      "name": "AGPL-3.0-only",
      "identifier": "AGPL-3.0-only"
    },
    "contact": {
      "name": "notesapp maintainers",
      "url": "https://notesapp.invalid/support"
    }
  },
  "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
  "servers": [
    {
      "url": "https://notes.invalid",
      "description": "This is a placeholder address. Use the HTTPS origin of your own installation in your client or API tool. Replace the placeholder before you send a request. The generated client takes the address from its configuration."
    }
  ],
  "security": [
    {
      "sessionCookie": []
    },
    {
      "personalApiKey": []
    }
  ],
  "tags": [
    {
      "name": "service",
      "description": "Service state operations used by operators and load balancers."
    },
    {
      "name": "accounts",
      "description": "The signed in account and the settings that follow it."
    },
    {
      "name": "administration",
      "description": "Accounts, invitations, and the settings of the installation. Only an administrator reaches these operations, and none of them reads a note."
    },
    {
      "name": "workspaces",
      "description": "Workspace containers for the files of an account."
    },
    {
      "name": "files",
      "description": "Files, their immutable revisions, and the atomic changesets that accept them."
    },
    {
      "name": "publishing",
      "description": "Read-only links that an owner makes over one note or one folder."
    },
    {
      "name": "published",
      "description": "The reader path of a published link. No operation of this tag names a security scheme, so no identity hook runs for one."
    },
    {
      "name": "legal",
      "description": "The terms and the privacy notice that the operator of the installation writes. A person reads them with no account."
    },
    {
      "name": "auth",
      "description": "Authentication protocol endpoints. Better Auth implements them; the contract records their shapes so the generated client owns every call."
    },
    {
      "name": "operator",
      "description": "Operations of a service of the operator, such as a billing service (record 0190). They take the operator token and no session, set no cookie, and never read or write a note, a workspace or a published link."
    }
  ],
  "paths": {
    "/api/account": {
      "get": {
        "operationId": "getAccount",
        "summary": "Report the signed in account and its settings.",
        "description": "Reports the identifier of the signed in account, the address and the display name that the identity provider supplied, and the stored settings of that account.",
        "tags": [
          "accounts"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Account"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/account/consent": {
      "post": {
        "operationId": "acceptLegalDocuments",
        "summary": "Accept the current legal documents of the installation.",
        "description": "Stores the versions of the terms and of the privacy notice that the person accepts, with the time (record 0120). The versions must be the current ones, so a page that showed an older version records nothing and answers consent_required.",
        "tags": [
          "accounts"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/Consent"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/ConsentRecorded"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/account/keys": {
      "get": {
        "operationId": "listApiKeys",
        "summary": "List the API keys of the account.",
        "description": "Lists the names, creation, expiry and last use of all keys. No secret is returned.",
        "tags": [
          "accounts"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "description": "List the API keys of the account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKeyList"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "post": {
        "operationId": "createApiKey",
        "summary": "Create an API key.",
        "description": "Makes one key with full access to the account and current rights. The secret appears in this answer only. The account keeps at most 25 keys. Create a replacement before revoking an old key to rotate it.",
        "tags": [
          "accounts"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Create an API key.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApiKeyCreateInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Create an API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKeyCreated"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/account/keys/{keyId}": {
      "delete": {
        "operationId": "revokeApiKey",
        "summary": "Revoke an API key.",
        "description": "Removes one key of this account. The next request with it is refused. Another account cannot revoke this key.",
        "tags": [
          "accounts"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "name": "keyId",
            "in": "path",
            "required": true,
            "style": "simple",
            "explode": false,
            "description": "Identifier of the key to revoke.",
            "schema": {
              "$ref": "#/components/schemas/Uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Revoke an API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Removed"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/account/portal": {
      "post": {
        "operationId": "openAccountPortal",
        "summary": "Open the account portal of the operator for the signed in account.",
        "description": "Makes a single-use token that works for 60 seconds and answers the named path of the account portal with the token in the query (record 0190). The server stores only the digest of the token, and the portal redeems it through the operator API to learn the account. A locked account keeps this operation, because the portal is the way to unlock it (record 0201). An installation that names no portal answers 404 with the code not_found.",
        "tags": [
          "accounts"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/PortalOpen"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/PortalAddress"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/account/preferences": {
      "put": {
        "operationId": "updatePreferences",
        "summary": "Change the stored settings of the signed in account.",
        "description": "Stores the settings that the body names, and they follow the account to every device. A member that the body leaves out keeps its stored value. The theme family selects the palette, the appearance selects the light variant, the dark variant, or the one that matches the device, and the spell check turns the spelling marks of the editor on or off.",
        "tags": [
          "accounts"
        ],
        "security": [
          {
            "sessionCookie": []
          },
          {
            "personalApiKey": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/PreferencesUpdate"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/Preferences"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/account/removal": {
      "post": {
        "operationId": "removeOwnAccount",
        "summary": "Remove the signed in account and every note it owns.",
        "description": "The person gives their password again. The account, its workspaces, its sessions, and its settings go. The last enabled administrator cannot remove their own account.",
        "tags": [
          "accounts"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/AccountRemoval"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/Removed"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/LastAdministrator"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/account/sessions": {
      "get": {
        "operationId": "listSessions",
        "summary": "List the sessions of the signed in account.",
        "description": "Lists every session of the account with the device that the browser named and the last activity. No answer holds a token.",
        "tags": [
          "accounts"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/AccountSessionList"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/account/sessions/others": {
      "delete": {
        "operationId": "revokeOtherSessions",
        "summary": "End every session of the account but the current one.",
        "description": "Signs the account out on every other device. The session that makes the request stays.",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "tags": [
          "accounts"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/SessionsRevoked"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/account/sessions/{sessionId}": {
      "delete": {
        "operationId": "revokeSession",
        "summary": "End one session of the signed in account.",
        "description": "Ends one session of the account, for example on a lost device. A session of another account answers not found.",
        "tags": [
          "accounts"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Removed"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/account/themes": {
      "post": {
        "operationId": "importTheme",
        "summary": "Keep an imported theme for the signed in account.",
        "description": "Keeps one theme that the person imported from a file, so it follows the account to every device. The answer is the stored settings with the new theme in them. The client checks the contrast of the theme before it sends it, and the account keeps a bounded number of themes.",
        "tags": [
          "accounts"
        ],
        "security": [
          {
            "sessionCookie": []
          },
          {
            "personalApiKey": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/ThemeImport"
        },
        "responses": {
          "201": {
            "$ref": "#/components/responses/Preferences"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/ThemeLimit"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/account/themes/{themeId}": {
      "delete": {
        "operationId": "deleteTheme",
        "summary": "Delete one imported theme of the signed in account.",
        "description": "Deletes one imported theme of the account. When the account uses that theme, it takes the default family in the same change. The answer is the stored settings. A theme of another account answers not found.",
        "tags": [
          "accounts"
        ],
        "security": [
          {
            "sessionCookie": []
          },
          {
            "personalApiKey": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/ThemeId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Preferences"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/accounts": {
      "get": {
        "operationId": "listAccounts",
        "summary": "List every account of the installation.",
        "description": "Only an administrator lists the accounts. The list holds names, addresses, states, activity, and usage, and never a note.",
        "tags": [
          "administration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/AccountList"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/accounts/{accountId}": {
      "patch": {
        "operationId": "updateAccount",
        "summary": "Change the role, the state, the limit, or the controls of one account.",
        "description": "Only an administrator changes an account. A change that would leave the installation with no enabled administrator is refused. A change of the controls names the revision that the administrator read, and an old revision answers 409 with the code controls_changed (record 0189).",
        "tags": [
          "administration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/AccountId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/AccountUpdate"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/AccountSummary"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/AccountChangeConflict"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "delete": {
        "operationId": "removeAccount",
        "summary": "Remove another account and every note it owns.",
        "description": "Only an administrator removes another account. The account, its workspaces, its sessions, and its settings go. An account removes itself through removeOwnAccount instead. The removal of the last enabled administrator is refused.",
        "tags": [
          "administration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/AccountId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Removed"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/LastAdministrator"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/auth/get-session": {
      "get": {
        "operationId": "getAuthSession",
        "summary": "Report the current session.",
        "description": "Reports the session that the request cookie names, or null when there is none.",
        "tags": [
          "auth"
        ],
        "security": [],
        "x-notesapp-protocol": "better-auth",
        "responses": {
          "200": {
            "description": "The current session, or null.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthCurrentSession"
                }
              }
            }
          },
          "400": {
            "description": "The request did not match the endpoint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The credential was refused.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The request did not come from the configured origin.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "The named record does not exist.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too many attempts. Try again later.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The service failed to complete the request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/auth/request-password-reset": {
      "post": {
        "operationId": "requestPasswordReset",
        "summary": "Ask for a password reset message.",
        "description": "Sends a reset link to the address when a mail transport is configured. The link opens the reset page of the application. A deployment without one uses the operator recovery command instead. The answer never says whether the address exists, and the messages to one address count against its mail budget.",
        "tags": [
          "auth"
        ],
        "security": [],
        "x-notesapp-protocol": "better-auth",
        "requestBody": {
          "description": "The address that asks for a reset message.",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AuthPasswordResetRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The request was accepted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthOutcome"
                }
              }
            }
          },
          "400": {
            "description": "The request did not match the endpoint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The credential was refused.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The request did not come from the configured origin.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "The named record does not exist.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "The request body is larger than the configured limit.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "415": {
            "description": "The request media type is not supported.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too many attempts. Try again later.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The service failed to complete the request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/auth/reset-password": {
      "post": {
        "operationId": "resetPassword",
        "summary": "Choose a new password with a reset token.",
        "description": "Sets a new password and revokes every session of the account. The token works once and expires one hour after it was created.",
        "tags": [
          "auth"
        ],
        "security": [],
        "x-notesapp-protocol": "better-auth",
        "requestBody": {
          "description": "The new password and the reset token.",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AuthPasswordReset"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The password was replaced.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthOutcome"
                }
              }
            }
          },
          "400": {
            "description": "The request did not match the endpoint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The credential was refused.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The request did not come from the configured origin.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "The named record does not exist.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "The request body is larger than the configured limit.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "415": {
            "description": "The request media type is not supported.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too many attempts. Try again later.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The service failed to complete the request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/auth/sign-in/email": {
      "post": {
        "operationId": "signInWithPassword",
        "summary": "Sign in with an address and a password.",
        "description": "Checks a local password and sets the Secure HttpOnly session cookie. Public registration is disabled, so this endpoint never creates an account.",
        "tags": [
          "auth"
        ],
        "security": [],
        "x-notesapp-protocol": "better-auth",
        "requestBody": {
          "description": "Address and password of a local account.",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AuthPasswordSignIn"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The sign-in completed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthSession"
                }
              }
            }
          },
          "400": {
            "description": "The request did not match the endpoint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The credential was refused.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The request did not come from the configured origin.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "The named record does not exist.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "The request body is larger than the configured limit.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "415": {
            "description": "The request media type is not supported.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too many attempts. Try again later.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The service failed to complete the request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/auth/sign-out": {
      "post": {
        "operationId": "signOut",
        "summary": "End the current session.",
        "description": "Removes the session on the server and clears the session cookie. A cleared session cannot be used again.",
        "tags": [
          "auth"
        ],
        "security": [],
        "x-notesapp-protocol": "better-auth",
        "requestBody": {
          "description": "Sign-out carries no data.",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AuthSignOut"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The session ended.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthSignOutResult"
                }
              }
            }
          },
          "400": {
            "description": "The request did not match the endpoint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The credential was refused.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The request did not come from the configured origin.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "The named record does not exist.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "The request body is larger than the configured limit.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "415": {
            "description": "The request media type is not supported.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too many attempts. Try again later.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The service failed to complete the request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/auth/update-user": {
      "post": {
        "operationId": "updateProfile",
        "summary": "Change the display name of the account.",
        "description": "Stores the name of the authenticated account for either a session or an API key.",
        "tags": [
          "accounts"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Change the display name of the account.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProfileUpdateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Change the display name of the account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProfileUpdated"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/health": {
      "get": {
        "operationId": "getHealth",
        "summary": "Report that the service process is running.",
        "description": "Reports process liveness only. The operation never inspects a dependency, so a caller cannot use it to decide that the service can accept traffic. Use the readiness operation for that decision.",
        "tags": [
          "service"
        ],
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Health"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/installation": {
      "get": {
        "operationId": "getInstallation",
        "summary": "Read the settings of the installation.",
        "description": "Only an administrator reads the settings of the installation.",
        "tags": [
          "administration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Installation"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "put": {
        "operationId": "updateInstallation",
        "summary": "Change the registration policy of the installation.",
        "description": "Only an administrator changes the settings. The server refuses open registration until the installation has a mail transport and its legal documents, and it refuses any change while the server environment names the policy.",
        "tags": [
          "administration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/InstallationUpdate"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/Installation"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/SettingConflict"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "422": {
            "$ref": "#/components/responses/OpenRegistrationUnavailable"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/installation/legal/{document}": {
      "get": {
        "operationId": "getLegalDocumentSettings",
        "summary": "Read one legal document of the installation to change it.",
        "description": "Only an administrator reads the stored text or address of a document and the template of the document, with the facts that the server knows already filled in (record 0148).",
        "tags": [
          "administration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/LegalDocumentName"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/LegalDocumentSettings"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "put": {
        "operationId": "updateLegalDocument",
        "summary": "Set one legal document of the installation.",
        "description": "Only an administrator sets a document: a Markdown text that this server serves, or an external address, and its version. The documents apply when both exist. A text that still holds a blank of the template is refused. A new version asks every account to accept again (record 0120).",
        "tags": [
          "administration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/LegalDocumentName"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/LegalDocumentUpdate"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/Installation"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/SettingConflict"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "422": {
            "$ref": "#/components/responses/LegalDocumentUnfinished"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "delete": {
        "operationId": "removeLegalDocument",
        "summary": "Remove one legal document of the installation.",
        "description": "Only an administrator removes a document. The server refuses while the server environment sets the documents, and while open registration needs them (record 0114).",
        "tags": [
          "administration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/LegalDocumentName"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Installation"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/SettingConflict"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/installation/mail": {
      "put": {
        "operationId": "updateMailSettings",
        "summary": "Set the mail transport of the installation.",
        "description": "Only an administrator sets the mail transport (record 0148). A password that the body leaves out keeps the stored one, and no answer holds a password. The server refuses the change while the server environment sets the mail transport.",
        "tags": [
          "administration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/MailSettingsUpdate"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/Installation"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/SettingConflict"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "delete": {
        "operationId": "removeMailSettings",
        "summary": "Remove the mail transport of the installation.",
        "description": "Only an administrator removes the mail transport. The server refuses while the server environment sets it, and while open registration needs it (record 0114).",
        "tags": [
          "administration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Installation"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/SettingConflict"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/installation/mail/test": {
      "post": {
        "operationId": "sendTestMessage",
        "summary": "Send a test message to the address of the administrator.",
        "description": "Sends one message through the mail transport that applies now, to the address of the administrator who asks (record 0148). A failure names its kind and never the answer of the mail server.",
        "tags": [
          "administration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/MailTestSent"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/MailFailed"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/invitations": {
      "get": {
        "operationId": "listInvitations",
        "summary": "List the invitations that wait.",
        "description": "Only an administrator lists the invitations. A used or revoked invitation does not appear.",
        "tags": [
          "administration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/InvitationList"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "post": {
        "operationId": "createInvitation",
        "summary": "Invite one address to make an account.",
        "description": "Only an administrator invites. The link goes by mail when the installation has a mail transport. Otherwise the answer holds the link once, for the administrator to copy.",
        "tags": [
          "administration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/InvitationCreate"
        },
        "responses": {
          "201": {
            "$ref": "#/components/responses/InvitationCreated"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/InvitationRefused"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/invitations/{invitationId}": {
      "delete": {
        "operationId": "revokeInvitation",
        "summary": "Revoke one invitation.",
        "description": "Only an administrator revokes an invitation. A revoked invitation opens nothing.",
        "tags": [
          "administration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/InvitationId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Removed"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/operator/accounts": {
      "get": {
        "operationId": "findOperatorAccount",
        "summary": "Find one account by its sign-in address.",
        "description": "A service of the operator finds an account by its address and reads its controls with their revision and its usage (record 0190). The answer holds no note, no workspace and no published link.",
        "tags": [
          "operator"
        ],
        "security": [
          {
            "operatorToken": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/AccountAddress"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/OperatorAccount"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/OperatorNotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/operator/accounts/{accountId}": {
      "get": {
        "operationId": "readOperatorAccount",
        "summary": "Read the controls and the usage of one account.",
        "description": "A service of the operator reads the controls of one account with their revision, and its usage (record 0190). A later write of the controls names that revision.",
        "tags": [
          "operator"
        ],
        "security": [
          {
            "operatorToken": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/AccountId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/OperatorAccount"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/OperatorNotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "delete": {
        "operationId": "removeOperatorAccount",
        "summary": "Remove one account and every note it owns.",
        "description": "A service of the operator removes one account through the one removal of record 0111. The account, its workspaces, its sessions and its settings go, and a tombstone stays. The removal of the last enabled administrator is refused.",
        "tags": [
          "operator"
        ],
        "security": [
          {
            "operatorToken": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/AccountId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Removed"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/OperatorNotFound"
          },
          "409": {
            "$ref": "#/components/responses/LastAdministrator"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/operator/accounts/{accountId}/controls": {
      "patch": {
        "operationId": "setOperatorAccountControls",
        "summary": "Change the controls of one account.",
        "description": "A service of the operator changes the controls of one account with the revision that it read (record 0189). A write that names an old revision answers 409 with the code controls_changed and changes nothing, so a write that was made from an old state cannot replace a newer one.",
        "tags": [
          "operator"
        ],
        "security": [
          {
            "operatorToken": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/AccountId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/AccountControlsUpdate"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/OperatorAccount"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/OperatorNotFound"
          },
          "409": {
            "$ref": "#/components/responses/ControlsChanged"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/operator/events": {
      "get": {
        "operationId": "listOperatorAccountEvents",
        "summary": "List the account events after a cursor.",
        "description": "A service of the operator reads the events of the accounts after its own cursor, oldest first: an account was made, its address was verified, or it was removed (record 0190). The core sends nothing out, so the service asks. The positions follow the order of the commits, so a reader that continues after the last position misses no event.",
        "tags": [
          "operator"
        ],
        "security": [
          {
            "operatorToken": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/AccountEventAfter"
          },
          {
            "$ref": "#/components/parameters/PageLimit"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/AccountEventList"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/OperatorOff"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/operator/handoffs": {
      "post": {
        "operationId": "redeemAccountHandoff",
        "summary": "Redeem the token of one portal handoff.",
        "description": "The account portal of the operator redeems the token that it received and learns the account and its address (record 0190). A token works once and for 60 seconds. A used, an expired and an unknown token all answer 404 with the code not_found.",
        "tags": [
          "operator"
        ],
        "security": [
          {
            "operatorToken": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/HandoffRedeem"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/HandoffAccount"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/OperatorNotFound"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/operator/totals": {
      "get": {
        "operationId": "readOperatorTotals",
        "summary": "Read the totals of the installation for one month.",
        "description": "A service of the operator reads the totals of the whole installation for one calendar month in UTC: the published transfer, the downloads, and the calls to the object store (record 0193). A month with no count answers zero for each total.",
        "tags": [
          "operator"
        ],
        "security": [
          {
            "operatorToken": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/UsageMonthQuery"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/OperatorTotals"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/OperatorOff"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/ready": {
      "get": {
        "operationId": "getReadiness",
        "summary": "Report whether the service can accept traffic.",
        "description": "Reports the state of every startup requirement that the service can check. The current release validates configuration only, because no database or storage dependency exists yet. A later task adds a database check and a storage check to the same report.",
        "tags": [
          "service"
        ],
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Detail"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Readiness"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/NotReady"
          }
        }
      }
    },
    "/api/registrations": {
      "post": {
        "operationId": "registerAccount",
        "summary": "Make an account from an invitation and sign it in.",
        "description": "Makes an account for the address that the invitation binds, with the given password, and starts its session. A used, revoked, or expired invitation makes nothing, and the answer does not say which of the three applied. Two requests with one invitation make one account. When the installation names its terms and its privacy notice, the request names the versions that the person accepted, and a missing or an older version makes nothing (record 0120).",
        "tags": [
          "auth"
        ],
        "security": [],
        "requestBody": {
          "$ref": "#/components/requestBodies/Registration"
        },
        "responses": {
          "201": {
            "$ref": "#/components/responses/Registered"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/InvitationUnavailable"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/registrations/challenge": {
      "get": {
        "operationId": "getSignUpChallenge",
        "summary": "Read a proof of work challenge for one sign-up.",
        "description": "Answers a random value, a difficulty and an expiry, signed by this server (record 0115). The browser finds a solution whose digest starts with as many zero bits as the difficulty names, and sends it with the sign-up. One solution makes one account. No third party takes part. The installation must have the open registration policy.",
        "tags": [
          "auth"
        ],
        "security": [],
        "responses": {
          "200": {
            "$ref": "#/components/responses/SignUpChallenge"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/registrations/invitation": {
      "post": {
        "operationId": "readInvitation",
        "summary": "Read the address that a valid invitation binds.",
        "description": "Answers the address of a valid invitation, so the person sees the address of their new account before they choose a password. The token travels in the body, so it reaches no address log.",
        "tags": [
          "auth"
        ],
        "security": [],
        "requestBody": {
          "$ref": "#/components/requestBodies/InvitationRead"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/InvitationAddress"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/InvitationUnavailable"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/registrations/open": {
      "post": {
        "operationId": "signUpAccount",
        "summary": "Ask for an account with an address and a password.",
        "description": "Open registration (record 0114). A new address gets a pending account and a verification link by mail. An address that already signs in gets a mail that tells its owner about the attempt. A pending address is replaced, with its password. Every one of these answers the same status and body, so the answer states nothing about the address. The installation must have the open registration policy.",
        "tags": [
          "auth"
        ],
        "security": [],
        "requestBody": {
          "$ref": "#/components/requestBodies/SignUp"
        },
        "responses": {
          "202": {
            "$ref": "#/components/responses/SignUpAccepted"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/registrations/verification": {
      "post": {
        "operationId": "verifyAddress",
        "summary": "Prove the address of a pending account and make the account.",
        "description": "Takes the token of a verification link. A valid token marks the address verified and makes the account, and the person then signs in. An expired, a replaced and an unknown token all take one refusal. The token travels in the body, so it reaches no address log.",
        "tags": [
          "auth"
        ],
        "security": [],
        "requestBody": {
          "$ref": "#/components/requestBodies/AddressVerification"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/AddressVerified"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/VerificationUnavailable"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/reports": {
      "get": {
        "operationId": "listReports",
        "summary": "List the open reports of published links.",
        "description": "Only an administrator reads the reports. A report names its link and the address to open it, and no fact of a note or of the workspace.",
        "tags": [
          "administration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/LinkReportList"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/reports/{reportId}": {
      "delete": {
        "operationId": "dismissReport",
        "summary": "Close one report and keep its link.",
        "description": "Only an administrator closes a report. The link stays as it is.",
        "tags": [
          "administration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/ReportId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Removed"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/reports/{reportId}/takedown": {
      "post": {
        "operationId": "takeDownReportedLink",
        "summary": "Take down the link of one report.",
        "description": "Only an administrator takes a link down. The link stops at once, and every open report of it closes. The owner sees that an administrator took the link down and cannot make it live again. The administrator gets no membership, so no note of the workspace becomes readable.",
        "tags": [
          "administration"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/ReportId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Removed"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/setup": {
      "get": {
        "operationId": "getSetupStatus",
        "summary": "Report whether the first account exists and who can make one.",
        "description": "Reports if first-run setup is complete without exposing account data.",
        "tags": [
          "auth"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "The setup state.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "initialized",
                    "openRegistration",
                    "passwordReset",
                    "legalDocuments"
                  ],
                  "properties": {
                    "initialized": {
                      "type": "boolean",
                      "readOnly": true
                    },
                    "openRegistration": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Whether a person can ask for an account without an invitation (record 0114)."
                    },
                    "passwordReset": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Whether a person can reset a forgotten password by mail (record 0141). It is false when the installation has no mail transport."
                    },
                    "legalDocuments": {
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/LegalDocuments"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The terms and the privacy notice, or null when the installation names none (record 0120)."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "post": {
        "operationId": "createOwner",
        "summary": "Create the first account during first-run setup.",
        "description": "Creates the first account of the installation as its administrator and signs it in. This operation is refused after the first account exists. Every later account comes in through an invitation.",
        "tags": [
          "auth"
        ],
        "security": [],
        "requestBody": {
          "description": "The email address and password of the first account.",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "email",
                  "password"
                ],
                "properties": {
                  "email": {
                    "$ref": "#/components/schemas/EmailAddress"
                  },
                  "password": {
                    "$ref": "#/components/schemas/Password"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The first account was created and signed in.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "initialized"
                  ],
                  "properties": {
                    "initialized": {
                      "type": "boolean",
                      "readOnly": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/sync/notices": {
      "get": {
        "operationId": "openSyncNotices",
        "summary": "Open the WebSocket stream of sync notices.",
        "description": "Upgrades the connection to the WebSocket stream that tells a signed in device when the feed of a subscribed workspace changes. The stream carries notices only. Saves, receipts, feed pages and snapshots stay on the HTTP operations, and a device that cannot open the stream reads the feed on its own schedule. `asyncapi.yaml` states every message of the stream.",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "tags": [
          "files"
        ],
        "x-notesapp-protocol": "sync-notices",
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/SyncNoticeProtocolHeader"
          }
        ],
        "responses": {
          "101": {
            "$ref": "#/components/responses/SyncNoticesOpened"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/SyncNoticesUnavailable"
          }
        }
      }
    },
    "/api/sync/protocol": {
      "get": {
        "operationId": "getSyncProtocol",
        "summary": "Report the sync protocol versions that this server serves.",
        "description": "Lists every sync protocol version that the push and pull operations of this deployment accept. A client reads it before it pushes or pulls and sends nothing when its own version is not in the list. A server that answers 404 for this operation predates it and serves version 1 only. The answer holds no account or workspace data, so no session is needed.",
        "tags": [
          "service"
        ],
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/SyncProtocol"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces": {
      "get": {
        "operationId": "listWorkspaces",
        "summary": "List every workspace of the signed in account.",
        "description": "Lists the workspaces that the account is a member of, with the current role in each. An account never sees a workspace it does not belong to.",
        "tags": [
          "workspaces"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/WorkspaceList"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "post": {
        "operationId": "createWorkspace",
        "summary": "Create a workspace owned by the signed in account.",
        "description": "Creates a workspace whose only member is the account that created it, as its owner.",
        "tags": [
          "workspaces"
        ],
        "security": [
          {
            "sessionCookie": []
          },
          {
            "personalApiKey": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/WorkspaceName"
        },
        "responses": {
          "201": {
            "$ref": "#/components/responses/Workspace"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}": {
      "put": {
        "operationId": "updateWorkspace",
        "summary": "Rename a workspace.",
        "description": "Renames a workspace. An owner or an administrator of that workspace may do this.",
        "tags": [
          "workspaces"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/WorkspaceName"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/Workspace"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "delete": {
        "operationId": "deleteWorkspace",
        "summary": "Delete a workspace and every record that belongs to it.",
        "description": "Deletes a workspace and its complete content history. Only its owner may do this.",
        "tags": [
          "workspaces"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Removed"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/attachments": {
      "post": {
        "operationId": "uploadAttachment",
        "summary": "Upload a temporary attachment image file.",
        "description": "Uploads an image as multipart/form-data. The server stores the bytes in a temporary object, validates format, dimensions, and pixel count in an isolated worker, and computes the SHA-256 digest.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/UploadAttachment"
        },
        "responses": {
          "201": {
            "$ref": "#/components/responses/AttachmentUploaded"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "408": {
            "$ref": "#/components/responses/RequestTimeout"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableContent"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceBusy"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/attachments/{objectId}/finalize": {
      "post": {
        "operationId": "finalizeAttachment",
        "summary": "Finalize an attachment object and create an immutable revision.",
        "description": "Finalizes an uploaded temporary attachment object and commits an attachment revision to the workspace file tree in one transaction. An existing file requires an If-Match header naming the accepted head.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "$ref": "#/components/parameters/ObjectId"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/FinalizeAttachment"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/FileChange"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "410": {
            "$ref": "#/components/responses/Gone"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableContent"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/attachments/{revisionId}": {
      "get": {
        "operationId": "getAttachmentRevision",
        "summary": "Read the binary image of an accepted attachment revision.",
        "description": "Streams the immutable binary bytes of an accepted attachment revision with its declared media type.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "$ref": "#/components/parameters/RevisionId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/AttachmentBinary"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/changesets": {
      "post": {
        "operationId": "commitChangeset",
        "summary": "Accept one atomic change of one or more files.",
        "description": "Accepts a complete changeset: every revision commits or none does. The request states an expected head for each file it changes, and null for a file that must not exist yet. It is the operation that the sync engine uses, and it also performs a folder change of up to 1000 files. A retry with the same mutation identity and the same body returns the first outcome; the same identity with a different body is refused.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/Changeset"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/AcceptedChangeset"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "410": {
            "$ref": "#/components/responses/Gone"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableContent"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/SyncProtocolUnsupported"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/daily-note-settings": {
      "get": {
        "operationId": "getDailyNoteSettings",
        "summary": "Read the daily note settings of the signed in member.",
        "description": "Reports the settings of daily notes that the signed in account keeps in this workspace: the note whose text a new daily note starts with, and whether the note of today opens when the application starts. A member that never stored a setting reads the defaults, which name no template and open nothing. The settings of another member are never part of the answer.",
        "tags": [
          "workspaces"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/DailyNoteSettings"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "put": {
        "operationId": "updateDailyNoteSettings",
        "summary": "Replace the daily note settings of the signed in member.",
        "description": "Replaces the settings of daily notes that the signed in account keeps in this workspace. A template must name a live note of this workspace, and a template that names no such note is refused as not found. A folder and a name format that cannot make a note path for every date are refused as an invalid path. The settings of another member do not change.",
        "tags": [
          "workspaces"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/DailyNoteSettingsUpdate"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/DailyNoteSettings"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableContent"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/export": {
      "get": {
        "operationId": "exportWorkspace",
        "summary": "Download every live note and image as a zip archive.",
        "description": "Answers a zip archive that holds every live note of the workspace as a Markdown file at its stored path, plus every live image at its stored path. A deleted file is not in the archive. Nothing in the archive needs this application to be read again, so it is also the cheapest disaster recovery. The server plans the archive from the live heads before its first byte, so the answer states its exact length and streams at once. A workspace of more files or bytes than one zip archive holds without ZIP64 answers 422 with the code export_too_large. One import or export of an account runs at once (429 archive_job_running) and a few of the installation (503 archive_jobs_busy, with Retry-After). A request that states Sec-Fetch-Site cross-site is refused, so a page of another site cannot start an export of the account. A browser reads this address itself to save a large archive to its disk, so it holds no required query or header parameter (record 0178). Every archive that this operation answers is an archive that importWorkspace takes.",
        "x-notesapp-browser-address": true,
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/WorkspaceArchive"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableContent"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceBusy"
          }
        }
      },
      "head": {
        "operationId": "inspectWorkspaceExport",
        "summary": "Check that the workspace can be exported now.",
        "description": "Plans the archive of exportWorkspace and answers its headers with no body: the exact length and the download name. It runs no export job, so it costs one read of the live heads. A client checks it before it hands the address of exportWorkspace to the browser, so a workspace that one archive cannot hold, a missing workspace and a missing session reach the person as a sentence (record 0178). A HEAD answer has no body, so the status names the cause.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/WorkspaceArchivePlanned"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableContent"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/files": {
      "get": {
        "operationId": "listFiles",
        "summary": "List the live files of a workspace.",
        "description": "Lists the accepted files of the workspace in the requested order, paged with a keyset cursor. `updated` is the newest accepted change first and is the default; `path` is the order of the folder tree. A deleted file is not listed, because it holds no place in the file tree; its history stays readable through its revisions. The answer carries metadata only, so a file tree can be drawn without downloading any note.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "$ref": "#/components/parameters/FilePageCursor"
          },
          {
            "$ref": "#/components/parameters/PageLimit"
          },
          {
            "$ref": "#/components/parameters/FileSort"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/FileList"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "post": {
        "operationId": "createFile",
        "summary": "Create a file with its first revision.",
        "description": "Creates a file that does not exist yet, together with the first revision of its content. The client assigns the file, revision, and mutation identifiers, so a retry that lost its answer repeats the same operation instead of creating a second file. The answer carries a strong entity tag that names the accepted revision.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/CreateFile"
        },
        "responses": {
          "201": {
            "$ref": "#/components/responses/FileChange"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "410": {
            "$ref": "#/components/responses/Gone"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableContent"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/files/{fileId}": {
      "get": {
        "operationId": "getFile",
        "summary": "Read a file and the content of its accepted head.",
        "description": "Reports the metadata of one live file and the Markdown of its accepted head revision, and the document of the note unless the caller asks for the text alone. The answer carries a strong entity tag that names that revision, so a later conditional read answers 304 and a later conditional write answers 412 when the head has moved. If-None-Match with that tag, or with *, answers 304. A deleted file answers 404; its revisions stay readable.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "$ref": "#/components/parameters/FileId"
          },
          {
            "$ref": "#/components/parameters/FileReadContent"
          },
          {
            "$ref": "#/components/parameters/IfNoneMatch"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/File"
          },
          "304": {
            "$ref": "#/components/responses/NotModified"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "410": {
            "$ref": "#/components/responses/Gone"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "put": {
        "operationId": "updateFile",
        "summary": "Replace the content or the path of a file.",
        "description": "Writes one revision of an existing file. The request must carry the entity tag of the head that the client saw in If-Match; a request without it, and a request that carries *, both answer 428, and a head that has moved answers 412. The request states the new text, the new path, or both; a member that is absent keeps the value of the expected head. The answer carries the accepted revision without its text.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "$ref": "#/components/parameters/FileId"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/UpdateFile"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/FileChange"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "410": {
            "$ref": "#/components/responses/Gone"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableContent"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "delete": {
        "operationId": "deleteFile",
        "summary": "Delete a file by writing a tombstone revision.",
        "description": "Deletes one file. The deletion is a revision, so the history of the file stays complete and a later restore is possible. The tombstone carries no note text, and a submitted tombstone that carries Markdown is refused with 422, so a deletion can never add content. Deleting removes the file from search, so a workspace at its storage limit can still be tidied. The request must carry the entity tag of the head that the client saw.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "$ref": "#/components/parameters/FileId"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/DeleteFile"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/FileChange"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "410": {
            "$ref": "#/components/responses/Gone"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableContent"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/files/{fileId}/backlinks": {
      "get": {
        "operationId": "listBacklinks",
        "summary": "List notes that link to one live file.",
        "description": "Reads the accepted path-based link index. Each result names the live note and revision that contains at least one link to this file.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "$ref": "#/components/parameters/FileId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/BacklinkList"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/files/{fileId}/export": {
      "get": {
        "operationId": "exportNote",
        "summary": "Download one note as a Markdown file.",
        "description": "Returns the accepted head of one note as Markdown, with a content disposition that names the file. A deleted note answers 404, because it holds no place in the file tree any more.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "$ref": "#/components/parameters/FileId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/NoteMarkdown"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "410": {
            "$ref": "#/components/responses/Gone"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/files/{fileId}/history": {
      "get": {
        "operationId": "listHistory",
        "summary": "Read the revision history of a file.",
        "description": "Lists the immutable revisions of one file in reverse chronological order. The result supports cursor pagination. Each item reports byte size, author identity, checkpoint status, and restored-from references.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "$ref": "#/components/parameters/FileId"
          },
          {
            "$ref": "#/components/parameters/PageCursor"
          },
          {
            "$ref": "#/components/parameters/HistoryLimit"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/HistoryPage"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "410": {
            "$ref": "#/components/responses/Gone"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/files/{fileId}/restore": {
      "post": {
        "operationId": "restoreRevision",
        "summary": "Restore a file to a historic revision.",
        "description": "Appends a child revision to the current accepted head referencing the historic target revision in restoredFrom, reusing existing content bytes without rewriting history.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "$ref": "#/components/parameters/FileId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/RestoreRevision"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/AcceptedChangeset"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "410": {
            "$ref": "#/components/responses/Gone"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableContent"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/imports": {
      "post": {
        "operationId": "startWorkspaceImport",
        "summary": "Start the upload of a portable workspace zip archive in parts.",
        "description": "An import sends its archive in parts, because a proxy in front of the server refuses a large request body (record 0192). This operation starts the upload and answers its identifier and the size of each part. The client then sends every part with sendWorkspaceImportPart and ends with completeWorkspaceImport. The stated size is checked against the bound of one archive, up to 4 GiB without ZIP64, so a zip file that is too large is refused before a part is sent. An account has one open import: a start removes every earlier import of the account that is still open. When the server keeps the parts on its own disk, a size that its free space cannot hold answers 507 storage_full. Any server instance of the installation takes the next request of the upload. An upload that nobody completes is removed after one day.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/StartWorkspaceImport"
        },
        "responses": {
          "201": {
            "$ref": "#/components/responses/WorkspaceImportStarted"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceBusy"
          },
          "507": {
            "$ref": "#/components/responses/InsufficientStorage"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/imports/{importId}": {
      "delete": {
        "operationId": "abortWorkspaceImport",
        "summary": "Remove an import upload and every part that it holds.",
        "description": "Removes one import that startWorkspaceImport started, with its parts and with the archive of a completion that a refusal stopped (record 0192). A client calls it when a part or the completion fails, so the parts do not hold the storage of the server for a day. An import that is not there, or that another account started, answers removed as well, so a second call changes nothing.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "$ref": "#/components/parameters/ImportId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Removed"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/imports/{importId}/complete": {
      "post": {
        "operationId": "completeWorkspaceImport",
        "summary": "Complete an import and read its zip archive into the workspace.",
        "description": "Joins the parts of an import into one archive and imports it (record 0192). Parts that do not make one archive answer archive_invalid. The import reads Markdown files and image files at their archive paths. An image outside the attachments folder moves into it, and a wiki link whose target is in the archive becomes a standard link (record 0172). The settings of a tool and every other kind of file are left out, and the answer counts them. Every imported path must be free in the workspace. The operation takes every archive that exportWorkspace answers: up to 65534 files and 4 GiB without ZIP64. A refused archive answers archive_invalid, archive_too_many_files or archive_too_large. Record 0170 bounds the work: one import or export of an account runs at once (429 archive_job_running) and a few of the installation (503 archive_jobs_busy, with Retry-After), and an archive that the storage cannot hold answers 507 storage_full. After such a refusal the parts stay, so the client completes the import again later. Every file is checked before the first commit, so only a failure of the service stops an import after it (503 import_incomplete, which states how many files came in). The upload is removed when the import ends.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "$ref": "#/components/parameters/ImportId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/WorkspaceImported"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableContent"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceBusy"
          },
          "507": {
            "$ref": "#/components/responses/InsufficientStorage"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/imports/{importId}/parts/{partNumber}": {
      "put": {
        "operationId": "sendWorkspaceImportPart",
        "summary": "Send one part of a workspace zip archive.",
        "description": "Stores one part of an import that startWorkspaceImport started (record 0192). The body is the bytes of the part, and it states its length. Every part but the last holds exactly the part size that the start answered, and no part holds more. A part sent again replaces the earlier one. The gap between two chunks of the body is bounded, so a sender that stops in the middle is answered and the part is not stored. An import that does not exist, or that another account started, answers not_found. When the server keeps the parts on its own disk, a part that its free space cannot hold answers 507 storage_full before a byte of it is read.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "$ref": "#/components/parameters/ImportId"
          },
          {
            "$ref": "#/components/parameters/PartNumber"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/WorkspaceImportPart"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WorkspaceImportPartReceived"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "408": {
            "$ref": "#/components/responses/RequestTimeout"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceBusy"
          },
          "507": {
            "$ref": "#/components/responses/InsufficientStorage"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/mutations/{mutationId}": {
      "get": {
        "operationId": "getMutationReceipt",
        "summary": "Read what the workspace knows about one mutation identity.",
        "description": "States whether this workspace accepted the request that carries the mutation identity and the request digest. A device reads it after a lost answer, before it transforms work that may already have committed. The answer repeats the stored outcome and never the text of a note, so an actor that may write and not read learns nothing. A digest that names another request answers other_request.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "$ref": "#/components/parameters/MutationId"
          },
          {
            "$ref": "#/components/parameters/RequestDigest"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/MutationReceipt"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableContent"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/publications": {
      "post": {
        "operationId": "createPublishedLink",
        "summary": "Publish a read-only link to one note or one folder.",
        "description": "Makes one read-only link over one note, or over one folder and every note below it. The answer holds the token of the new link. The server keeps only a digest of that token, so this is the one time that the value exists outside the address that the owner copies. A workspace holds a bounded number of links, and a request past that bound is refused.",
        "tags": [
          "publishing"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/CreatePublishedLink"
        },
        "responses": {
          "201": {
            "$ref": "#/components/responses/PublishedLinkCreated"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableContent"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "get": {
        "operationId": "listPublishedLinks",
        "summary": "List the published links of a workspace.",
        "description": "Reports every published link of the workspace, what it opens, when it expires, and whether it has a password. No entry holds a token and no entry holds a part of one, so a read of this list opens nothing. The answer reports no reader count, because the reader path counts nothing.",
        "tags": [
          "publishing"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/PublishedLinkList"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/publications/{publicationId}": {
      "delete": {
        "operationId": "revokePublishedLink",
        "summary": "Revoke one published link.",
        "description": "Stops one published link. The server reads the link record on every reader call, so the link opens nothing from the next call onward. A reader that holds the token then takes the one refusal of the reader path.",
        "tags": [
          "publishing"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "$ref": "#/components/parameters/PublicationId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Removed"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/purge": {
      "post": {
        "operationId": "purgeFiles",
        "summary": "Permanently delete files and write purge markers.",
        "description": "Permanently purges files and revisions, writes purge markers, and reclaims storage. Subsequent writes to purged file identifiers answer 410 Gone. Restricted to the workspace owner.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/PurgeFiles"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/PurgedFiles"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableContent"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/purge/preview": {
      "post": {
        "operationId": "previewPurge",
        "summary": "Preview permanent deletion of files.",
        "description": "Reports affected revisions, reclaimable bytes, and blocking references such as attachments referenced by external revisions. Restricted to workspace owners.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/PreviewPurge"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/PurgePreview"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableContent"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/revisions/{revisionId}": {
      "get": {
        "operationId": "getRevision",
        "summary": "Read one immutable revision.",
        "description": "Reports one accepted revision of the workspace with its parents, its path at that time, and its content. A Markdown revision carries its text. An attachment revision carries the identity of its immutable object; its bytes are transferred through the attachment operations.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "$ref": "#/components/parameters/RevisionId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Revision"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/search": {
      "get": {
        "operationId": "searchFiles",
        "summary": "Search accepted live notes in a workspace.",
        "description": "Searches the accepted names of notes and the text that a reader of each note sees, with no Markdown mark and no link address. One text configuration serves every language: it is the PostgreSQL simple configuration with the unaccent filter, so it has no stemming and no stop words, and a letter with an accent matches the same letter without one. A word of the query of three characters or more matches as a prefix, and a shorter word matches only itself. Deleted files and historic revisions are excluded.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "$ref": "#/components/parameters/SearchQuery"
          },
          {
            "$ref": "#/components/parameters/SearchLimit"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/SearchResults"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/sync/changes": {
      "get": {
        "operationId": "getChanges",
        "summary": "Read ordered incremental changes after a cursor.",
        "description": "Reads the commit ordered change records after a cursor the client already applied, oldest first. Every relevant write allocates its cursor under the workspace lock, so the stream cannot skip a file transaction that commits late. A page never splits a commit, so the next cursor never passes a record of it. Change records are kept for 90 days; an older cursor answers 410 with the code snapshot_required, while saved revision identifiers stay valid beyond that window.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "$ref": "#/components/parameters/SyncCursor"
          },
          {
            "$ref": "#/components/parameters/SyncLimit"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/SyncChanges"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "410": {
            "$ref": "#/components/responses/SnapshotRequired"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableContent"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/SyncProtocolUnsupported"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/sync/snapshots": {
      "post": {
        "operationId": "startSnapshot",
        "summary": "Capture a consistent download snapshot of a workspace.",
        "description": "Captures the accepted file metadata and the workspace high-water cursor in one repeatable-read transaction and materializes bounded metadata pages for 15 minutes. Each item names an immutable revision identifier; content transfer reuses the revision read by that identifier, never a later current head. The syncVersion names the sync protocol version; only version 1 is served and any other value is rejected without changing data.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/StartSnapshot"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/SnapshotStarted"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableContent"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/SyncProtocolUnsupported"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/sync/snapshots/{token}": {
      "get": {
        "operationId": "getSnapshotPage",
        "summary": "Read one page of a materialized snapshot.",
        "description": "Reads one page of the items that the snapshot captured. The page runs in its own short transaction and rechecks current access; no database transaction stays open across network pages. A missing token, an expired snapshot, and a snapshot that a purge invalidated all answer 410 with the code snapshot_required: the client starts a fresh snapshot and keeps its local work.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "$ref": "#/components/parameters/SnapshotToken"
          },
          {
            "$ref": "#/components/parameters/SnapshotPosition"
          },
          {
            "$ref": "#/components/parameters/SnapshotPageLimit"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/SnapshotPage"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "410": {
            "$ref": "#/components/responses/SnapshotRequired"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/SyncProtocolUnsupported"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/template-settings": {
      "get": {
        "operationId": "getTemplateSettings",
        "summary": "Read the template settings of the signed in member.",
        "description": "Reports the template folder that the signed in account keeps in this workspace. Every note below this folder, also in a subfolder, is a template that the application can insert into a note. A member that never stored a setting reads the default folder, Templates. The settings of another member are never part of the answer.",
        "tags": [
          "workspaces"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/TemplateSettings"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "put": {
        "operationId": "updateTemplateSettings",
        "summary": "Replace the template settings of the signed in member.",
        "description": "Replaces the template folder that the signed in account keeps in this workspace. A folder that is not a folder path in its stored spelling is refused as an invalid path. The settings of another member do not change, and no note moves.",
        "tags": [
          "workspaces"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/TemplateSettingsUpdate"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/TemplateSettings"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableContent"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/trash": {
      "get": {
        "operationId": "listDeletedFiles",
        "summary": "List the deleted files of a workspace.",
        "description": "Lists the files of the workspace that a tombstone revision deleted, in the requested order and paged with a keyset cursor, exactly as the live listing is. A deleted file holds no place in the file tree, so it appears here instead. Each entry names the instant of the deletion and the tombstone that is the accepted head, which the restore operation needs. A permanently purged file is not listed, because nothing of it is left to restore.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "$ref": "#/components/parameters/FilePageCursor"
          },
          {
            "$ref": "#/components/parameters/PageLimit"
          },
          {
            "$ref": "#/components/parameters/FileSort"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/DeletedFileList"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workspaces/{workspaceId}/trash/{fileId}/restore": {
      "post": {
        "operationId": "restoreFile",
        "summary": "Bring one deleted file back into the file tree.",
        "description": "Writes one revision on top of the tombstone that un-deletes the file with the content of its last revision before the deletion. The tombstone is the expected head, so a change that arrived after the deletion answers 412 and nothing is written. The file keeps its identifier, so every link to it and its whole history stay valid. The file goes back to the path it held before the deletion. If a live file already holds that path, the answer restores the file beside it under the name plus \" (restored)\" in the same folder, so a restore never overwrites live work. A file that is not deleted answers 404, and a permanently purged one answers 410.",
        "tags": [
          "files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "$ref": "#/components/parameters/FileId"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/RestoreFile"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/FileChange"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "410": {
            "$ref": "#/components/responses/Gone"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableContent"
          },
          "423": {
            "$ref": "#/components/responses/AccountLocked"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/health": {
      "get": {
        "operationId": "getRootHealth",
        "summary": "Report that the service process is running, at the root address.",
        "description": "Serves the same answer as the liveness operation at the API address. A load balancer and an orchestrator usually probe a fixed root path, so the service answers that address too. The server calls one implementation for both addresses, so the two answers cannot disagree. Reports process liveness only, and never inspects a dependency.",
        "tags": [
          "service"
        ],
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Health"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/legal/{document}": {
      "get": {
        "operationId": "getLegalDocument",
        "summary": "Read one legal document of the installation.",
        "description": "Answers the terms or the privacy notice as one HTML document that the server builds from the Markdown file of the operator, with the one sanitized renderer (record 0140). The page holds no script, and its only style sheet is the built style sheet of the application. The operation declares an empty security requirement, so a person reads the documents before they have an account. A document that the operator names by an external address, or does not name, answers not found.",
        "tags": [
          "legal"
        ],
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/LegalDocumentName"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/LegalPage"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/published/{token}": {
      "get": {
        "operationId": "getPublishedPage",
        "summary": "Read the page of a published link.",
        "description": "Answers the published note as one HTML document that the server builds with the one sanitized renderer. The operation declares an empty security requirement, so no identity hook runs for it and no session reaches it. Every state of a link answers one document: it shows the note, or it says that the link is not available, or it asks for the password. A link that never existed, a revoked link, an expired link and a wrong password therefore read alike.",
        "tags": [
          "published"
        ],
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/PublishedToken"
          },
          {
            "$ref": "#/components/parameters/PublishedNote"
          },
          {
            "$ref": "#/components/parameters/ReadingTicket"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/PublishedPage"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "post": {
        "operationId": "openPublishedPage",
        "summary": "Give the password of a published link from its page.",
        "description": "Takes the password that the form of the published page carries and answers the page again. A served page holds no script, so the form sends a form encoded body and the answer is a document rather than a program. The right password answers the note, and every address on that page carries the reading ticket. A wrong password answers the same form and the same words as a link that was never opened. The operation declares an empty security requirement, so no identity hook runs for it. The attempt limit of this route guards the password check.",
        "tags": [
          "published"
        ],
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/PublishedToken"
          },
          {
            "$ref": "#/components/parameters/PublishedNote"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/PublishedPasswordForm"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/PublishedPage"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/published/{token}/attachments/{fileId}/{revisionId}": {
      "get": {
        "operationId": "getPublishedAttachment",
        "summary": "Read a picture of a published note.",
        "description": "Streams the bytes of one attachment revision that a published note names. The address names the link, the note and the revision, and the server proves all three facts on every call: the link opens the note, and the current content of that note names that revision. It trusts no part of the address. The operation declares an empty security requirement, so no identity hook runs for it. Every failure takes the one refusal of the reader path.",
        "tags": [
          "published"
        ],
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/PublishedToken"
          },
          {
            "$ref": "#/components/parameters/FileId"
          },
          {
            "$ref": "#/components/parameters/RevisionId"
          },
          {
            "$ref": "#/components/parameters/ReadingTicket"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/AttachmentBinary"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/PublishedLinkUnavailable"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/published/{token}/report": {
      "get": {
        "operationId": "getReportPage",
        "summary": "Read the report form of a published link.",
        "description": "Answers one HTML document that the server builds, with no script. The form asks for a reason from a fixed list and an optional note. The form answers the same document for every token, so it states nothing about the link.",
        "tags": [
          "published"
        ],
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/PublishedToken"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/PublishedPage"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "post": {
        "operationId": "reportPublishedLink",
        "summary": "Report a published link to the administrators.",
        "description": "Takes the reason and the note of the report form and answers one document that thanks the reader. The report is the second write of the reader path. One narrow function stores it for a link that opens now, and stores nothing for any other token. Both answer the same document. The operation declares an empty security requirement, so no identity hook runs for it. The attempt limit of this route counts each client address, and each /64 prefix of an IPv6 address.",
        "tags": [
          "published"
        ],
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/PublishedToken"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/PublishedReportForm"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/PublishedPage"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/published/{token}/unlock": {
      "post": {
        "operationId": "unlockPublishedLink",
        "summary": "Give the password of a published link.",
        "description": "Takes the password of one link and answers a reading ticket that is bound to that link. The reader carries the ticket in the address of every later call to the link, and the server sets no cookie. The operation declares an empty security requirement, so no identity hook runs for it. A wrong password and a link that never existed take one refusal, so a caller cannot walk the tokens. The attempt limit of this route guards the password check.",
        "tags": [
          "published"
        ],
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/PublishedToken"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/UnlockPublishedLink"
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/ReadingTicketGranted"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/PublishedLinkUnavailable"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/ready": {
      "get": {
        "operationId": "getRootReadiness",
        "summary": "Report whether the service can accept traffic, at the root address.",
        "description": "Serves the same answer as the readiness operation at the API address. A load balancer and an orchestrator usually probe a fixed root path, so the service answers that address too. The server calls one implementation for both addresses, so the two answers cannot disagree. Reports the state of every startup requirement, and reports the stop of the process while it drains.",
        "tags": [
          "service"
        ],
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Detail"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Readiness"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/NotReady"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "personalApiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "Personal API key",
        "description": "A personal API key gives full access to its enabled account through the Authorization header. Use HTTPS. Keys expire and can be revoked at once. Never put a key in a URL. An invalid bearer never falls back to a cookie."
      },
      "sessionCookie": {
        "type": "apiKey",
        "in": "cookie",
        "name": "notesapp_session",
        "description": "Browser session cookie. The cookie is HttpOnly and SameSite, and a cookie authenticated write also needs an origin check. A deployment whose origin is https serves the same cookie under the reserved name __Secure-notesapp_session and adds the Secure attribute, as the cookie prefix rules require."
      },
      "operatorToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "The one secret of the operator of the installation, from NOTESAPP_OPERATOR_TOKEN or from the file that NOTESAPP_OPERATOR_TOKEN_FILE names (records 0190 and 0207). A service of the operator sends it on each operator operation. The server compares it in constant time, and the attempt counters bound the failures. With no secret, every operator operation answers 404 with the code operator_off."
      }
    },
    "parameters": {
      "MutationId": {
        "name": "mutationId",
        "in": "path",
        "required": true,
        "style": "simple",
        "explode": false,
        "description": "The stable identity that the device gave one mutation.",
        "schema": {
          "$ref": "#/components/schemas/Uuid"
        }
      },
      "RequestDigest": {
        "name": "digest",
        "in": "query",
        "required": true,
        "style": "form",
        "explode": true,
        "description": "The digest of the exact request that the device froze on its first send. It decides whether the stored receipt belongs to this request.",
        "schema": {
          "$ref": "#/components/schemas/ContentDigest"
        }
      },
      "RequestId": {
        "name": "x-request-id",
        "in": "header",
        "required": false,
        "style": "simple",
        "explode": false,
        "description": "Optional caller supplied correlation identifier. The server echoes the value and generates a UUID when the header is absent. A value outside the pattern below is rejected with a 400 problem.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128,
          "pattern": "^[A-Za-z0-9._-]+$"
        }
      },
      "Detail": {
        "name": "detail",
        "in": "query",
        "required": false,
        "style": "form",
        "explode": true,
        "description": "Amount of readiness information to return. A summary report omits the detail text of each check.",
        "schema": {
          "type": "string",
          "enum": [
            "summary",
            "full"
          ]
        }
      },
      "WorkspaceId": {
        "name": "workspaceId",
        "in": "path",
        "required": true,
        "style": "simple",
        "explode": false,
        "description": "Identifier of the workspace that the operation acts on.",
        "schema": {
          "$ref": "#/components/schemas/Uuid"
        }
      },
      "FileId": {
        "name": "fileId",
        "in": "path",
        "required": true,
        "style": "simple",
        "explode": false,
        "description": "Identifier of the file that the operation acts on.",
        "schema": {
          "$ref": "#/components/schemas/Uuid"
        }
      },
      "RevisionId": {
        "name": "revisionId",
        "in": "path",
        "required": true,
        "style": "simple",
        "explode": false,
        "description": "Identifier of the revision that the operation reads.",
        "schema": {
          "$ref": "#/components/schemas/Uuid"
        }
      },
      "ObjectId": {
        "name": "objectId",
        "in": "path",
        "required": true,
        "style": "simple",
        "explode": false,
        "description": "Identifier of the attachment object that the operation acts on.",
        "schema": {
          "$ref": "#/components/schemas/Uuid"
        }
      },
      "ImportId": {
        "name": "importId",
        "in": "path",
        "required": true,
        "style": "simple",
        "explode": false,
        "description": "Identifier of the import upload that startWorkspaceImport answered.",
        "schema": {
          "$ref": "#/components/schemas/Uuid"
        }
      },
      "PartNumber": {
        "name": "partNumber",
        "in": "path",
        "required": true,
        "style": "simple",
        "explode": false,
        "description": "The place of the part in the archive, from 1. The server takes as many parts as one archive of the largest size needs, and refuses a higher number.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 10000
        }
      },
      "PageCursor": {
        "name": "cursor",
        "in": "query",
        "required": false,
        "style": "form",
        "explode": true,
        "description": "Position to continue a listing from. Use the nextCursor value of the previous page. The first page names no cursor.",
        "schema": {
          "$ref": "#/components/schemas/Uuid"
        }
      },
      "FilePageCursor": {
        "name": "cursor",
        "in": "query",
        "required": false,
        "style": "form",
        "explode": true,
        "description": "Position to continue a file listing from. Use the nextCursor value of the previous page, together with the same sort. The first page names no cursor.",
        "schema": {
          "$ref": "#/components/schemas/FilePageToken"
        }
      },
      "FileSort": {
        "name": "sort",
        "in": "query",
        "required": false,
        "style": "form",
        "explode": true,
        "description": "Order of the listing. `updated` puts the newest accepted change first and is the default. `path` orders by the stored path, which is the order of the folder tree.",
        "schema": {
          "$ref": "#/components/schemas/FileSortOrder"
        }
      },
      "PageLimit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "style": "form",
        "explode": true,
        "description": "Largest number of entries in one page. The server uses 100 when the parameter is absent and never returns more than 500.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 500
        }
      },
      "IfMatch": {
        "name": "if-match",
        "in": "header",
        "required": false,
        "style": "simple",
        "explode": false,
        "description": "The strong entity tag of the accepted head that the client saw, for example \"3f1c2b7a-0e5d-4c1b-9a7e-2b6d4f8c1a03\". A list of tags is accepted and the request proceeds when any of them names the current head. The operation needs a tag: a request without one answers 428, and a head that has moved answers 412. The parameter is declared optional so that the missing case reaches the documented 428 answer instead of a schema error. The value * is refused with 428 as well: it would permit a write against a state the client never read, which is the lost update that this precondition exists to prevent.",
        "schema": {
          "$ref": "#/components/schemas/EntityTagCondition"
        }
      },
      "IfNoneMatch": {
        "name": "if-none-match",
        "in": "header",
        "required": false,
        "style": "simple",
        "explode": false,
        "description": "Entity tag that the client already holds, or a list of them. The answer is 304 with no body when one of them names the current head. The value * means any representation, so it answers 304 for a file that exists.",
        "schema": {
          "$ref": "#/components/schemas/EntityTagCondition"
        }
      },
      "FileReadContent": {
        "name": "content",
        "in": "query",
        "required": false,
        "style": "form",
        "explode": true,
        "description": "The parts of the head that the answer carries. `text` answers the Markdown and a null document. `full` also answers the document of the note, and it is the value when the parameter is absent, so a caller that names none reads what it read before.",
        "schema": {
          "$ref": "#/components/schemas/FileReadContent"
        }
      },
      "HistoryLimit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "style": "form",
        "explode": true,
        "description": "Largest number of history items to return. Defaults to 50.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100
        }
      },
      "SearchQuery": {
        "name": "query",
        "in": "query",
        "required": true,
        "style": "form",
        "explode": true,
        "description": "Words to find in accepted note names and in the text that a reader of a note sees.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 256
        }
      },
      "SearchLimit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "style": "form",
        "explode": true,
        "description": "Largest number of search results to return.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100
        }
      },
      "SnapshotToken": {
        "name": "token",
        "in": "path",
        "required": true,
        "style": "simple",
        "explode": false,
        "description": "Opaque token of a materialized snapshot, issued by the snapshot start operation. Only its hash is stored, so the value cannot be guessed.",
        "schema": {
          "type": "string",
          "minLength": 43,
          "maxLength": 43,
          "pattern": "^[A-Za-z0-9_-]{43}$"
        }
      },
      "SnapshotPosition": {
        "name": "position",
        "in": "query",
        "required": false,
        "style": "form",
        "explode": true,
        "description": "Ordinal of the first snapshot item to return. Use the nextPosition value of the previous page. The first page starts at zero.",
        "schema": {
          "type": "integer",
          "minimum": 0
        }
      },
      "SnapshotPageLimit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "style": "form",
        "explode": true,
        "description": "Largest number of snapshot items in one page. The server uses the page size stored with the snapshot when the parameter is absent and never returns more than 500.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 500
        }
      },
      "SyncCursor": {
        "name": "cursor",
        "in": "query",
        "required": true,
        "style": "form",
        "explode": true,
        "description": "Commit ordered cursor the client already applied. The answer carries the records after this position, oldest first. A cursor that predates the retained 90 day window needs a fresh snapshot instead.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 32,
          "pattern": "^[0-9]+$"
        }
      },
      "SyncLimit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "style": "form",
        "explode": true,
        "description": "Largest number of change records in one answer. The server uses 100 when the parameter is absent and accepts at most 500. A page ends only at the end of a commit, so the server stops before a commit that does not fit. When the first commit is larger than the limit, the answer holds that one whole commit.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 500
        }
      },
      "SyncNoticeProtocolHeader": {
        "name": "sec-websocket-protocol",
        "in": "header",
        "required": true,
        "style": "simple",
        "explode": false,
        "description": "The subprotocol that the browser asks for when it opens the notice stream. The server opens the stream only for the one subprotocol that this contract names.",
        "schema": {
          "$ref": "#/components/schemas/SyncNoticeProtocol"
        }
      },
      "PublicationId": {
        "name": "publicationId",
        "in": "path",
        "required": true,
        "style": "simple",
        "explode": false,
        "description": "Identifier of the published link that the operation acts on.",
        "schema": {
          "$ref": "#/components/schemas/Uuid"
        }
      },
      "PublishedToken": {
        "name": "token",
        "in": "path",
        "required": true,
        "style": "simple",
        "explode": false,
        "description": "The token of the published link. It is the one part of the address that opens the link. Any single segment of an address is accepted here, because a value that no link holds opens nothing and must read like every other value that no link holds.",
        "schema": {
          "$ref": "#/components/schemas/PublishedSecret"
        }
      },
      "ReadingTicket": {
        "name": "ticket",
        "in": "query",
        "required": false,
        "style": "form",
        "explode": true,
        "description": "The reading ticket of a link that has a password. The reader carries it in the address, because a picture inside a server built page sets no header and the reader path sets no cookie. Leave it out for a link that opens without a password.",
        "schema": {
          "$ref": "#/components/schemas/PublishedSecret"
        }
      },
      "AccountId": {
        "name": "accountId",
        "in": "path",
        "required": true,
        "style": "simple",
        "explode": false,
        "description": "Identifier of the account that the operation acts on.",
        "schema": {
          "$ref": "#/components/schemas/Uuid"
        }
      },
      "InvitationId": {
        "name": "invitationId",
        "in": "path",
        "required": true,
        "style": "simple",
        "explode": false,
        "description": "Identifier of the invitation that the operation acts on.",
        "schema": {
          "$ref": "#/components/schemas/Uuid"
        }
      },
      "SessionId": {
        "name": "sessionId",
        "in": "path",
        "required": true,
        "style": "simple",
        "explode": false,
        "description": "Identifier of the session that the operation ends.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128,
          "pattern": "^[A-Za-z0-9_-]+$"
        }
      },
      "ThemeId": {
        "name": "themeId",
        "in": "path",
        "required": true,
        "style": "simple",
        "explode": false,
        "description": "Identifier of the imported theme that the operation removes.",
        "schema": {
          "$ref": "#/components/schemas/Uuid"
        }
      },
      "ReportId": {
        "name": "reportId",
        "in": "path",
        "required": true,
        "style": "simple",
        "explode": false,
        "description": "Identifier of the report that the operation acts on.",
        "schema": {
          "$ref": "#/components/schemas/Uuid"
        }
      },
      "LegalDocumentName": {
        "name": "document",
        "in": "path",
        "required": true,
        "style": "simple",
        "explode": false,
        "description": "Which legal document to read, the terms or the privacy notice.",
        "schema": {
          "type": "string",
          "enum": [
            "terms",
            "privacy"
          ]
        }
      },
      "AccountAddress": {
        "name": "address",
        "in": "query",
        "required": true,
        "style": "form",
        "explode": true,
        "description": "The sign-in address of the account to find. The server compares it in its one written form, in lower case.",
        "schema": {
          "$ref": "#/components/schemas/EmailAddress"
        }
      },
      "UsageMonthQuery": {
        "name": "month",
        "in": "query",
        "required": false,
        "style": "form",
        "explode": true,
        "description": "The calendar month in UTC of the totals. The server uses the current month when the parameter is absent.",
        "schema": {
          "$ref": "#/components/schemas/UsageMonth"
        }
      },
      "AccountEventAfter": {
        "name": "after",
        "in": "query",
        "required": false,
        "style": "form",
        "explode": true,
        "description": "The position of the last event that the reader already read. The answer holds the events after it, oldest first. The server uses 0 when the parameter is absent, which reads from the first event.",
        "schema": {
          "$ref": "#/components/schemas/AccountEventCursor"
        }
      },
      "PublishedNote": {
        "name": "note",
        "in": "query",
        "required": false,
        "style": "form",
        "explode": true,
        "description": "The note of a folder link that the page shows. Leave it out to read the list of every note that the link opens. A link over one note opens that note, so it needs no value here.",
        "schema": {
          "$ref": "#/components/schemas/PublishedNoteReference"
        }
      }
    },
    "requestBodies": {
      "PreferencesUpdate": {
        "description": "The settings to store for the signed in account.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/PreferencesInput"
            }
          }
        }
      },
      "ThemeImport": {
        "description": "The theme to keep for the signed in account.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ThemeImportInput"
            }
          }
        }
      },
      "DailyNoteSettingsUpdate": {
        "description": "The daily note settings to store for the signed in member.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/DailyNoteSettingsInput"
            }
          }
        }
      },
      "TemplateSettingsUpdate": {
        "description": "The template settings to store for the signed in member.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/TemplateSettingsInput"
            }
          }
        }
      },
      "WorkspaceName": {
        "description": "The name to give the workspace.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/WorkspaceNameInput"
            }
          }
        }
      },
      "CreateFile": {
        "description": "The identifiers, the path, and the first content of a new file.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/CreateFileInput"
            }
          }
        }
      },
      "UpdateFile": {
        "description": "The identifiers and the new content or path of a file.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/UpdateFileInput"
            }
          }
        }
      },
      "DeleteFile": {
        "description": "The identifiers of the tombstone revision.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/DeleteFileInput"
            }
          }
        }
      },
      "Changeset": {
        "description": "One atomic change of one or more files.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ChangesetInput"
            }
          }
        }
      },
      "UploadAttachment": {
        "description": "Multipart form upload that contains the binary attachment file.",
        "required": true,
        "content": {
          "multipart/form-data": {
            "schema": {
              "$ref": "#/components/schemas/UploadAttachmentInput"
            }
          }
        }
      },
      "StartWorkspaceImport": {
        "description": "The size of the zip archive that the import sends in parts.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/StartWorkspaceImportInput"
            }
          }
        }
      },
      "WorkspaceImportPart": {
        "description": "The bytes of one part of a zip archive, with their stated length.",
        "required": true,
        "content": {
          "application/octet-stream": {
            "schema": {
              "$ref": "#/components/schemas/WorkspaceImportPart"
            }
          }
        }
      },
      "FinalizeAttachment": {
        "description": "Payload to finalize an attachment and create an immutable revision.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/FinalizeAttachmentInput"
            }
          }
        }
      },
      "RestoreRevision": {
        "description": "Revision restore payload.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/RestoreRevisionInput"
            }
          }
        }
      },
      "PreviewPurge": {
        "description": "Purge preview payload.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/PreviewPurgeInput"
            }
          }
        }
      },
      "PurgeFiles": {
        "description": "File purge payload.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/PurgeFilesInput"
            }
          }
        }
      },
      "RestoreFile": {
        "description": "Deleted file restore payload.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/RestoreFileInput"
            }
          }
        }
      },
      "StartSnapshot": {
        "description": "Snapshot start payload.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/StartSnapshotInput"
            }
          }
        }
      },
      "CreatePublishedLink": {
        "description": "What to publish, and how a reader reaches it.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/CreatePublishedLinkInput"
            }
          }
        }
      },
      "UnlockPublishedLink": {
        "description": "The password of the published link.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/UnlockPublishedLinkInput"
            }
          }
        }
      },
      "AccountUpdate": {
        "description": "The facts of the account to change.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AccountUpdateInput"
            }
          }
        }
      },
      "InvitationCreate": {
        "description": "The address to invite.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/InvitationCreateInput"
            }
          }
        }
      },
      "InvitationRead": {
        "description": "The token of the invitation to read.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/InvitationReadInput"
            }
          }
        }
      },
      "Registration": {
        "description": "The invitation token and the password of the new account.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/RegistrationInput"
            }
          }
        }
      },
      "InstallationUpdate": {
        "description": "The settings of the installation to change.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/InstallationUpdateInput"
            }
          }
        }
      },
      "MailSettingsUpdate": {
        "description": "The mail transport to set.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/MailSettingsInput"
            }
          }
        }
      },
      "LegalDocumentUpdate": {
        "description": "The legal document to set.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/LegalDocumentInput"
            }
          }
        }
      },
      "AccountRemoval": {
        "description": "The current password of the account.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AccountRemovalInput"
            }
          }
        }
      },
      "AccountControlsUpdate": {
        "description": "The change of the controls and the revision that it read.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AccountControlsInput"
            }
          }
        }
      },
      "HandoffRedeem": {
        "description": "The token of the handoff.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/HandoffRedeemInput"
            }
          }
        }
      },
      "PortalOpen": {
        "description": "The path on the account portal to open.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/PortalOpenInput"
            }
          }
        }
      },
      "SignUp": {
        "description": "The address and the password of the account that a person asks for.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SignUpInput"
            }
          }
        }
      },
      "AddressVerification": {
        "description": "The token of a verification link.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AddressVerificationInput"
            }
          }
        }
      },
      "Consent": {
        "description": "The versions of the legal documents that the person accepts.",
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ConsentInput"
            }
          }
        }
      },
      "PublishedPasswordForm": {
        "description": "The password of the published link, as its page form sends it.",
        "required": true,
        "content": {
          "application/x-www-form-urlencoded": {
            "schema": {
              "$ref": "#/components/schemas/PublishedPasswordFormInput"
            }
          }
        }
      },
      "PublishedReportForm": {
        "description": "The report of a published link, as its form sends it.",
        "required": true,
        "content": {
          "application/x-www-form-urlencoded": {
            "schema": {
              "$ref": "#/components/schemas/PublishedReportFormInput"
            }
          }
        }
      }
    },
    "responses": {
      "Health": {
        "description": "The service process is running.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/HealthReport"
            }
          }
        }
      },
      "Readiness": {
        "description": "The service can accept traffic.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ReadinessReport"
            }
          }
        }
      },
      "NotReady": {
        "description": "The service cannot accept traffic yet.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "SyncProtocol": {
        "description": "The sync protocol versions that this server serves.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SyncProtocolReport"
            }
          }
        }
      },
      "BadRequest": {
        "description": "The request did not match the contract.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "ServerError": {
        "description": "The service failed to complete the request.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "The request carries no usable session.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "Forbidden": {
        "description": "The actor may not perform this operation.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "NotFound": {
        "description": "The requested resource does not exist.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "PayloadTooLarge": {
        "description": "The request body is larger than the configured limit. A save of a note adds document_too_large, which means that the update or the document it would produce passes a bound of the workspace. The work stays on the device, which offers recovery rather than sending the same bytes again.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "RequestTimeout": {
        "description": "The request body stopped arriving before the operation could read all of it, so the operation did nothing.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "UnsupportedMediaType": {
        "description": "The request media type is not supported.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Too many requests. Too many attempts were made in a short time, the account runs its limit of archive jobs, or the account or the installation downloaded the most bytes or read the most objects that one calendar month in UTC allows (record 0193). The code names the cause: rate_limited, archive_job_running or download_limit. Nothing changed.",
        "headers": {
          "retry-after": {
            "description": "The seconds after which the caller may try again.",
            "schema": {
              "type": "string",
              "maxLength": 16
            }
          },
          "notesapp-limit": {
            "description": "The limit of the month that refused the request, on the codes download_limit and storage_busy only, so the answer of a HEAD request names it too (record 0193).",
            "schema": {
              "$ref": "#/components/schemas/UsageLimit"
            }
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "ServiceBusy": {
        "description": "The service cannot do this work now: it runs as many jobs of this kind as it can, a failure of the service stopped the work, or the object store of the installation took the most writes that one calendar month in UTC allows (record 0193). The code names the cause, for example storage_busy. Nothing changed.",
        "headers": {
          "retry-after": {
            "description": "The seconds after which the caller may try again.",
            "schema": {
              "type": "string",
              "maxLength": 16
            }
          },
          "notesapp-limit": {
            "description": "The limit of the month that refused the request, on the codes download_limit and storage_busy only, so the answer of a HEAD request names it too (record 0193).",
            "schema": {
              "$ref": "#/components/schemas/UsageLimit"
            }
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "WorkspaceArchivePlanned": {
        "description": "The workspace can be exported now. The answer states the exact length of its archive and its download name, and carries no body.",
        "headers": {
          "content-length": {
            "description": "The exact length of the archive in bytes.",
            "schema": {
              "type": "string",
              "maxLength": 16
            }
          },
          "content-disposition": {
            "description": "The download name of the archive.",
            "schema": {
              "type": "string",
              "maxLength": 1024
            }
          }
        }
      },
      "InsufficientStorage": {
        "description": "The storage of the server has no room for this request body now.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "Account": {
        "description": "The signed in account and its settings.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Account"
            }
          }
        }
      },
      "Preferences": {
        "description": "The stored settings of the signed in account.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Preferences"
            }
          }
        }
      },
      "DailyNoteSettings": {
        "description": "The stored daily note settings of the signed in member.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/DailyNoteSettings"
            }
          }
        }
      },
      "TemplateSettings": {
        "description": "The stored template settings of the signed in member.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/TemplateSettings"
            }
          }
        }
      },
      "Workspace": {
        "description": "One workspace of the signed in account.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Workspace"
            }
          }
        }
      },
      "WorkspaceList": {
        "description": "Every workspace of the signed in account.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/WorkspaceList"
            }
          }
        }
      },
      "Removed": {
        "description": "The named record no longer exists.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Removed"
            }
          }
        }
      },
      "Conflict": {
        "description": "The change cannot be accepted next to the state that the workspace holds. The code names the reason: path_conflict for a path that another live file occupies, and mutation_reused for a mutation identity that was already used for another operation. A save of a note adds epoch_mismatch, which means that the note holds another generation of its document, so the device reads the current document before it saves again.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "Gone": {
        "description": "The file identifier was permanently purged. It can never be written again, so a late offline change must be recovered into a new file.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "PreconditionFailed": {
        "description": "An expected head does not match the accepted head. The fileIds member names every file that moved on, so the client can resolve them.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "PreconditionRequired": {
        "description": "The operation needs a precondition and the request carried none. Repeat the request with the entity tag of the head that was read.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "UnprocessableContent": {
        "description": "The request is well formed but its content cannot be accepted. The code names the reason: invalid_path, invalid_graph, invalid_content, or too_many_files. A save of a note adds document_malformed for bytes that are not an update, document_dependency_missing for work that names an insertion or a deletion the document lacks, and document_unsupported for work that writes anything other than the text of the note, and unrenderable_note for a note over a limit of the Markdown grammar, with the limit in noteRefusal. Each of them leaves the accepted state exactly as it was.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "NotModified": {
        "description": "The entity tag in the request names the current head, so the answer carries no body."
      },
      "File": {
        "description": "One live file and the content of its accepted head.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/WorkspaceFile"
            }
          }
        }
      },
      "FileList": {
        "description": "One page of the live files of a workspace.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/WorkspaceFileList"
            }
          }
        }
      },
      "DeletedFileList": {
        "description": "One page of the deleted files of a workspace.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/WorkspaceDeletedFileList"
            }
          }
        }
      },
      "SearchResults": {
        "description": "Accepted live notes that match the search query.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SearchResults"
            }
          }
        }
      },
      "BacklinkList": {
        "description": "Live notes that link to one file path.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/BacklinkList"
            }
          }
        }
      },
      "FileChange": {
        "description": "The accepted revision and the outcome of its changeset.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/FileChange"
            }
          }
        }
      },
      "Revision": {
        "description": "One immutable revision of a workspace.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/FileRevision"
            }
          }
        }
      },
      "AcceptedChangeset": {
        "description": "The outcome of one accepted changeset.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AcceptedChangeset"
            }
          }
        }
      },
      "AttachmentUploaded": {
        "description": "The uploaded temporary attachment object and its verified digest.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AttachmentUploadResult"
            }
          }
        }
      },
      "NoteMarkdown": {
        "description": "The accepted head of one note as a Markdown file.",
        "headers": {
          "content-disposition": {
            "description": "Names the download and asks the client to save it rather than to show it.",
            "schema": {
              "type": "string",
              "maxLength": 1024
            }
          }
        },
        "content": {
          "text/markdown": {
            "schema": {
              "type": "string",
              "format": "binary"
            }
          }
        }
      },
      "WorkspaceArchive": {
        "description": "A zip archive of every live note and its attachments.",
        "headers": {
          "content-disposition": {
            "description": "Names the download and asks the client to save it rather than to show it.",
            "schema": {
              "type": "string",
              "maxLength": 1024
            }
          }
        },
        "content": {
          "application/zip": {
            "schema": {
              "type": "string",
              "format": "binary"
            }
          }
        }
      },
      "WorkspaceImported": {
        "description": "Counts of the files read from one portable archive.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ImportWorkspaceResult"
            }
          }
        }
      },
      "WorkspaceImportStarted": {
        "description": "The import upload and the size of each of its parts.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/WorkspaceImportStarted"
            }
          }
        }
      },
      "WorkspaceImportPartReceived": {
        "description": "The part that the server stored.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/WorkspaceImportPartReceived"
            }
          }
        }
      },
      "AttachmentBinary": {
        "description": "Binary bytes of the immutable attachment.",
        "headers": {
          "content-disposition": {
            "description": "Names the file and states what the client does with the bytes. An image of an accepted type is shown, and every other type is saved.",
            "schema": {
              "type": "string",
              "maxLength": 1024
            }
          }
        },
        "content": {
          "image/png": {
            "schema": {
              "type": "string",
              "format": "binary"
            }
          },
          "image/jpeg": {
            "schema": {
              "type": "string",
              "format": "binary"
            }
          },
          "image/gif": {
            "schema": {
              "type": "string",
              "format": "binary"
            }
          },
          "image/webp": {
            "schema": {
              "type": "string",
              "format": "binary"
            }
          }
        }
      },
      "HistoryPage": {
        "description": "One page of file history revisions.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/HistoryPage"
            }
          }
        }
      },
      "PurgePreview": {
        "description": "Preview of permanent file purge.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/PurgePreview"
            }
          }
        }
      },
      "PurgedFiles": {
        "description": "Outcome of executed permanent file purge.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/PurgedFiles"
            }
          }
        }
      },
      "SnapshotStarted": {
        "description": "The captured snapshot and its opaque page token.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SnapshotStarted"
            }
          }
        }
      },
      "SnapshotPage": {
        "description": "One page of the items that a snapshot captured.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SnapshotPage"
            }
          }
        }
      },
      "MutationReceipt": {
        "description": "What the workspace knows about one mutation identity.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/MutationReceipt"
            }
          }
        }
      },
      "SyncChanges": {
        "description": "Ordered incremental changes after a cursor.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SyncChanges"
            }
          }
        }
      },
      "SyncProtocolUnsupported": {
        "description": "This deployment does not serve the sync protocol version of the caller. The code is sync_protocol_unsupported. The request changed nothing, so the caller keeps its work, reads the served versions, and sends again after it holds a version that this deployment serves.",
        "headers": {
          "Retry-After": {
            "description": "Seconds to wait before the caller asks again.",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "SyncNoticesOpened": {
        "description": "The server switched the connection to the notice stream. The messages of the stream are in `asyncapi.yaml`."
      },
      "SyncNoticesUnavailable": {
        "description": "This deployment does not open the notice stream now. The code is notices_unavailable. The client keeps its work, reads the feed on its own schedule, and tries the stream again later.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "SnapshotRequired": {
        "description": "The snapshot expired, is unknown, was invalidated by a purge, or the sync cursor predates the retained 90 day window. The code is snapshot_required. The client starts a fresh snapshot and keeps its local work.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "PublishedLinkCreated": {
        "description": "The new link and its token. This answer shows the token once, and no later answer holds it.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/PublishedLinkCreated"
            }
          }
        }
      },
      "PublishedLinkList": {
        "description": "Every published link of the workspace, without a token.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/PublishedLinkList"
            }
          }
        }
      },
      "ReadingTicketGranted": {
        "description": "The reading ticket of the link.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ReadingTicketGrant"
            }
          }
        }
      },
      "PublishedLinkUnavailable": {
        "description": "The link is not available. Every reader operation answers this one shape for a link that never existed, a revoked link, an expired link and a wrong password, so the four causes read alike.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/PublishedRefusal"
            }
          }
        }
      },
      "PublishedPage": {
        "description": "The published page, as one HTML document.",
        "headers": {
          "cache-control": {
            "description": "States that the page belongs to this reader. No shared cache stores it.",
            "schema": {
              "type": "string",
              "maxLength": 256
            }
          }
        },
        "content": {
          "text/html": {
            "schema": {
              "$ref": "#/components/schemas/PublishedDocument"
            }
          }
        }
      },
      "LegalPage": {
        "description": "The legal document, as one HTML document.",
        "headers": {
          "cache-control": {
            "description": "States that the browser checks the page again each time and that no shared cache stores it. The document changes only when the server starts again.",
            "schema": {
              "type": "string",
              "maxLength": 256
            }
          }
        },
        "content": {
          "text/html": {
            "schema": {
              "$ref": "#/components/schemas/LegalPageDocument"
            }
          }
        }
      },
      "AccountList": {
        "description": "Every account of the installation.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AccountList"
            }
          }
        }
      },
      "AccountSummary": {
        "description": "One account as an administrator sees it.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AccountSummary"
            }
          }
        }
      },
      "InvitationList": {
        "description": "The invitations that wait.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/InvitationList"
            }
          }
        }
      },
      "SignUpAccepted": {
        "description": "The sign-up was taken. A message goes to the address.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SignUpAccepted"
            }
          }
        }
      },
      "SignUpChallenge": {
        "description": "One challenge for the proof of work of a sign-up.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SignUpChallenge"
            }
          }
        }
      },
      "ConsentRecorded": {
        "description": "The consent is stored.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ConsentRecorded"
            }
          }
        }
      },
      "AddressVerified": {
        "description": "The address is proved and the account exists.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AddressVerified"
            }
          }
        }
      },
      "VerificationUnavailable": {
        "description": "The verification link opens nothing. The code is verification_invalid for a token that expired, that a later sign-up replaced, or that never existed. The answer does not say which. The code is registration_closed when the installation stopped open registration after the sign-up.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "LinkReportList": {
        "description": "The open reports of published links.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/LinkReportList"
            }
          }
        }
      },
      "InvitationCreated": {
        "description": "The new invitation.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/InvitationCreated"
            }
          }
        }
      },
      "InvitationAddress": {
        "description": "The address that the invitation binds.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/InvitationAddress"
            }
          }
        }
      },
      "Registered": {
        "description": "The account exists and its session started.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Registered"
            }
          }
        }
      },
      "Installation": {
        "description": "The settings of the installation.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Installation"
            }
          }
        }
      },
      "SettingConflict": {
        "description": "The setting cannot change now. The code is setting_locked when the server environment sets it, and setting_required when open registration needs it. Nothing changed.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "MailFailed": {
        "description": "The test message did not go. The code is mail_failed, and the reason member names the kind of the failure.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "MailTestSent": {
        "description": "The test message went to the mail server.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/MailTestSent"
            }
          }
        }
      },
      "LegalDocumentUnfinished": {
        "description": "The text still holds a blank of the template. The code is legal_document_unfinished, and the blanks member lists each one. Nothing changed.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "LegalDocumentSettings": {
        "description": "One legal document as the administrator changes it.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/LegalDocumentSettings"
            }
          }
        }
      },
      "LastAdministrator": {
        "description": "The change would leave the installation with no enabled administrator. The code is last_administrator. Nothing changed.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "ThemeLimit": {
        "description": "The account already keeps as many imported themes as it may. The code is theme_limit. Nothing changed.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "InvitationUnavailable": {
        "description": "The invitation opens nothing. The code is invitation_invalid for a token that expired, that somebody used, that an administrator revoked, or that never existed. The answer does not say which.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "OpenRegistrationUnavailable": {
        "description": "The installation cannot take open registration yet. The code is open_registration_unavailable, and the missing member lists each part that the installation lacks.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "InvitationRefused": {
        "description": "The address cannot take an invitation. The code is account_exists when an account already signs in with that address.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "AccountSessionList": {
        "description": "Every session of the signed in account.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AccountSessionList"
            }
          }
        }
      },
      "SessionsRevoked": {
        "description": "How many sessions ended.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SessionsRevoked"
            }
          }
        }
      },
      "AccountLocked": {
        "description": "The account is locked, and a locked account keeps only a fixed list of operations (record 0201). The code is account_locked. Nothing changed.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "OperatorOff": {
        "description": "The installation names no operator token, so the operator API is off (record 0190). The code is operator_off.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "OperatorNotFound": {
        "description": "The operator API is off, with the code operator_off, or the request names no account or no valid handoff, with the code not_found.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "ControlsChanged": {
        "description": "The controls changed after the revision that the write names. The code is controls_changed. Nothing changed, and the writer reads the controls again.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "AccountChangeConflict": {
        "description": "The change would leave the installation with no enabled administrator, with the code last_administrator, or the controls changed after the revision that the change names, with the code controls_changed. Nothing changed.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "OperatorAccount": {
        "description": "One account as a service of the operator reads it.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/OperatorAccount"
            }
          }
        }
      },
      "OperatorTotals": {
        "description": "The totals of the installation for one month.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/OperatorTotals"
            }
          }
        }
      },
      "AccountEventList": {
        "description": "The account events after a cursor.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AccountEventList"
            }
          }
        }
      },
      "HandoffAccount": {
        "description": "The account that opened the portal.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/HandoffAccount"
            }
          }
        }
      },
      "PortalAddress": {
        "description": "The address that opens the account portal.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/PortalAddress"
            }
          }
        }
      }
    },
    "schemas": {
      "AcceptedChangeset": {
        "type": "object",
        "description": "The outcome of one accepted changeset.",
        "additionalProperties": false,
        "required": [
          "mutationId",
          "revisionIds",
          "cursor",
          "revisions",
          "superseded"
        ],
        "properties": {
          "mutationId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "The mutation identity that the client submitted."
          },
          "revisionIds": {
            "type": "array",
            "readOnly": true,
            "description": "Every revision that this changeset accepted, in submitted order. A retry of the same mutation returns exactly these identifiers again.",
            "minItems": 1,
            "maxItems": 4000,
            "items": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          "cursor": {
            "type": "string",
            "readOnly": true,
            "description": "The commit ordered position of this change in the workspace. A sync client asks for changes after a cursor it already applied.",
            "minLength": 1,
            "maxLength": 32,
            "pattern": "^[0-9]+$"
          },
          "revisions": {
            "type": "array",
            "readOnly": true,
            "description": "Every accepted revision with the values that the workspace assigned. A client applies these without reading the workspace again, and a retry of the same mutation repeats them.",
            "minItems": 1,
            "maxItems": 4000,
            "items": {
              "$ref": "#/components/schemas/AcceptedRevision"
            }
          },
          "superseded": {
            "type": "array",
            "readOnly": true,
            "description": "Every file whose accepted head this changeset rebased, empty for the normal case. A client shows the person that a save from another device is now only in the history of the file.",
            "maxItems": 4000,
            "items": {
              "$ref": "#/components/schemas/SupersededHead"
            }
          }
        }
      },
      "AcceptedRevision": {
        "type": "object",
        "description": "One revision as the workspace accepted it. The record carries the values that the workspace assigned, and no note text: the client that wrote the revision already holds its content, and an actor that may write but not read must not receive content through a write answer.",
        "additionalProperties": false,
        "required": [
          "revisionId",
          "fileId",
          "parents",
          "path",
          "deleted",
          "digest",
          "size",
          "actorAccountId",
          "serverTime",
          "message",
          "epoch",
          "acceptedState",
          "merged"
        ],
        "properties": {
          "revisionId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "Identifier of the accepted revision."
          },
          "fileId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "The file that the revision belongs to."
          },
          "parents": {
            "type": "array",
            "readOnly": true,
            "description": "The parents of the revision, in submitted order.",
            "maxItems": 2,
            "items": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          "path": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FilePath"
              }
            ],
            "readOnly": true,
            "description": "The accepted path, in its normalized form."
          },
          "deleted": {
            "type": "boolean",
            "readOnly": true,
            "description": "True for a tombstone, which is how a deletion is recorded."
          },
          "digest": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ContentDigest"
              }
            ],
            "readOnly": true,
            "description": "Digest of the content of the revision."
          },
          "size": {
            "type": "integer",
            "readOnly": true,
            "description": "Size of the content in bytes.",
            "minimum": 0
          },
          "actorAccountId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "The account that the workspace recorded as the author. It comes from the verified request; a client cannot supply it."
          },
          "serverTime": {
            "type": "string",
            "readOnly": true,
            "description": "Instant at which the workspace accepted the revision.",
            "format": "date-time",
            "maxLength": 64
          },
          "message": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CheckpointMessage"
              }
            ],
            "readOnly": true,
            "description": "The checkpoint name of the revision, or null."
          },
          "epoch": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DocumentEpoch"
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "The generation of the document that this revision holds, or null for an attachment revision."
          },
          "acceptedState": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DocumentObservedState"
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "The complete state of the document after acceptance. It states identities and deletions, and it holds no note text, so an actor that may write and not read learns nothing from it. Absent for an attachment revision, where it is null."
          },
          "merged": {
            "type": "boolean",
            "readOnly": true,
            "description": "True when this save joined work that the device had not seen. The device that saved keeps the checkpoint of that save for Review, and every device marks the revision in History."
          }
        }
      },
      "Account": {
        "type": "object",
        "description": "The signed in account and its settings.",
        "additionalProperties": false,
        "required": [
          "accountId",
          "installationRole",
          "storage",
          "preferences",
          "consentRequired",
          "controls",
          "month",
          "accountPortal"
        ],
        "properties": {
          "accountId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "Stable identifier of the account inside this deployment."
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "readOnly": true,
            "description": "Sign-in address, or null when no address is linked.",
            "maxLength": 320
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "readOnly": true,
            "description": "Display name, or null when no name is stored.",
            "maxLength": 256
          },
          "installationRole": {
            "allOf": [
              {
                "$ref": "#/components/schemas/InstallationRole"
              }
            ],
            "readOnly": true,
            "description": "The role of the account in the installation."
          },
          "storage": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountStorage"
              }
            ],
            "readOnly": true,
            "description": "The usage and the limit of the account."
          },
          "preferences": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Preferences"
              }
            ],
            "readOnly": true,
            "description": "The stored settings of the account."
          },
          "consentRequired": {
            "type": "boolean",
            "readOnly": true,
            "description": "Whether the account must accept the current legal documents before the application opens (record 0120)."
          },
          "controls": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountControls"
              }
            ],
            "readOnly": true,
            "description": "The controls of the account (record 0189). A locked account opens one screen, which names the way to unlock it (record 0201)."
          },
          "month": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountMonth"
              }
            ],
            "readOnly": true,
            "description": "The transfer of the current month and each limit that holds the account now (record 0193)."
          },
          "accountPortal": {
            "type": "boolean",
            "readOnly": true,
            "description": "Whether the installation names an account portal, which openAccountPortal opens (record 0190)."
          }
        }
      },
      "AccountControls": {
        "type": "object",
        "description": "The controls of one account and their revision (record 0189). With no setting of the operator, an account is active, has every feature, and has no text, transfer or download limit.",
        "additionalProperties": false,
        "required": [
          "revision",
          "standing",
          "removalAt",
          "limitBytes",
          "textLimitBytes",
          "publishedTransferLimitBytes",
          "downloadLimitBytes",
          "features"
        ],
        "properties": {
          "revision": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ControlRevision"
              }
            ],
            "readOnly": true,
            "description": "The revision of these controls."
          },
          "standing": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountStanding"
              }
            ],
            "readOnly": true,
            "description": "Whether the account is active or locked."
          },
          "removalAt": {
            "oneOf": [
              {
                "type": "string",
                "format": "date-time",
                "maxLength": 64
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "The instant after which the daily run removes a locked account, or null. Only a locked account has one (record 0201)."
          },
          "limitBytes": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ByteCount"
              }
            ],
            "readOnly": true,
            "description": "The most bytes that the workspaces of the account can use (record 0112)."
          },
          "textLimitBytes": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ByteLimit"
              }
            ],
            "readOnly": true,
            "description": "The most bytes of text and history that the workspaces of the account can use, inside the storage limit, or null for no limit."
          },
          "publishedTransferLimitBytes": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ByteLimit"
              }
            ],
            "readOnly": true,
            "description": "The most bytes that the published pages of the account send in one calendar month in UTC, or null for no limit (record 0193)."
          },
          "downloadLimitBytes": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ByteLimit"
              }
            ],
            "readOnly": true,
            "description": "The most bytes that the account downloads in one calendar month in UTC, or null for no limit (record 0193)."
          },
          "features": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountFeatures"
              }
            ],
            "readOnly": true,
            "description": "The switch of each switchable feature."
          }
        }
      },
      "AccountControlsInput": {
        "type": "object",
        "description": "A change of the controls of one account (record 0189). The write names the revision that it read, and the server refuses it with 409 and the code controls_changed when the stored revision differs, so nothing changes. A member that is absent keeps its stored value. Setting the standing to active clears the removal time, and only a locked account can have one.",
        "additionalProperties": false,
        "required": [
          "revision"
        ],
        "minProperties": 2,
        "properties": {
          "revision": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ControlRevision"
              }
            ],
            "writeOnly": true,
            "description": "The revision of the controls that the writer read."
          },
          "standing": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountStanding"
              }
            ],
            "writeOnly": true,
            "description": "The new standing."
          },
          "removalAt": {
            "oneOf": [
              {
                "type": "string",
                "format": "date-time",
                "maxLength": 64
              },
              {
                "type": "null"
              }
            ],
            "writeOnly": true,
            "description": "The new removal time of a locked account, or null for none."
          },
          "limitBytes": {
            "type": "integer",
            "writeOnly": true,
            "description": "The new storage limit, in bytes.",
            "minimum": 1,
            "maximum": 9007199254740991
          },
          "textLimitBytes": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ByteLimit"
              }
            ],
            "writeOnly": true,
            "description": "The new text limit, in bytes, or null for no limit."
          },
          "publishedTransferLimitBytes": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ByteLimit"
              }
            ],
            "writeOnly": true,
            "description": "The new published transfer limit of one month, in bytes, or null for no limit."
          },
          "downloadLimitBytes": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ByteLimit"
              }
            ],
            "writeOnly": true,
            "description": "The new download limit of one month, in bytes, or null for no limit."
          },
          "features": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountFeaturesInput"
              }
            ],
            "writeOnly": true,
            "description": "The feature switches to change."
          }
        }
      },
      "AccountEvent": {
        "type": "object",
        "description": "One account event. It names the account and nothing else of it.",
        "additionalProperties": false,
        "required": [
          "cursor",
          "accountId",
          "kind",
          "occurredAt"
        ],
        "properties": {
          "cursor": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountEventCursor"
              }
            ],
            "readOnly": true,
            "description": "The position of the event."
          },
          "accountId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "Identifier of the account."
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountEventKind"
              }
            ],
            "readOnly": true,
            "description": "What happened."
          },
          "occurredAt": {
            "type": "string",
            "readOnly": true,
            "description": "Instant at which it happened.",
            "format": "date-time",
            "maxLength": 64
          }
        }
      },
      "AccountEventCursor": {
        "type": "integer",
        "description": "The position of one account event. The positions follow the order in which the events committed, so a reader that continues after the last one that it read misses no event.",
        "minimum": 0,
        "maximum": 9007199254740991
      },
      "AccountEventKind": {
        "type": "string",
        "description": "What happened to an account (record 0190).",
        "enum": [
          "made",
          "verified",
          "removed"
        ]
      },
      "AccountEventList": {
        "type": "object",
        "description": "The account events after a cursor, oldest first, and the cursor to read after next.",
        "additionalProperties": false,
        "required": [
          "events",
          "cursor"
        ],
        "properties": {
          "events": {
            "type": "array",
            "readOnly": true,
            "description": "The events, oldest first.",
            "maxItems": 500,
            "items": {
              "$ref": "#/components/schemas/AccountEvent"
            }
          },
          "cursor": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountEventCursor"
              }
            ],
            "readOnly": true,
            "description": "The position of the last event of the answer, or the position that the request named when the answer holds none."
          }
        }
      },
      "AccountFeatures": {
        "type": "object",
        "description": "The switch of each feature that a later design makes switchable (record 0189). Every switch is on by default, and a self-hosted installation never needs to turn one off.",
        "additionalProperties": false,
        "required": [
          "teams",
          "collaboration"
        ],
        "properties": {
          "teams": {
            "type": "boolean",
            "readOnly": true,
            "description": "Whether the account can use teams."
          },
          "collaboration": {
            "type": "boolean",
            "readOnly": true,
            "description": "Whether the account can use collaboration."
          }
        }
      },
      "AccountFeaturesInput": {
        "type": "object",
        "description": "The feature switches that a write changes. A member that is absent keeps its stored value.",
        "additionalProperties": false,
        "minProperties": 1,
        "properties": {
          "teams": {
            "type": "boolean",
            "writeOnly": true,
            "description": "Whether the account can use teams."
          },
          "collaboration": {
            "type": "boolean",
            "writeOnly": true,
            "description": "Whether the account can use collaboration."
          }
        }
      },
      "AccountList": {
        "type": "object",
        "description": "Every account of the installation.",
        "additionalProperties": false,
        "required": [
          "accounts"
        ],
        "properties": {
          "accounts": {
            "type": "array",
            "readOnly": true,
            "description": "The accounts, in the order in which they were made.",
            "maxItems": 10000,
            "items": {
              "$ref": "#/components/schemas/AccountSummary"
            }
          }
        }
      },
      "AccountMonth": {
        "type": "object",
        "description": "What the account sent in the current calendar month in UTC, and each limit of record 0193 that holds it now. A state is true past the limit of the account or past the cap of the installation, and it holds until endsAt.",
        "additionalProperties": false,
        "required": [
          "month",
          "endsAt",
          "publishedTransferBytes",
          "downloadBytes",
          "publishedPagesClosed",
          "downloadsPaused",
          "uploadsPaused",
          "imagesPaused"
        ],
        "properties": {
          "month": {
            "allOf": [
              {
                "$ref": "#/components/schemas/UsageMonth"
              }
            ],
            "readOnly": true,
            "description": "The month of the counts."
          },
          "endsAt": {
            "type": "string",
            "format": "date-time",
            "maxLength": 64,
            "readOnly": true,
            "description": "The first instant of the next month in UTC, when every count starts again from zero."
          },
          "publishedTransferBytes": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ByteCount"
              }
            ],
            "readOnly": true,
            "description": "The bytes that the published pages of the account sent in the month."
          },
          "downloadBytes": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ByteCount"
              }
            ],
            "readOnly": true,
            "description": "The bytes that the account downloaded in the month."
          },
          "publishedPagesClosed": {
            "type": "boolean",
            "readOnly": true,
            "description": "Whether each published link of the account answers the closed page, past its published transfer limit or the published transfer cap of the installation."
          },
          "downloadsPaused": {
            "type": "boolean",
            "readOnly": true,
            "description": "Whether an export, an attachment and a sync snapshot answer download_limit, past the download limit of the account or the download cap of the installation."
          },
          "uploadsPaused": {
            "type": "boolean",
            "readOnly": true,
            "description": "Whether an upload and an import answer storage_busy, past the object write cap of the installation."
          },
          "imagesPaused": {
            "type": "boolean",
            "readOnly": true,
            "description": "Whether an attachment answers download_limit and a published page shows no image, past the object read cap of the installation."
          }
        }
      },
      "AccountRemovalInput": {
        "type": "object",
        "description": "The password of the account that removes itself.",
        "additionalProperties": false,
        "required": [
          "password"
        ],
        "properties": {
          "password": {
            "type": "string",
            "description": "The current password of the account.",
            "minLength": 1,
            "maxLength": 512,
            "writeOnly": true
          }
        }
      },
      "AccountSession": {
        "type": "object",
        "description": "One session of the signed in account, on one device. It holds no token, so a read of the list opens no session.",
        "additionalProperties": false,
        "required": [
          "sessionId",
          "current",
          "userAgent",
          "createdAt",
          "lastActiveAt",
          "expiresAt"
        ],
        "properties": {
          "sessionId": {
            "type": "string",
            "readOnly": true,
            "description": "Identifier of the session. It is not the token.",
            "minLength": 1,
            "maxLength": 128
          },
          "current": {
            "type": "boolean",
            "readOnly": true,
            "description": "True for the session of the device that reads the list."
          },
          "userAgent": {
            "type": [
              "string",
              "null"
            ],
            "readOnly": true,
            "description": "What the browser of the session said it is, or null when it said nothing.",
            "maxLength": 512
          },
          "createdAt": {
            "type": "string",
            "readOnly": true,
            "description": "Instant at which the session started.",
            "format": "date-time",
            "maxLength": 64
          },
          "lastActiveAt": {
            "type": "string",
            "readOnly": true,
            "description": "Instant at which the session was last used.",
            "format": "date-time",
            "maxLength": 64
          },
          "expiresAt": {
            "type": "string",
            "readOnly": true,
            "description": "Instant at which the session ends if nobody uses it.",
            "format": "date-time",
            "maxLength": 64
          }
        }
      },
      "AccountSessionList": {
        "type": "object",
        "description": "Every session of the signed in account.",
        "additionalProperties": false,
        "required": [
          "sessions"
        ],
        "properties": {
          "sessions": {
            "type": "array",
            "readOnly": true,
            "description": "The sessions, the current one first, then newest first.",
            "maxItems": 1000,
            "items": {
              "$ref": "#/components/schemas/AccountSession"
            }
          }
        }
      },
      "AccountStanding": {
        "type": "string",
        "description": "The standing of an account (record 0189). An active account uses every operation. A locked account keeps a fixed list of operations, and every other operation answers 423 with the code account_locked (record 0201).",
        "enum": [
          "active",
          "locked"
        ]
      },
      "AccountState": {
        "type": "string",
        "description": "Whether an account can sign in. A disabled account keeps its notes and gets no session.",
        "enum": [
          "enabled",
          "disabled"
        ]
      },
      "AccountStorage": {
        "type": "object",
        "description": "The bytes that the workspaces of one account use, and the limit of that account. The owner of a workspace pays for every byte in it.",
        "additionalProperties": false,
        "required": [
          "usedBytes",
          "limitBytes"
        ],
        "properties": {
          "usedBytes": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ByteCount"
              }
            ],
            "readOnly": true,
            "description": "The bytes that the workspaces of the account use."
          },
          "limitBytes": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ByteCount"
              }
            ],
            "readOnly": true,
            "description": "The most bytes that the workspaces of the account can use."
          }
        }
      },
      "AccountSummary": {
        "type": "object",
        "description": "One account as an administrator sees it. It holds no note and no workspace of the account.",
        "additionalProperties": false,
        "required": [
          "accountId",
          "email",
          "name",
          "installationRole",
          "state",
          "createdAt",
          "lastActiveAt",
          "storage",
          "controls",
          "self"
        ],
        "properties": {
          "accountId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "Identifier of the account."
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "readOnly": true,
            "description": "Sign-in address of the account.",
            "maxLength": 320
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "readOnly": true,
            "description": "Display name of the account.",
            "maxLength": 256
          },
          "installationRole": {
            "allOf": [
              {
                "$ref": "#/components/schemas/InstallationRole"
              }
            ],
            "readOnly": true,
            "description": "The role of the account in the installation."
          },
          "state": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountState"
              }
            ],
            "readOnly": true,
            "description": "Whether the account can sign in."
          },
          "createdAt": {
            "type": "string",
            "readOnly": true,
            "description": "Instant at which the account was made.",
            "format": "date-time",
            "maxLength": 64
          },
          "lastActiveAt": {
            "oneOf": [
              {
                "type": "string",
                "format": "date-time",
                "maxLength": 64
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "The last instant at which a session of the account was used, or null when the account has no session."
          },
          "storage": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountStorage"
              }
            ],
            "readOnly": true,
            "description": "The usage and the limit of the account."
          },
          "controls": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountControls"
              }
            ],
            "readOnly": true,
            "description": "The controls of the account and their revision (record 0189)."
          },
          "self": {
            "type": "boolean",
            "readOnly": true,
            "description": "True for the account that reads the list."
          }
        }
      },
      "AccountUpdateInput": {
        "type": "object",
        "description": "The facts of an account that an administrator changes. A member that is absent keeps its stored value.",
        "additionalProperties": false,
        "minProperties": 1,
        "properties": {
          "installationRole": {
            "allOf": [
              {
                "$ref": "#/components/schemas/InstallationRole"
              }
            ],
            "description": "The new role of the account in the installation."
          },
          "state": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountState"
              }
            ],
            "description": "The new state. A disabled account loses every session and gets no new one."
          },
          "limitBytes": {
            "type": "integer",
            "description": "The new limit of the account, in bytes.",
            "minimum": 1,
            "maximum": 9007199254740991
          },
          "controls": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountControlsInput"
              }
            ],
            "description": "A change of the controls, with the revision that the administrator read (record 0189). It cannot name a storage limit together with limitBytes."
          }
        }
      },
      "AccountUsage": {
        "type": "object",
        "description": "What one account uses: the stored bytes, the part of them that is text and history, and the transfer of the current month in UTC (record 0193).",
        "additionalProperties": false,
        "required": [
          "usedBytes",
          "textBytes",
          "month",
          "publishedTransferBytes",
          "downloadBytes"
        ],
        "properties": {
          "usedBytes": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ByteCount"
              }
            ],
            "readOnly": true,
            "description": "The bytes that the workspaces of the account use."
          },
          "textBytes": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ByteCount"
              }
            ],
            "readOnly": true,
            "description": "The part of the used bytes that is text and history."
          },
          "month": {
            "allOf": [
              {
                "$ref": "#/components/schemas/UsageMonth"
              }
            ],
            "readOnly": true,
            "description": "The month of the two transfer counts."
          },
          "publishedTransferBytes": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ByteCount"
              }
            ],
            "readOnly": true,
            "description": "The bytes that the published pages of the account sent in the month."
          },
          "downloadBytes": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ByteCount"
              }
            ],
            "readOnly": true,
            "description": "The bytes that the account downloaded in the month."
          }
        }
      },
      "AddressVerificationInput": {
        "type": "object",
        "description": "The token that a verification link carries in its fragment.",
        "additionalProperties": false,
        "required": [
          "token"
        ],
        "properties": {
          "token": {
            "type": "string",
            "description": "The token of the verification link.",
            "minLength": 1,
            "maxLength": 512,
            "pattern": "^[A-Za-z0-9_.-]+$"
          }
        }
      },
      "AddressVerified": {
        "type": "object",
        "description": "The address that the verification proved. Its account now exists.",
        "additionalProperties": false,
        "required": [
          "email"
        ],
        "properties": {
          "email": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EmailAddress"
              }
            ],
            "readOnly": true,
            "description": "The address of the new account, which signs in now."
          }
        }
      },
      "ApiKey": {
        "type": "object",
        "description": "One key of the account. No secret or digest is included.",
        "additionalProperties": false,
        "required": [
          "keyId",
          "name",
          "createdAt",
          "expiresAt",
          "lastUsedAt"
        ],
        "properties": {
          "keyId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "Identifier used to revoke the key. It is not the secret."
          },
          "name": {
            "type": "string",
            "readOnly": true,
            "description": "Name of the program that uses the key.",
            "minLength": 1,
            "maxLength": 80
          },
          "createdAt": {
            "type": "string",
            "readOnly": true,
            "description": "Time when the key was made.",
            "format": "date-time",
            "maxLength": 64
          },
          "expiresAt": {
            "type": "string",
            "readOnly": true,
            "description": "Time after which the key is refused.",
            "format": "date-time",
            "maxLength": 64
          },
          "lastUsedAt": {
            "type": [
              "string",
              "null"
            ],
            "readOnly": true,
            "description": "Last use of the key, or null when it has not been used.",
            "format": "date-time",
            "maxLength": 64
          }
        }
      },
      "ApiKeyCreateInput": {
        "type": "object",
        "description": "The name and lifetime of a full account key.",
        "additionalProperties": false,
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "writeOnly": true,
            "description": "Name of the program. Use no leading or trailing space.",
            "minLength": 1,
            "maxLength": 80,
            "pattern": "^(?!.*[\\p{Cc}\\p{Cf}\\u2028\\u2029])\\S(?:[\\s\\S]*\\S)?$"
          },
          "expiresInDays": {
            "type": "integer",
            "writeOnly": true,
            "description": "Lifetime in whole days. The default is 90 days.",
            "minimum": 1,
            "maximum": 365,
            "default": 90
          }
        }
      },
      "ApiKeyCreated": {
        "type": "object",
        "description": "A new key. Copy the token now. The server never shows it again.",
        "additionalProperties": false,
        "required": [
          "key",
          "token"
        ],
        "properties": {
          "key": {
            "$ref": "#/components/schemas/ApiKey"
          },
          "token": {
            "type": "string",
            "readOnly": true,
            "description": "The one secret. Send it as a bearer header through HTTPS.",
            "pattern": "^tnk_[A-Za-z0-9_-]{43}$",
            "minLength": 47,
            "maxLength": 47
          }
        }
      },
      "ApiKeyList": {
        "type": "object",
        "description": "The keys of the account, including expired keys. No token is included.",
        "additionalProperties": false,
        "required": [
          "keys"
        ],
        "properties": {
          "keys": {
            "type": "array",
            "readOnly": true,
            "description": "Keys of the account, newest first.",
            "maxItems": 25,
            "items": {
              "$ref": "#/components/schemas/ApiKey"
            }
          }
        }
      },
      "Appearance": {
        "type": "string",
        "description": "Appearance choice. The value system follows the device preference between the light and the dark variant of the chosen theme family.",
        "enum": [
          "system",
          "light",
          "dark"
        ]
      },
      "AttachmentContentInput": {
        "type": "object",
        "description": "The content of one attachment revision. It names a finalized object of the same workspace and the digest of its bytes.",
        "additionalProperties": false,
        "required": [
          "kind",
          "digest",
          "attachmentObjectId"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "description": "Names this content form.",
            "enum": [
              "attachment"
            ]
          },
          "digest": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ContentDigest"
              }
            ],
            "description": "Digest of the bytes. The server recomputes it and refuses a revision that declares another value."
          },
          "attachmentObjectId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "description": "The finalized attachment object of this revision."
          }
        }
      },
      "AttachmentUploadResult": {
        "type": "object",
        "description": "The uploaded temporary attachment object and its verified digest.",
        "additionalProperties": false,
        "required": [
          "objectId",
          "digest",
          "size",
          "mediaType",
          "width",
          "height"
        ],
        "properties": {
          "objectId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "description": "Unique identifier of the uploaded attachment object."
          },
          "digest": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ContentDigest"
              }
            ],
            "description": "SHA-256 digest of the validated image bytes."
          },
          "size": {
            "type": "integer",
            "minimum": 1,
            "description": "Size of the attachment in bytes."
          },
          "mediaType": {
            "type": "string",
            "description": "Validated MIME type of the uploaded image.",
            "enum": [
              "image/png",
              "image/jpeg",
              "image/gif",
              "image/webp"
            ]
          },
          "width": {
            "type": "integer",
            "minimum": 1,
            "description": "Width of the image in pixels."
          },
          "height": {
            "type": "integer",
            "minimum": 1,
            "description": "Height of the image in pixels."
          }
        }
      },
      "AuthCurrentSession": {
        "type": [
          "object",
          "null"
        ],
        "description": "The current session, or null when there is none.",
        "additionalProperties": true,
        "properties": {
          "user": {
            "$ref": "#/components/schemas/AuthUser"
          },
          "session": {
            "$ref": "#/components/schemas/AuthSessionRecord"
          }
        }
      },
      "AuthOutcome": {
        "type": "object",
        "description": "Whether the protocol endpoint completed its work.",
        "additionalProperties": true,
        "required": [
          "status"
        ],
        "properties": {
          "status": {
            "type": "boolean",
            "readOnly": true,
            "description": "True when the endpoint completed its work."
          }
        }
      },
      "AuthPasswordReset": {
        "type": "object",
        "description": "The new password and the token from the reset message.",
        "additionalProperties": false,
        "required": [
          "newPassword"
        ],
        "properties": {
          "newPassword": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Password"
              }
            ],
            "description": "New password of the account."
          },
          "token": {
            "type": "string",
            "description": "Token from the reset message.",
            "minLength": 1,
            "maxLength": 512
          }
        }
      },
      "AuthPasswordResetRequest": {
        "type": "object",
        "description": "The address that asks for a password reset message.",
        "additionalProperties": false,
        "required": [
          "email"
        ],
        "properties": {
          "email": {
            "type": "string",
            "description": "Sign-in address of the account.",
            "format": "email",
            "minLength": 3,
            "maxLength": 320
          }
        }
      },
      "AuthPasswordSignIn": {
        "type": "object",
        "description": "Address and password of a local account.",
        "additionalProperties": false,
        "required": [
          "email",
          "password"
        ],
        "properties": {
          "email": {
            "type": "string",
            "description": "Sign-in address of the account.",
            "format": "email",
            "minLength": 3,
            "maxLength": 320
          },
          "password": {
            "type": "string",
            "description": "Password of the account.",
            "minLength": 1,
            "maxLength": 512
          },
          "rememberMe": {
            "type": "boolean",
            "description": "Whether the session survives a browser restart."
          },
          "callbackURL": {
            "type": "string",
            "description": "Address to open after a completed sign-in.",
            "maxLength": 2048
          }
        }
      },
      "AuthSession": {
        "type": "object",
        "description": "The result of a completed sign-in. It never carries the session token: the browser already holds that value in an HttpOnly cookie, and the protocol adapter removes it from this answer.",
        "additionalProperties": true,
        "required": [
          "redirect"
        ],
        "properties": {
          "redirect": {
            "type": "boolean",
            "readOnly": true,
            "description": "Whether the caller should follow a redirect."
          },
          "token": {
            "not": {},
            "description": "Never present. The adapter removes the session token from this answer."
          },
          "url": {
            "type": "string",
            "readOnly": true,
            "description": "Address to open, when the answer asks for a redirect.",
            "maxLength": 2048
          },
          "user": {
            "$ref": "#/components/schemas/AuthUser"
          }
        }
      },
      "AuthSessionRecord": {
        "type": "object",
        "description": "The stored session of the signed in user. It never carries the session token: the browser already holds that value in an HttpOnly cookie, and the protocol adapter removes it from this answer.",
        "additionalProperties": true,
        "required": [
          "id",
          "expiresAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "readOnly": true,
            "description": "Identifier of the session record.",
            "minLength": 1,
            "maxLength": 128
          },
          "expiresAt": {
            "type": "string",
            "readOnly": true,
            "description": "Instant after which the session is refused.",
            "maxLength": 64
          },
          "token": {
            "not": {},
            "description": "Never present. The adapter removes the session token from this answer."
          }
        }
      },
      "AuthSignOut": {
        "type": "object",
        "description": "Sign-out carries no data. The session cookie names it.",
        "additionalProperties": false,
        "properties": {}
      },
      "AuthSignOutResult": {
        "type": "object",
        "description": "Whether the session was ended.",
        "additionalProperties": true,
        "required": [
          "success"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "readOnly": true,
            "description": "True when the session no longer exists."
          }
        }
      },
      "AuthUser": {
        "type": "object",
        "description": "The signed in user as the identity provider reports it.",
        "additionalProperties": true,
        "required": [
          "id",
          "email"
        ],
        "properties": {
          "id": {
            "type": "string",
            "readOnly": true,
            "description": "Identifier of the user inside the identity provider.",
            "minLength": 1,
            "maxLength": 128
          },
          "email": {
            "type": "string",
            "readOnly": true,
            "description": "Sign-in address of the user.",
            "maxLength": 320
          },
          "name": {
            "type": "string",
            "readOnly": true,
            "description": "Display name of the user.",
            "maxLength": 256
          },
          "emailVerified": {
            "type": "boolean",
            "readOnly": true,
            "description": "Whether the provider reported the address as verified."
          }
        }
      },
      "Backlink": {
        "type": "object",
        "description": "One live note that links to the requested file path.",
        "additionalProperties": false,
        "required": [
          "fileId",
          "path",
          "revisionId"
        ],
        "properties": {
          "fileId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true
          },
          "path": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FilePath"
              }
            ],
            "readOnly": true
          },
          "revisionId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true
          }
        }
      },
      "BacklinkList": {
        "type": "object",
        "description": "Live notes that link to one current file path.",
        "additionalProperties": false,
        "required": [
          "backlinks"
        ],
        "properties": {
          "backlinks": {
            "type": "array",
            "readOnly": true,
            "maxItems": 100,
            "items": {
              "$ref": "#/components/schemas/Backlink"
            }
          }
        }
      },
      "BlockingReference": {
        "type": "object",
        "description": "A reference that blocks permanent deletion.",
        "additionalProperties": false,
        "required": [
          "kind",
          "targetId",
          "referrerId",
          "description"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "revision"
            ]
          },
          "targetId": {
            "type": "string"
          },
          "referrerId": {
            "type": "string"
          },
          "description": {
            "type": "string"
          }
        }
      },
      "ByteCount": {
        "type": "integer",
        "description": "A number of bytes.",
        "minimum": 0,
        "maximum": 9007199254740991
      },
      "ByteLimit": {
        "type": [
          "integer",
          "null"
        ],
        "description": "A most number of bytes, or null for no limit.",
        "minimum": 1,
        "maximum": 9007199254740991
      },
      "ChangesetInput": {
        "type": "object",
        "description": "One atomic change of one or more files.",
        "additionalProperties": false,
        "required": [
          "mutationId",
          "deviceId",
          "expectedHeads",
          "revisions"
        ],
        "properties": {
          "mutationId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "description": "Identity of this operation. A retry with the same identity and the same body returns the first outcome."
          },
          "deviceId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DeviceId"
              }
            ],
            "description": "The device that submitted the changeset."
          },
          "expectedHeads": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ExpectedHeads"
              }
            ],
            "description": "The precondition of every file that the changeset changes."
          },
          "revisions": {
            "type": "array",
            "description": "The revisions to accept, in submission order. The revisions of one file form one chain, and the last one becomes its head. One changeset may change at most 1000 files, and a file may carry several revisions, so the limit below is above the file limit.",
            "minItems": 1,
            "maxItems": 4000,
            "items": {
              "$ref": "#/components/schemas/RevisionInput"
            }
          }
        }
      },
      "CheckpointMessage": {
        "type": [
          "string",
          "null"
        ],
        "description": "Name of a checkpoint, or null for an ordinary revision. It is written by the author and is not interpreted by the server.",
        "maxLength": 512
      },
      "ConsentInput": {
        "type": "object",
        "description": "The versions of the two legal documents that a person accepts.",
        "additionalProperties": false,
        "required": [
          "termsVersion",
          "privacyVersion"
        ],
        "properties": {
          "termsVersion": {
            "type": "string",
            "description": "The version of the terms that the person read.",
            "minLength": 1,
            "maxLength": 64
          },
          "privacyVersion": {
            "type": "string",
            "description": "The version of the privacy notice that the person read.",
            "minLength": 1,
            "maxLength": 64
          }
        }
      },
      "ConsentRecorded": {
        "type": "object",
        "description": "The account accepted the current legal documents.",
        "additionalProperties": false,
        "required": [
          "accepted"
        ],
        "properties": {
          "accepted": {
            "type": "boolean",
            "const": true,
            "readOnly": true,
            "description": "The consent is stored with its time."
          }
        }
      },
      "ContentDigest": {
        "type": "string",
        "description": "The SHA-256 digest of the content, in lower case hexadecimal. Content is addressed by this value, so it is verified against the bytes before a revision is accepted.",
        "minLength": 64,
        "maxLength": 64,
        "pattern": "^[0-9a-f]{64}$"
      },
      "ContentInput": {
        "description": "The content of one submitted revision. A note carries document work; an attachment names finalized bytes. The kind states which form applies.",
        "oneOf": [
          {
            "$ref": "#/components/schemas/MarkdownContentInput"
          },
          {
            "$ref": "#/components/schemas/AttachmentContentInput"
          }
        ]
      },
      "ControlRevision": {
        "type": "integer",
        "description": "The revision of the controls of one account. The server raises it on each change of a control, and a write names the revision that it read (record 0189).",
        "minimum": 1,
        "maximum": 9007199254740991
      },
      "CreateFileInput": {
        "type": "object",
        "description": "The identifiers, the path, and the first content of a new file.",
        "additionalProperties": false,
        "required": [
          "fileId",
          "revisionId",
          "mutationId",
          "deviceId",
          "path",
          "document"
        ],
        "properties": {
          "fileId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "description": "Identifier of the new file. The client assigns it, so a file that was written offline keeps one identity everywhere."
          },
          "revisionId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "description": "Identifier of the first revision."
          },
          "mutationId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "description": "Identity of this operation. A retry that repeats it returns the first outcome instead of writing a second time."
          },
          "deviceId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DeviceId"
              }
            ],
            "description": "The device that submitted the change."
          },
          "path": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FilePath"
              }
            ],
            "description": "Path of the new note, which must end in .md."
          },
          "document": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DocumentSave"
              }
            ],
            "description": "The document work of the first revision. A new note starts on the device that creates it, so the save carries the whole document."
          },
          "message": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CheckpointMessage"
              }
            ],
            "description": "Name of this checkpoint, or null."
          }
        }
      },
      "CreatePublishedLinkInput": {
        "type": "object",
        "description": "What to publish, and how a reader reaches it.",
        "additionalProperties": false,
        "required": [
          "scope"
        ],
        "properties": {
          "scope": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PublishedScope"
              }
            ],
            "description": "The one note, or the one folder, that the link opens."
          },
          "password": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Password"
              }
            ],
            "description": "Password that a reader gives before it reads the link. Leave it out for a link that opens without one. The product keeps one password policy, so this bound is the bound of an account password."
          },
          "expiresAt": {
            "type": "string",
            "writeOnly": true,
            "description": "Instant after which the link opens nothing. Leave it out for a link that lasts until the owner revokes it.",
            "format": "date-time",
            "maxLength": 64
          }
        }
      },
      "DailyNoteSettings": {
        "type": "object",
        "description": "The settings of daily notes that one member keeps in one workspace.",
        "additionalProperties": false,
        "required": [
          "templateFileId",
          "openOnStart",
          "folder",
          "format"
        ],
        "properties": {
          "templateFileId": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "The note whose text a new daily note starts with, or null for a daily note that starts empty."
          },
          "openOnStart": {
            "type": "boolean",
            "readOnly": true,
            "description": "True when the note of today opens when the application starts."
          },
          "folder": {
            "type": "string",
            "readOnly": true,
            "description": "The folder that holds every daily note, or an empty text for the top of the workspace.",
            "maxLength": 1024
          },
          "format": {
            "type": "string",
            "readOnly": true,
            "description": "The name of a daily note as date tokens, where a slash makes folders, for example YYYY/MM/YYYY-MM-DD dddd.",
            "minLength": 1,
            "maxLength": 255
          }
        }
      },
      "DailyNoteSettingsInput": {
        "type": "object",
        "description": "The settings of daily notes to store for the signed in member.",
        "additionalProperties": false,
        "required": [
          "templateFileId",
          "openOnStart",
          "folder",
          "format"
        ],
        "properties": {
          "templateFileId": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ],
            "description": "A live note of this workspace whose text a new daily note starts with, or null for a daily note that starts empty."
          },
          "openOnStart": {
            "type": "boolean",
            "description": "True to open the note of today when the application starts."
          },
          "folder": {
            "type": "string",
            "description": "The folder that holds every daily note, or an empty text for the top of the workspace.",
            "maxLength": 1024
          },
          "format": {
            "type": "string",
            "description": "The name of a daily note as date tokens, where a slash makes folders, for example YYYY/MM/YYYY-MM-DD dddd.",
            "minLength": 1,
            "maxLength": 255
          }
        }
      },
      "DeleteFileInput": {
        "type": "object",
        "description": "The identifiers of a tombstone revision.",
        "additionalProperties": false,
        "required": [
          "revisionId",
          "mutationId",
          "deviceId",
          "document"
        ],
        "properties": {
          "revisionId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "description": "Identifier of the tombstone revision."
          },
          "mutationId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "description": "Identity of this operation, which makes a retry safe."
          },
          "deviceId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DeviceId"
              }
            ],
            "description": "The device that submitted the deletion."
          },
          "message": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CheckpointMessage"
              }
            ],
            "description": "Reason for the deletion, or null."
          },
          "document": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DocumentSave"
              }
            ],
            "description": "What the device had seen of the document when it deleted the note. The save carries no update. The workspace refuses the deletion when the state does not cover the text work that the note holds, so a deletion never hides an edit that the device never saw."
          }
        }
      },
      "DeviceId": {
        "type": "string",
        "description": "The device that submitted the change. It is informational and appears in the history of the workspace.",
        "minLength": 1,
        "maxLength": 128
      },
      "DocumentEpoch": {
        "type": "integer",
        "description": "The generation of the document of one note. Identities of one epoch say nothing about another, so two states are compared inside one epoch only. Routine compaction keeps the epoch; a migration or an explicit repair starts a new one.",
        "minimum": 1
      },
      "DocumentObservedState": {
        "type": "string",
        "description": "The complete observed state of a document, as base64. It holds the state vector and the deletion set, so it states every insertion and every deletion that the device has seen. A state vector alone serves a delta and never decides whether work is unseen.",
        "contentEncoding": "base64",
        "pattern": "^[A-Za-z0-9+/]*={0,2}$",
        "maxLength": 1398104
      },
      "DocumentSave": {
        "type": "object",
        "description": "The text work of one saved note: the update, the generation it belongs to, and the complete state that the device had seen when it saved. The server derives the Markdown and its digest from the accepted document, so a save carries no text.",
        "additionalProperties": false,
        "required": [
          "update",
          "epoch",
          "observed"
        ],
        "properties": {
          "update": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DocumentUpdate"
              },
              {
                "type": "null"
              }
            ],
            "description": "The work of this save, from the last state the device sent, or null when the save carries no text work. A deletion states what the device had seen and nothing else."
          },
          "epoch": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DocumentEpoch"
              }
            ],
            "description": "The generation that this update belongs to."
          },
          "observed": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DocumentObservedState"
              }
            ],
            "description": "The complete state that the device had seen at the save. The workspace reads it to decide whether the save joins unseen work, and whether a deletion would hide an edit that the device never saw."
          }
        }
      },
      "DocumentStateVector": {
        "type": "string",
        "description": "The state vector of a document, as base64. A reader sends it to ask for the work that it lacks. It names insertions only, so it never answers whether a deletion is unseen.",
        "contentEncoding": "base64",
        "pattern": "^[A-Za-z0-9+/]*={0,2}$",
        "maxLength": 1398104
      },
      "DocumentUpdate": {
        "type": "string",
        "description": "One document update, as base64. It carries the text work of a note and nothing else. The server applies it to a trial document and refuses it when it is malformed, when it names work that the document lacks, when it writes anything other than the text of the note, or when the result passes a bound.",
        "contentEncoding": "base64",
        "pattern": "^[A-Za-z0-9+/]*={0,2}$",
        "maxLength": 2796204
      },
      "EmailAddress": {
        "type": "string",
        "description": "A sign-in address.",
        "format": "email",
        "minLength": 3,
        "maxLength": 320
      },
      "EntityTagCondition": {
        "type": "string",
        "description": "A conditional request header value: either the literal *, or one or more entity tags separated by commas. A tag is quoted, and a weak tag carries the W/ prefix. A write compares strongly, as RFC 9110 requires, so it accepts a strong tag only.",
        "minLength": 1,
        "maxLength": 1024,
        "pattern": "^(?:\\*|(?:W/)?\"[^\"]*\"(?:[ \\t]*,[ \\t]*(?:W/)?\"[^\"]*\")*)$"
      },
      "ExpectedHeads": {
        "type": "object",
        "description": "The accepted head that the client saw for each file of the changeset, keyed by file identifier. The value null states that the file must not exist in accepted state, which is the precondition of a new file. Every file that the changeset changes needs an entry, and an entry for a file that it does not change is refused. The limit below is a coarse bound that protects the parser; the rule that a changeset may change at most 1000 files is applied by the workspace and answers 422.",
        "maxProperties": 4000,
        "propertyNames": {
          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
        },
        "additionalProperties": {
          "oneOf": [
            {
              "$ref": "#/components/schemas/Uuid"
            },
            {
              "type": "null"
            }
          ]
        }
      },
      "FileChange": {
        "type": "object",
        "description": "The revision that one single file operation accepted.",
        "additionalProperties": false,
        "required": [
          "revision",
          "accepted"
        ],
        "properties": {
          "revision": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AcceptedRevision"
              }
            ],
            "readOnly": true,
            "description": "The accepted revision, as the workspace recorded it. Its identifier is the entity tag of the answer. It carries no text: the request that wrote it already holds the content."
          },
          "accepted": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AcceptedChangeset"
              }
            ],
            "readOnly": true,
            "description": "The outcome of the changeset that carried the revision."
          }
        }
      },
      "FileKind": {
        "type": "string",
        "description": "Whether a file holds Markdown or an attachment.",
        "enum": [
          "note",
          "attachment"
        ]
      },
      "FilePageToken": {
        "type": "string",
        "description": "Opaque position inside one file listing. It belongs to the sort that produced it and carries no meaning for a client.",
        "minLength": 1,
        "maxLength": 2048,
        "pattern": "^(updated|path)\\.[0-9a-fA-F-]{36}\\.[A-Za-z0-9\\-._~!*'()%]*$"
      },
      "FilePath": {
        "type": "string",
        "description": "Relative POSIX path of the file inside its workspace. A note path ends in .md. The stored path is the Unicode NFC form of this value, and it is compared case sensitively.",
        "minLength": 1,
        "maxLength": 1024
      },
      "FileReadContent": {
        "type": "string",
        "description": "The parts of the head that a file read carries. `text` is the Markdown alone, for a reader that shows the text. `full` is the Markdown and the whole document of the note, for an editor that merges later work.",
        "enum": [
          "text",
          "full"
        ],
        "default": "full"
      },
      "FileRevision": {
        "type": "object",
        "description": "One immutable revision. Its identity, its parents, and its content never change after acceptance.",
        "additionalProperties": false,
        "required": [
          "revisionId",
          "fileId",
          "path",
          "kind",
          "deleted",
          "parents",
          "digest",
          "size",
          "text",
          "document",
          "epoch",
          "merged",
          "attachmentObjectId",
          "message",
          "restoredFrom",
          "clientTime",
          "serverTime"
        ],
        "properties": {
          "revisionId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "Identifier of this revision."
          },
          "fileId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "The file that this revision belongs to."
          },
          "path": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FilePath"
              }
            ],
            "readOnly": true,
            "description": "The path of the file at this revision."
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FileKind"
              }
            ],
            "readOnly": true,
            "description": "Whether this revision holds Markdown or an attachment."
          },
          "deleted": {
            "type": "boolean",
            "readOnly": true,
            "description": "True for a tombstone, which is how a deletion is recorded."
          },
          "parents": {
            "type": "array",
            "readOnly": true,
            "description": "The parents of this revision, in submitted order. A first revision has none, a normal revision has one, and an explicit merge has two.",
            "maxItems": 2,
            "items": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          "digest": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ContentDigest"
              }
            ],
            "readOnly": true,
            "description": "Digest of the content of this revision."
          },
          "size": {
            "type": "integer",
            "readOnly": true,
            "description": "Size of the content in bytes.",
            "minimum": 0
          },
          "text": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/MarkdownText"
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "The Markdown of this revision, or null for an attachment revision."
          },
          "attachmentObjectId": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "The immutable attachment object of this revision, or null for a Markdown revision. Its bytes are transferred separately."
          },
          "message": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CheckpointMessage"
              }
            ],
            "readOnly": true,
            "description": "The checkpoint name of this revision, or null."
          },
          "restoredFrom": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "The historic revision that this one restored, or null. A restore never rewinds history; it adds a revision."
          },
          "clientTime": {
            "type": "string",
            "readOnly": true,
            "description": "The clock of the device that wrote the revision. It stays informational, because a device clock cannot be trusted.",
            "format": "date-time",
            "maxLength": 64
          },
          "serverTime": {
            "type": "string",
            "readOnly": true,
            "description": "Instant at which the workspace accepted the revision.",
            "format": "date-time",
            "maxLength": 64
          },
          "document": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DocumentUpdate"
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "The whole document of the note at this revision, so a reader can start from it and stay able to merge later work. Null for an attachment revision, and for a file read that asked for the text alone."
          },
          "epoch": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DocumentEpoch"
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "The generation of that document, or null for an attachment revision."
          },
          "merged": {
            "type": "boolean",
            "readOnly": true,
            "description": "True when the save that made this revision joined work that its device had not seen. Every device reads the mark in History, and the device that saved keeps its own checkpoint for Review."
          }
        }
      },
      "FileSortOrder": {
        "type": "string",
        "description": "Order of a file listing. `updated` is the newest accepted change first. `path` is the stored path in ascending order.",
        "enum": [
          "updated",
          "path"
        ]
      },
      "FinalizeAttachmentInput": {
        "type": "object",
        "description": "Payload to finalize an attachment and create an immutable revision.",
        "additionalProperties": false,
        "required": [
          "fileId",
          "revisionId",
          "mutationId",
          "deviceId",
          "path",
          "digest"
        ],
        "properties": {
          "fileId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "description": "Identifier of the file that holds this attachment revision."
          },
          "revisionId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "description": "Identifier of the new revision."
          },
          "mutationId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "description": "Identity of this operation, which makes a retry safe."
          },
          "deviceId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DeviceId"
              }
            ],
            "description": "The device that submitted the change."
          },
          "path": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FilePath"
              }
            ],
            "description": "Path of the attachment file in the workspace."
          },
          "digest": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ContentDigest"
              }
            ],
            "description": "The verified SHA-256 digest of the attachment object."
          },
          "message": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CheckpointMessage"
              }
            ],
            "description": "Name of this checkpoint, or null."
          }
        }
      },
      "HandoffAccount": {
        "type": "object",
        "description": "The account that opened the portal.",
        "additionalProperties": false,
        "required": [
          "accountId",
          "email"
        ],
        "properties": {
          "accountId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "Identifier of the account."
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "readOnly": true,
            "description": "Sign-in address of the account.",
            "maxLength": 320
          }
        }
      },
      "HandoffRedeemInput": {
        "type": "object",
        "description": "The token of a handoff that the portal received.",
        "additionalProperties": false,
        "required": [
          "token"
        ],
        "properties": {
          "token": {
            "allOf": [
              {
                "$ref": "#/components/schemas/HandoffToken"
              }
            ],
            "writeOnly": true,
            "description": "The token from the query of the portal address."
          }
        }
      },
      "HandoffToken": {
        "type": "string",
        "description": "A single-use token of one portal handoff (record 0190). It works once and for 60 seconds.",
        "minLength": 43,
        "maxLength": 43,
        "pattern": "^[A-Za-z0-9_-]{43}$"
      },
      "HealthReport": {
        "type": "object",
        "description": "Liveness report of the service process.",
        "additionalProperties": false,
        "required": [
          "status"
        ],
        "properties": {
          "status": {
            "type": "string",
            "readOnly": true,
            "description": "Always the literal value ok while the process answers.",
            "enum": [
              "ok"
            ]
          }
        }
      },
      "HistoryPage": {
        "type": "object",
        "description": "One page of file history revisions.",
        "additionalProperties": false,
        "required": [
          "revisions",
          "nextCursor"
        ],
        "properties": {
          "revisions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HistoryRevisionItem"
            }
          },
          "nextCursor": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "HistoryRevisionItem": {
        "type": "object",
        "description": "One historic revision of a file.",
        "additionalProperties": false,
        "required": [
          "revisionId",
          "fileId",
          "path",
          "deleted",
          "parents",
          "digest",
          "size",
          "actorAccountId",
          "clientTime",
          "serverTime",
          "message",
          "isCheckpoint",
          "checkpointName",
          "restoredFrom",
          "text",
          "objectId",
          "merged"
        ],
        "properties": {
          "revisionId": {
            "$ref": "#/components/schemas/Uuid"
          },
          "fileId": {
            "$ref": "#/components/schemas/Uuid"
          },
          "path": {
            "$ref": "#/components/schemas/FilePath"
          },
          "deleted": {
            "type": "boolean"
          },
          "parents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          "digest": {
            "$ref": "#/components/schemas/ContentDigest"
          },
          "size": {
            "type": "integer"
          },
          "actorAccountId": {
            "$ref": "#/components/schemas/Uuid"
          },
          "clientTime": {
            "type": "string",
            "format": "date-time"
          },
          "serverTime": {
            "type": "string",
            "format": "date-time"
          },
          "message": {
            "$ref": "#/components/schemas/CheckpointMessage"
          },
          "isCheckpoint": {
            "type": "boolean"
          },
          "checkpointName": {
            "$ref": "#/components/schemas/CheckpointMessage"
          },
          "restoredFrom": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "text": {
            "type": [
              "string",
              "null"
            ]
          },
          "objectId": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "merged": {
            "type": "boolean",
            "description": "True when the save that made this revision joined work that its device had not seen. History marks the revision on every device."
          }
        }
      },
      "ImportWorkspaceResult": {
        "type": "object",
        "description": "Counts of the files that one import wrote, and of the files of the archive that it left out: the settings of a tool, such as the .obsidian folder, and every file that is neither a note nor an image (record 0172).",
        "additionalProperties": false,
        "required": [
          "notes",
          "attachments",
          "skipped"
        ],
        "properties": {
          "notes": {
            "type": "integer",
            "minimum": 0
          },
          "attachments": {
            "type": "integer",
            "minimum": 0
          },
          "skipped": {
            "type": "object",
            "description": "The files of the archive that the import left out.",
            "additionalProperties": false,
            "required": [
              "files",
              "kinds"
            ],
            "properties": {
              "files": {
                "type": "integer",
                "minimum": 0
              },
              "kinds": {
                "type": "array",
                "description": "The kinds of the files left out, in name order: the file extension in lower case, `settings` for the settings of a tool, and `file` for a file with no extension.",
                "maxItems": 50,
                "items": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 40
                }
              }
            }
          }
        }
      },
      "ImportedTheme": {
        "type": "object",
        "description": "One theme that the account imported. The client checks its contrast before it offers or paints it, and its family is custom- and the identifier.",
        "additionalProperties": false,
        "required": [
          "themeId",
          "name"
        ],
        "properties": {
          "themeId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "Identifier of the imported theme."
          },
          "name": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ThemeName"
              }
            ],
            "readOnly": true
          },
          "light": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ThemePalette"
              }
            ],
            "readOnly": true
          },
          "dark": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ThemePalette"
              }
            ],
            "readOnly": true
          }
        }
      },
      "Installation": {
        "type": "object",
        "description": "The settings of the installation that an administrator reads.",
        "additionalProperties": false,
        "required": [
          "registrationPolicy",
          "registrationPolicySource",
          "mailConfigured",
          "invitationLifetimeHours",
          "defaultLimitBytes",
          "mail",
          "legalDocuments"
        ],
        "properties": {
          "registrationPolicy": {
            "allOf": [
              {
                "$ref": "#/components/schemas/RegistrationPolicy"
              }
            ],
            "readOnly": true,
            "description": "Who can make an account."
          },
          "registrationPolicySource": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SettingSource"
              }
            ],
            "readOnly": true,
            "description": "Where the registration policy comes from (record 0206). With environment, the server environment names it and the application cannot change it."
          },
          "mailConfigured": {
            "type": "boolean",
            "readOnly": true,
            "description": "Whether the installation has a mail transport. Without one, an invitation link appears once for the administrator to copy."
          },
          "invitationLifetimeHours": {
            "type": "integer",
            "readOnly": true,
            "description": "How long a new invitation stays valid, in hours.",
            "minimum": 1,
            "maximum": 8760
          },
          "defaultLimitBytes": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ByteCount"
              }
            ],
            "readOnly": true,
            "description": "The limit that a new account starts with."
          },
          "mail": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MailSettings"
              }
            ],
            "readOnly": true
          },
          "legalDocuments": {
            "allOf": [
              {
                "$ref": "#/components/schemas/LegalSettings"
              }
            ],
            "readOnly": true
          }
        }
      },
      "InstallationRole": {
        "type": "string",
        "description": "The role of an account in the installation. An administrator manages accounts and invitations. The role grants no access to a workspace of another account.",
        "enum": [
          "administrator",
          "member"
        ]
      },
      "InstallationUpdateInput": {
        "type": "object",
        "description": "The settings of the installation that an administrator changes.",
        "additionalProperties": false,
        "required": [
          "registrationPolicy"
        ],
        "properties": {
          "registrationPolicy": {
            "allOf": [
              {
                "$ref": "#/components/schemas/RegistrationPolicy"
              }
            ],
            "description": "Who can make an account. The server refuses open until the installation has every part that open registration needs."
          }
        }
      },
      "Invitation": {
        "type": "object",
        "description": "One invitation that waits. This shape holds no token, so a read of the list cannot open an invitation.",
        "additionalProperties": false,
        "required": [
          "invitationId",
          "email",
          "createdAt",
          "expiresAt",
          "state",
          "mailed"
        ],
        "properties": {
          "invitationId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "Identifier of the invitation record. An administrator names it to revoke the invitation. It is not the token."
          },
          "email": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EmailAddress"
              }
            ],
            "readOnly": true,
            "description": "The address that the invitation binds."
          },
          "createdAt": {
            "type": "string",
            "readOnly": true,
            "description": "Instant at which the invitation was made.",
            "format": "date-time",
            "maxLength": 64
          },
          "expiresAt": {
            "type": "string",
            "readOnly": true,
            "description": "Instant after which the invitation opens nothing.",
            "format": "date-time",
            "maxLength": 64
          },
          "state": {
            "type": "string",
            "readOnly": true,
            "description": "pending while the invitation can be used, expired after.",
            "enum": [
              "pending",
              "expired"
            ]
          },
          "mailed": {
            "type": "boolean",
            "readOnly": true,
            "description": "Whether the link went to the address by mail."
          }
        }
      },
      "InvitationAddress": {
        "type": "object",
        "description": "The address that a valid invitation binds.",
        "additionalProperties": false,
        "required": [
          "email"
        ],
        "properties": {
          "email": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EmailAddress"
              }
            ],
            "readOnly": true,
            "description": "The address of the new account."
          }
        }
      },
      "InvitationCreateInput": {
        "type": "object",
        "description": "The address that a new invitation binds.",
        "additionalProperties": false,
        "required": [
          "email"
        ],
        "properties": {
          "email": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EmailAddress"
              }
            ],
            "description": "The address of the invited person. The person cannot change it while they accept."
          }
        }
      },
      "InvitationCreated": {
        "type": "object",
        "description": "A new invitation, and its link when no mail transport sent it. The link appears in this answer only, once.",
        "additionalProperties": false,
        "required": [
          "invitation",
          "link"
        ],
        "properties": {
          "invitation": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Invitation"
              }
            ],
            "readOnly": true,
            "description": "The new invitation."
          },
          "link": {
            "oneOf": [
              {
                "type": "string",
                "format": "uri",
                "maxLength": 2048
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "The link that opens the invitation, for the administrator to copy, or null when the link went by mail."
          }
        }
      },
      "InvitationList": {
        "type": "object",
        "description": "The invitations that nobody used or revoked.",
        "additionalProperties": false,
        "required": [
          "invitations"
        ],
        "properties": {
          "invitations": {
            "type": "array",
            "readOnly": true,
            "description": "The invitations, newest first.",
            "maxItems": 10000,
            "items": {
              "$ref": "#/components/schemas/Invitation"
            }
          }
        }
      },
      "InvitationReadInput": {
        "type": "object",
        "description": "The token of the invitation to read.",
        "additionalProperties": false,
        "required": [
          "invitation"
        ],
        "properties": {
          "invitation": {
            "allOf": [
              {
                "$ref": "#/components/schemas/InvitationToken"
              }
            ],
            "description": "The token from the invitation link."
          }
        }
      },
      "InvitationToken": {
        "type": "string",
        "description": "The secret of one invitation, as the link carries it. The server keeps only its digest.",
        "minLength": 43,
        "maxLength": 43,
        "pattern": "^[A-Za-z0-9_-]{43}$",
        "writeOnly": true
      },
      "LegalDocument": {
        "type": "object",
        "description": "One legal document of the installation and its current version.",
        "additionalProperties": false,
        "required": [
          "url",
          "version"
        ],
        "properties": {
          "url": {
            "type": "string",
            "readOnly": true,
            "description": "Where a person reads the document.",
            "format": "uri",
            "maxLength": 2048
          },
          "version": {
            "type": "string",
            "readOnly": true,
            "description": "The current version, which a consent names.",
            "minLength": 1,
            "maxLength": 64
          }
        }
      },
      "LegalDocumentInput": {
        "type": "object",
        "description": "One legal document that an administrator sets: a text with the kind text, or an address with the kind address, and its version.",
        "additionalProperties": false,
        "required": [
          "kind",
          "version"
        ],
        "properties": {
          "kind": {
            "$ref": "#/components/schemas/LegalDocumentKind"
          },
          "text": {
            "type": "string",
            "description": "The Markdown text of the document, for the kind text.",
            "minLength": 1,
            "maxLength": 262144
          },
          "url": {
            "type": "string",
            "description": "The address of the document, for the kind address.",
            "format": "uri",
            "maxLength": 2048
          },
          "version": {
            "type": "string",
            "description": "The version of the document. A new version asks every account to accept again.",
            "minLength": 1,
            "maxLength": 64
          }
        }
      },
      "LegalDocumentKind": {
        "type": "string",
        "description": "The source of a legal document. text is Markdown that this server serves, and address is a page on another site.",
        "enum": [
          "text",
          "address"
        ]
      },
      "LegalDocumentSetting": {
        "type": "object",
        "description": "One stored legal document, as the administrator changes it.",
        "additionalProperties": false,
        "required": [
          "kind",
          "text",
          "url",
          "version"
        ],
        "properties": {
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/LegalDocumentKind"
              }
            ],
            "readOnly": true
          },
          "text": {
            "type": [
              "string",
              "null"
            ],
            "readOnly": true,
            "description": "The Markdown text, for the kind text.",
            "maxLength": 262144
          },
          "url": {
            "type": [
              "string",
              "null"
            ],
            "readOnly": true,
            "description": "The address, for the kind address.",
            "maxLength": 2048
          },
          "version": {
            "type": "string",
            "readOnly": true,
            "minLength": 1,
            "maxLength": 64
          }
        }
      },
      "LegalDocumentSettings": {
        "type": "object",
        "description": "One legal document of the installation and its template, as the administrator changes them.",
        "additionalProperties": false,
        "required": [
          "source",
          "document",
          "template"
        ],
        "properties": {
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SettingSource"
              }
            ],
            "readOnly": true
          },
          "document": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/LegalDocumentSetting"
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "The stored document, or null when the application holds none."
          },
          "template": {
            "type": "string",
            "readOnly": true,
            "description": "The template of the document in Markdown. The server fills the facts that it knows, and each other blank is a marker in double braces.",
            "maxLength": 262144
          }
        }
      },
      "LegalDocumentSummary": {
        "type": "object",
        "description": "One legal document that the installation holds.",
        "additionalProperties": false,
        "required": [
          "kind",
          "url",
          "version"
        ],
        "properties": {
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/LegalDocumentKind"
              }
            ],
            "readOnly": true
          },
          "url": {
            "type": "string",
            "readOnly": true,
            "description": "Where a person reads the document.",
            "format": "uri",
            "maxLength": 2048
          },
          "version": {
            "type": "string",
            "readOnly": true,
            "description": "The current version, which a consent names.",
            "minLength": 1,
            "maxLength": 64
          }
        }
      },
      "LegalDocuments": {
        "type": "object",
        "description": "The terms and the privacy notice of the installation (record 0120). The operator writes both and names their versions.",
        "additionalProperties": false,
        "required": [
          "terms",
          "privacy"
        ],
        "properties": {
          "terms": {
            "$ref": "#/components/schemas/LegalDocument"
          },
          "privacy": {
            "$ref": "#/components/schemas/LegalDocument"
          }
        }
      },
      "LegalPageDocument": {
        "type": "string",
        "description": "One legal document of the installation, as one HTML document. The server builds it from the Markdown file of the operator with the one sanitized renderer, and it holds no script.",
        "maxLength": 8388608
      },
      "LegalSettings": {
        "type": "object",
        "description": "The legal documents that the installation holds. They apply when both exist (record 0148).",
        "additionalProperties": false,
        "required": [
          "source",
          "terms",
          "privacy"
        ],
        "properties": {
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SettingSource"
              }
            ],
            "readOnly": true
          },
          "terms": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/LegalDocumentSummary"
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true
          },
          "privacy": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/LegalDocumentSummary"
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true
          }
        }
      },
      "LinkReport": {
        "type": "object",
        "description": "One open report of a published link, as an administrator reads it. It holds no fact of a note and no fact of the workspace.",
        "additionalProperties": false,
        "required": [
          "reportId",
          "publicationId",
          "reason",
          "note",
          "address",
          "linkState",
          "createdAt"
        ],
        "properties": {
          "reportId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "Identifier of the report."
          },
          "publicationId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "Identifier of the reported link. Two reports of one link name the same value. It opens nothing."
          },
          "reason": {
            "$ref": "#/components/schemas/ReportReason"
          },
          "note": {
            "oneOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "What the reader added, or null."
          },
          "address": {
            "oneOf": [
              {
                "type": "string",
                "maxLength": 2048
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "The address of the reported link, which the administrator opens as any reader does. It is null when the server cannot open the sealed address, for example after a change of its secret."
          },
          "linkState": {
            "type": "string",
            "readOnly": true,
            "description": "Whether the link opens now, an administrator took it down, or it stopped for another cause.",
            "enum": [
              "live",
              "taken-down",
              "stopped"
            ]
          },
          "createdAt": {
            "type": "string",
            "readOnly": true,
            "description": "Instant of the report.",
            "format": "date-time",
            "maxLength": 64
          }
        }
      },
      "LinkReportList": {
        "type": "object",
        "description": "The open reports of published links.",
        "additionalProperties": false,
        "required": [
          "reports"
        ],
        "properties": {
          "reports": {
            "type": "array",
            "readOnly": true,
            "description": "The open reports, newest first.",
            "maxItems": 10000,
            "items": {
              "$ref": "#/components/schemas/LinkReport"
            }
          }
        }
      },
      "MailSecurity": {
        "type": "string",
        "description": "How the connection to the mail server is protected. tls opens a TLS connection at once, starttls upgrades a plain connection, and none sends with no protection.",
        "enum": [
          "tls",
          "starttls",
          "none"
        ]
      },
      "MailSettings": {
        "type": "object",
        "description": "The mail transport that applies now. No member holds a password.",
        "additionalProperties": false,
        "required": [
          "source",
          "host",
          "port",
          "security",
          "username",
          "sender",
          "passwordStored"
        ],
        "properties": {
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SettingSource"
              }
            ],
            "readOnly": true
          },
          "host": {
            "type": [
              "string",
              "null"
            ],
            "readOnly": true,
            "description": "The host name of the mail server.",
            "maxLength": 253
          },
          "port": {
            "type": [
              "integer",
              "null"
            ],
            "readOnly": true,
            "description": "The port of the mail server.",
            "minimum": 1,
            "maximum": 65535
          },
          "security": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/MailSecurity"
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true
          },
          "username": {
            "type": [
              "string",
              "null"
            ],
            "readOnly": true,
            "description": "The user name that signs in to the mail server, or null.",
            "maxLength": 320
          },
          "sender": {
            "type": [
              "string",
              "null"
            ],
            "readOnly": true,
            "description": "The sender of every message.",
            "maxLength": 320
          },
          "passwordStored": {
            "type": "boolean",
            "readOnly": true,
            "description": "Whether the application holds a password for the mail server."
          }
        }
      },
      "MailSettingsInput": {
        "type": "object",
        "description": "The mail transport that an administrator sets.",
        "additionalProperties": false,
        "required": [
          "host",
          "port",
          "security",
          "sender"
        ],
        "properties": {
          "host": {
            "type": "string",
            "description": "The host name of the mail server.",
            "minLength": 1,
            "maxLength": 253
          },
          "port": {
            "type": "integer",
            "description": "The port of the mail server.",
            "minimum": 1,
            "maximum": 65535
          },
          "security": {
            "$ref": "#/components/schemas/MailSecurity"
          },
          "username": {
            "type": "string",
            "description": "The user name that signs in to the mail server. Leave it out for a server that takes mail with no sign-in.",
            "minLength": 1,
            "maxLength": 320
          },
          "password": {
            "type": "string",
            "writeOnly": true,
            "description": "The password of the user name. Leave it out to keep the stored one.",
            "minLength": 1,
            "maxLength": 1024
          },
          "sender": {
            "type": "string",
            "description": "The sender of every message, an address or a name and an address, for example tidy notebook <no-reply@notes.example.com>.",
            "minLength": 3,
            "maxLength": 320
          }
        }
      },
      "MailTestSent": {
        "type": "object",
        "description": "Where the test message went.",
        "additionalProperties": false,
        "required": [
          "to"
        ],
        "properties": {
          "to": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EmailAddress"
              }
            ],
            "readOnly": true
          }
        }
      },
      "MarkdownContentInput": {
        "type": "object",
        "description": "The content of one saved note. It carries document work, never text: the accepted text is what the workspace derives from the accepted document.",
        "additionalProperties": false,
        "required": [
          "kind",
          "document"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "description": "Names this content form.",
            "enum": [
              "markdown"
            ]
          },
          "document": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DocumentSave"
              }
            ],
            "description": "The text work of this save."
          }
        }
      },
      "MarkdownText": {
        "type": "string",
        "description": "The Markdown source of one revision. It is stored and returned exactly as it was written, without normalization.",
        "maxLength": 1048576
      },
      "MutationReceipt": {
        "type": "object",
        "description": "What the workspace knows about one mutation identity. A device reads it when it does not know whether a save reached the server, before it transforms work that may already have committed. The answer states the outcome and never the text of a note.",
        "additionalProperties": false,
        "required": [
          "mutationId",
          "status",
          "accepted"
        ],
        "properties": {
          "mutationId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "The mutation identity that the device asked about."
          },
          "status": {
            "type": "string",
            "readOnly": true,
            "description": "accepted means this workspace committed exactly this request. absent means it holds no receipt for the identity, which is definitive only while no other writer of this account is running. other_request means the identity belongs to a different request, so the device must not send this one under it.",
            "enum": [
              "accepted",
              "absent",
              "other_request"
            ]
          },
          "accepted": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/AcceptedChangeset"
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "The stored outcome of the accepted request, or null. It repeats what the first answer stated, so a device that lost the answer can settle its queue without sending again."
          }
        }
      },
      "OperatorAccount": {
        "type": "object",
        "description": "One account as a service of the operator reads it (record 0190). It holds no note, no workspace and no published link.",
        "additionalProperties": false,
        "required": [
          "accountId",
          "email",
          "role",
          "state",
          "createdAt",
          "controls",
          "usage"
        ],
        "properties": {
          "accountId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "Identifier of the account."
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "readOnly": true,
            "description": "Sign-in address of the account.",
            "maxLength": 320
          },
          "role": {
            "allOf": [
              {
                "$ref": "#/components/schemas/InstallationRole"
              }
            ],
            "readOnly": true,
            "description": "The role that decides which account controls can apply."
          },
          "state": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountState"
              }
            ],
            "readOnly": true,
            "description": "Whether the account can sign in."
          },
          "createdAt": {
            "type": "string",
            "readOnly": true,
            "description": "Instant at which the account was made.",
            "format": "date-time",
            "maxLength": 64
          },
          "controls": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountControls"
              }
            ],
            "readOnly": true,
            "description": "The controls of the account and their revision."
          },
          "usage": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountUsage"
              }
            ],
            "readOnly": true,
            "description": "What the account uses."
          }
        }
      },
      "OperatorTotals": {
        "type": "object",
        "description": "The totals of the whole installation for one calendar month in UTC (record 0193).",
        "additionalProperties": false,
        "required": [
          "month",
          "publishedTransferBytes",
          "downloadBytes",
          "objectWrites",
          "objectReads"
        ],
        "properties": {
          "month": {
            "allOf": [
              {
                "$ref": "#/components/schemas/UsageMonth"
              }
            ],
            "readOnly": true,
            "description": "The month of the totals."
          },
          "publishedTransferBytes": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ByteCount"
              }
            ],
            "readOnly": true,
            "description": "The bytes that every published page sent in the month."
          },
          "downloadBytes": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ByteCount"
              }
            ],
            "readOnly": true,
            "description": "The bytes that every account downloaded in the month."
          },
          "objectWrites": {
            "type": "integer",
            "readOnly": true,
            "description": "The write calls to the object store in the month.",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "objectReads": {
            "type": "integer",
            "readOnly": true,
            "description": "The read calls to the object store in the month.",
            "minimum": 0,
            "maximum": 9007199254740991
          }
        }
      },
      "Password": {
        "type": "string",
        "description": "A new password. The bounds are the ones of NIST SP 800-63B revision 4 for a password that is the only factor, and passwordBounds of the core states the same bounds. The server also refuses a password that a list of leaked passwords holds.",
        "minLength": 15,
        "maxLength": 512,
        "writeOnly": true
      },
      "PortalAddress": {
        "type": "object",
        "description": "The address that opens the account portal for the signed in account. It carries a single-use token that works for 60 seconds.",
        "additionalProperties": false,
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "type": "string",
            "readOnly": true,
            "description": "The full address of the portal, with the token in the query.",
            "format": "uri",
            "maxLength": 2400
          }
        }
      },
      "PortalOpenInput": {
        "type": "object",
        "description": "The path on the account portal to open.",
        "additionalProperties": false,
        "required": [
          "path"
        ],
        "properties": {
          "path": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PortalPath"
              }
            ],
            "writeOnly": true,
            "description": "The path on the portal."
          }
        }
      },
      "PortalPath": {
        "type": "string",
        "description": "A path on the account portal of the operator. It starts with a slash, and each part is letters, digits and the marks of an address.",
        "minLength": 1,
        "maxLength": 256,
        "pattern": "^(/[A-Za-z0-9_~-][A-Za-z0-9._~-]*)*/?$"
      },
      "Preferences": {
        "type": "object",
        "description": "Settings that follow one account to every device.",
        "additionalProperties": false,
        "required": [
          "appearance",
          "themeFamily",
          "spellCheck",
          "themes"
        ],
        "properties": {
          "appearance": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Appearance"
              }
            ],
            "readOnly": true,
            "description": "The stored appearance choice of the account."
          },
          "themeFamily": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ThemeFamily"
              }
            ],
            "readOnly": true,
            "description": "The stored theme family of the account."
          },
          "spellCheck": {
            "type": "boolean",
            "readOnly": true,
            "description": "True when the editor asks the browser to check the spelling of a note."
          },
          "themes": {
            "type": "array",
            "readOnly": true,
            "description": "The themes that the account imported, oldest first.",
            "maxItems": 20,
            "items": {
              "$ref": "#/components/schemas/ImportedTheme"
            }
          }
        }
      },
      "PreferencesInput": {
        "type": "object",
        "description": "Settings to store for the signed in account. A member that the body leaves out keeps its stored value, so a client changes one setting without the others.",
        "additionalProperties": false,
        "minProperties": 1,
        "properties": {
          "appearance": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Appearance"
              }
            ],
            "description": "The appearance choice to store."
          },
          "themeFamily": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ThemeFamily"
              }
            ],
            "description": "The theme family to store."
          },
          "spellCheck": {
            "type": "boolean",
            "description": "Whether the editor checks the spelling of a note."
          }
        }
      },
      "PreviewPurgeInput": {
        "type": "object",
        "description": "Payload to preview permanent deletion of files.",
        "additionalProperties": false,
        "required": [
          "fileIds"
        ],
        "properties": {
          "fileIds": {
            "type": "array",
            "minItems": 1,
            "maxItems": 1000,
            "items": {
              "$ref": "#/components/schemas/Uuid"
            }
          }
        }
      },
      "ProblemDetails": {
        "type": "object",
        "description": "RFC 9457 problem details. The code field carries the stable application error code that a client can branch on.",
        "additionalProperties": true,
        "required": [
          "type",
          "title",
          "status",
          "code",
          "requestId"
        ],
        "properties": {
          "type": {
            "type": "string",
            "readOnly": true,
            "description": "Stable URI reference that identifies the problem type.",
            "format": "uri-reference",
            "maxLength": 256
          },
          "title": {
            "type": "string",
            "readOnly": true,
            "description": "Short human readable summary of the problem type.",
            "maxLength": 256
          },
          "status": {
            "type": "integer",
            "readOnly": true,
            "description": "HTTP status code of this response.",
            "minimum": 100,
            "maximum": 599
          },
          "detail": {
            "type": "string",
            "readOnly": true,
            "description": "Explanation of this occurrence. The field never contains note content, a secret, or a stack trace.",
            "maxLength": 1024
          },
          "instance": {
            "type": "string",
            "readOnly": true,
            "description": "URI reference of the request that produced the problem.",
            "format": "uri-reference",
            "maxLength": 1024
          },
          "code": {
            "type": "string",
            "readOnly": true,
            "description": "Stable application error code.",
            "pattern": "^[a-z][a-z0-9_]*$",
            "maxLength": 64
          },
          "requestId": {
            "type": "string",
            "readOnly": true,
            "description": "Identifier of the request, repeated in the x-request-id header.",
            "minLength": 1,
            "maxLength": 128
          },
          "issues": {
            "type": "array",
            "readOnly": true,
            "description": "Values that a boundary check rejected. Each entry names the value by JSON Pointer and never repeats the value itself.",
            "maxItems": 64,
            "items": {
              "$ref": "#/components/schemas/ValidationIssue"
            }
          },
          "fileIds": {
            "type": "array",
            "readOnly": true,
            "description": "The files that a content failure refers to, for example every file whose accepted head moved on. The list is absent when the failure names no file. It carries identifiers only, never a path or note content.",
            "maxItems": 4000,
            "items": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          "noteRefusal": {
            "type": "string",
            "readOnly": true,
            "description": "The limit of the Markdown grammar that a refused note is over, on the code unrenderable_note only (record 0182). A client names the cause and the next step in words, and never shows this value.",
            "enum": [
              "note_too_large",
              "note_too_deep",
              "note_too_many_marks",
              "note_too_many_cells"
            ]
          },
          "limit": {
            "allOf": [
              {
                "$ref": "#/components/schemas/UsageLimit"
              }
            ],
            "readOnly": true,
            "description": "The limit of the month that refused the request, on the codes download_limit and storage_busy only (record 0193)."
          }
        }
      },
      "ProfileUpdateInput": {
        "type": "object",
        "description": "The name of the account.",
        "additionalProperties": false,
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "writeOnly": true,
            "description": "Display name of the account.",
            "minLength": 1,
            "maxLength": 256,
            "pattern": "^\\S(?:[\\s\\S]*\\S)?$"
          }
        }
      },
      "ProfileUpdated": {
        "type": "object",
        "description": "The profile name was stored.",
        "additionalProperties": false,
        "required": [
          "status"
        ],
        "properties": {
          "status": {
            "type": "boolean",
            "readOnly": true,
            "description": "True when the name was stored.",
            "const": true
          }
        }
      },
      "PublishedDocument": {
        "type": "string",
        "description": "The published page, as one HTML document. The server builds it from the stored Markdown with the one sanitized renderer, and it holds no script. Its only style sheet is the built style sheet of the application.",
        "maxLength": 8388608
      },
      "PublishedFolderScope": {
        "type": "object",
        "description": "A link that opens one folder and every note below it. A folder is a part of a note path, so the scope is a path prefix inside one workspace. A note in the Trash stays outside it.",
        "additionalProperties": false,
        "required": [
          "kind",
          "path"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "description": "Names this scope as one folder.",
            "const": "folder"
          },
          "path": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FilePath"
              }
            ],
            "description": "The folder that the link opens. Every note below it is published, now and later."
          }
        }
      },
      "PublishedLink": {
        "type": "object",
        "description": "One published link of a workspace, as its owner sees it. This shape holds no token, so a read of the list cannot open a link.",
        "additionalProperties": false,
        "required": [
          "publicationId",
          "scope",
          "createdAt",
          "expiresAt",
          "passwordProtected",
          "takenDown"
        ],
        "properties": {
          "publicationId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "Identifier of the link record. The owner names it to revoke the link. It is not the token and it opens nothing."
          },
          "scope": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PublishedScope"
              }
            ],
            "readOnly": true,
            "description": "What the link opens."
          },
          "createdAt": {
            "type": "string",
            "readOnly": true,
            "description": "Instant at which the owner made the link.",
            "format": "date-time",
            "maxLength": 64
          },
          "expiresAt": {
            "oneOf": [
              {
                "type": "string",
                "format": "date-time",
                "maxLength": 64
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "Instant after which the link opens nothing, or null for a link that lasts until the owner revokes it."
          },
          "passwordProtected": {
            "type": "boolean",
            "readOnly": true,
            "description": "Whether a reader gives a password before it reads the link."
          },
          "takenDown": {
            "type": "boolean",
            "readOnly": true,
            "description": "Whether an administrator took the link down after a report. A taken down link opens nothing, and its owner cannot make it live again. It stays in the list for 30 days."
          }
        }
      },
      "PublishedLinkCreated": {
        "type": "object",
        "description": "The new link and its token. This is the one answer of the whole interface that holds a token. The server keeps only a digest of the token, so it cannot show the value again.",
        "additionalProperties": false,
        "required": [
          "link",
          "token"
        ],
        "properties": {
          "link": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PublishedLink"
              }
            ],
            "readOnly": true,
            "description": "The new link, as the list reports it from now on."
          },
          "token": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PublishedTokenValue"
              }
            ],
            "readOnly": true,
            "description": "The token of the new link. The owner puts it in the address that it shares. No other answer holds it, and no answer holds a part of it."
          }
        }
      },
      "PublishedLinkList": {
        "type": "object",
        "description": "Every published link of one workspace. No entry holds a token.",
        "additionalProperties": false,
        "required": [
          "links"
        ],
        "properties": {
          "links": {
            "type": "array",
            "readOnly": true,
            "description": "One entry for each link that the workspace holds.",
            "maxItems": 200,
            "items": {
              "$ref": "#/components/schemas/PublishedLink"
            }
          }
        }
      },
      "PublishedNoteReference": {
        "type": "string",
        "description": "Names one note of a folder link. The page of a folder link lists the notes that it opens, and each entry of that list carries this value. Any short text is accepted, because a value that names no note inside the scope of the link answers the same page as a value that names nothing at all.",
        "minLength": 1,
        "maxLength": 200
      },
      "PublishedNoteScope": {
        "type": "object",
        "description": "A link that opens one note.",
        "additionalProperties": false,
        "required": [
          "kind",
          "fileId"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "description": "Names this scope as one note.",
            "const": "note"
          },
          "fileId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "description": "The note that the link opens. A rename keeps the link, because the identifier of a note does not move."
          }
        }
      },
      "PublishedPasswordFormInput": {
        "type": "object",
        "description": "The one field of the password form of a published page. A served page holds no script, so the browser sends the field in the form encoding of HTML and the server reads one name from it.",
        "additionalProperties": false,
        "required": [
          "password"
        ],
        "properties": {
          "password": {
            "type": "string",
            "writeOnly": true,
            "description": "The password that the owner gave the link. Any value is accepted here and a wrong value answers the same page, so the answer states nothing about the link or about the password policy. An empty value is accepted as well, because a form that a person sends empty is a wrong password and answers the same page.",
            "maxLength": 512
          }
        }
      },
      "PublishedRefusal": {
        "type": "object",
        "description": "The one refusal of the reader path. A link that never existed, a revoked link, an expired link and a wrong password all take this body, so the answer states nothing about the link. The shape is closed and every member that could carry a difference is fixed, so a later change cannot add a word that tells the four causes apart. The body names no note, no folder, no account and no identifier of the product.",
        "additionalProperties": false,
        "required": [
          "type",
          "title",
          "status",
          "detail",
          "instance",
          "code",
          "requestId"
        ],
        "properties": {
          "type": {
            "type": "string",
            "readOnly": true,
            "description": "Stable URI reference that identifies the problem type.",
            "const": "https://notesapp.invalid/problems/published_link_unavailable",
            "format": "uri-reference",
            "maxLength": 256
          },
          "title": {
            "type": "string",
            "readOnly": true,
            "description": "The one sentence of this refusal. It repeats the detail, because a difference between the two would be a place to hide a cause.",
            "const": "This link is not available.",
            "maxLength": 256
          },
          "status": {
            "type": "integer",
            "readOnly": true,
            "description": "Always 404, for each of the four causes.",
            "const": 404
          },
          "detail": {
            "type": "string",
            "readOnly": true,
            "description": "The one sentence of this refusal.",
            "const": "This link is not available.",
            "maxLength": 1024
          },
          "instance": {
            "type": "string",
            "readOnly": true,
            "description": "Address of the request, without its query. It repeats what the caller sent and it adds nothing.",
            "format": "uri-reference",
            "maxLength": 1024
          },
          "code": {
            "type": "string",
            "readOnly": true,
            "description": "The one code of every reader refusal.",
            "const": "published_link_unavailable",
            "maxLength": 64
          },
          "requestId": {
            "type": "string",
            "readOnly": true,
            "description": "Identifier of the request, repeated in the x-request-id header.",
            "minLength": 1,
            "maxLength": 128
          }
        }
      },
      "PublishedReportFormInput": {
        "type": "object",
        "description": "The fields of the report form of a published page. The page holds no script, so the browser sends the fields in the form encoding of HTML.",
        "additionalProperties": false,
        "required": [
          "reason"
        ],
        "properties": {
          "reason": {
            "$ref": "#/components/schemas/ReportReason"
          },
          "note": {
            "type": "string",
            "writeOnly": true,
            "description": "What the reader adds for the administrator. An empty value is the same as no note.",
            "maxLength": 2000
          }
        }
      },
      "PublishedScope": {
        "description": "What one published link opens.",
        "oneOf": [
          {
            "$ref": "#/components/schemas/PublishedNoteScope"
          },
          {
            "$ref": "#/components/schemas/PublishedFolderScope"
          }
        ]
      },
      "PublishedSecret": {
        "type": "string",
        "description": "One secret of a reader, as it travels in the address of a published link. The token is a path segment and the reading ticket is a query value, and the server compares a digest of what it received with a digest at rest. A value of any other shape therefore opens nothing, exactly as an unknown value opens nothing, so this shape stays wide on purpose: a reader that mistypes an address must read the one answer of the reader path and never a refusal that tells it that the shape was wrong. The shape of the value that the server draws is in PublishedTokenValue. The length is not bounded here, because the server digests the value and never stores it, and the whole address is already bounded by the header byte limit of the deployment. A second bound would answer a long address with a refusal instead of the one page of decision 0047.",
        "minLength": 1,
        "pattern": "^[^/?#]+$"
      },
      "PublishedTokenValue": {
        "type": "string",
        "description": "The opaque value that opens one published link. The server draws it at random, so it names no note, no folder and no account. The server keeps only a digest of it, and it appears once, in the address that the owner copies.",
        "pattern": "^[A-Za-z0-9_-]{22,64}$",
        "minLength": 22,
        "maxLength": 64
      },
      "PurgeFilesInput": {
        "type": "object",
        "description": "Payload to permanently purge files.",
        "additionalProperties": false,
        "required": [
          "mutationId",
          "fileIds"
        ],
        "properties": {
          "mutationId": {
            "$ref": "#/components/schemas/Uuid"
          },
          "fileIds": {
            "type": "array",
            "minItems": 1,
            "maxItems": 1000,
            "items": {
              "$ref": "#/components/schemas/Uuid"
            }
          }
        }
      },
      "PurgePreview": {
        "type": "object",
        "description": "Summary preview of an intended permanent file purge.",
        "additionalProperties": false,
        "required": [
          "fileIds",
          "revisionIds",
          "contentDigests",
          "attachmentObjectIds",
          "blockingReferences",
          "dependentRevisionCount",
          "reclaimableBytes",
          "canPurge"
        ],
        "properties": {
          "fileIds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          "revisionIds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          "contentDigests": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "attachmentObjectIds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          "blockingReferences": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BlockingReference"
            }
          },
          "dependentRevisionCount": {
            "type": "integer"
          },
          "reclaimableBytes": {
            "type": "integer"
          },
          "canPurge": {
            "type": "boolean"
          }
        }
      },
      "PurgedFiles": {
        "type": "object",
        "description": "Outcome of executed permanent file purge.",
        "additionalProperties": false,
        "required": [
          "mutationId",
          "purgedFileIds",
          "purgedRevisionIds",
          "reclaimedBytes"
        ],
        "properties": {
          "mutationId": {
            "$ref": "#/components/schemas/Uuid"
          },
          "purgedFileIds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          "purgedRevisionIds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          "reclaimedBytes": {
            "type": "integer"
          }
        }
      },
      "ReadinessCheck": {
        "type": "object",
        "description": "State of one startup requirement.",
        "additionalProperties": false,
        "required": [
          "name",
          "status"
        ],
        "properties": {
          "name": {
            "type": "string",
            "readOnly": true,
            "description": "Stable name of the requirement, for example configuration.",
            "minLength": 1,
            "maxLength": 64
          },
          "status": {
            "type": "string",
            "readOnly": true,
            "description": "State of this requirement.",
            "enum": [
              "ok",
              "degraded"
            ]
          },
          "detail": {
            "type": "string",
            "readOnly": true,
            "description": "Operator readable explanation. The field is absent in a summary report and it never contains note content or a secret.",
            "maxLength": 512
          }
        }
      },
      "ReadinessReport": {
        "type": "object",
        "description": "Readiness report of every startup requirement.",
        "additionalProperties": false,
        "required": [
          "status",
          "checks"
        ],
        "properties": {
          "status": {
            "type": "string",
            "readOnly": true,
            "description": "Overall readiness. The value is degraded when at least one check is degraded.",
            "enum": [
              "ok",
              "degraded"
            ]
          },
          "checks": {
            "type": "array",
            "readOnly": true,
            "description": "One entry for every startup requirement that was checked.",
            "minItems": 1,
            "maxItems": 32,
            "items": {
              "$ref": "#/components/schemas/ReadinessCheck"
            }
          }
        }
      },
      "ReadingTicketGrant": {
        "type": "object",
        "description": "The reading ticket of one link. The reader carries it in the address of every later call to that link. No cookie is set.",
        "additionalProperties": false,
        "required": [
          "ticket",
          "expiresAt"
        ],
        "properties": {
          "ticket": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ReadingTicketValue"
              }
            ],
            "readOnly": true,
            "description": "The ticket. It opens this one link and nothing else."
          },
          "expiresAt": {
            "type": "string",
            "readOnly": true,
            "description": "Instant at which the ticket stops. A read does not move it, so a reader that returns later gives the password again.",
            "format": "date-time",
            "maxLength": 64
          }
        }
      },
      "ReadingTicketValue": {
        "type": "string",
        "description": "The value that a reader carries after it gives the password of a link. It is bound to that one link, it lives 12 hours, and a read does not move its expiry. The server keeps only a digest of it.",
        "pattern": "^[A-Za-z0-9_-]{22,64}$",
        "minLength": 22,
        "maxLength": 64
      },
      "Registered": {
        "type": "object",
        "description": "Confirmation that the account exists and that its session started.",
        "additionalProperties": false,
        "required": [
          "registered"
        ],
        "properties": {
          "registered": {
            "type": "boolean",
            "readOnly": true,
            "description": "Always true."
          }
        }
      },
      "RegistrationInput": {
        "type": "object",
        "description": "What a person gives to make an account. The address comes from the invitation.",
        "additionalProperties": false,
        "required": [
          "invitation",
          "password"
        ],
        "properties": {
          "invitation": {
            "allOf": [
              {
                "$ref": "#/components/schemas/InvitationToken"
              }
            ],
            "description": "The token from the invitation link."
          },
          "password": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Password"
              }
            ],
            "description": "The password of the new account."
          },
          "name": {
            "type": "string",
            "description": "The display name of the new account.",
            "minLength": 1,
            "maxLength": 256
          },
          "consent": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ConsentInput"
              }
            ],
            "description": "The versions of the terms and of the privacy notice that the person accepted. It is required when the installation names both documents (record 0120)."
          }
        }
      },
      "RegistrationPolicy": {
        "type": "string",
        "description": "Who can make an account. With invitation, only a person with a valid invitation can. With open, a person who proves their address can.",
        "enum": [
          "invitation",
          "open"
        ]
      },
      "Removed": {
        "type": "object",
        "description": "Confirmation that the named record no longer exists.",
        "additionalProperties": false,
        "required": [
          "removed"
        ],
        "properties": {
          "removed": {
            "type": "boolean",
            "readOnly": true,
            "description": "Always true. The record no longer exists."
          }
        }
      },
      "ReportReason": {
        "type": "string",
        "description": "Why a reader reports a published link. The list is fixed, so an administrator can sort the reports.",
        "enum": [
          "phishing",
          "malware",
          "illegal",
          "harassment",
          "spam",
          "other"
        ]
      },
      "RestoreFileInput": {
        "type": "object",
        "description": "Payload to bring one deleted file back into the file tree.",
        "additionalProperties": false,
        "required": [
          "mutationId",
          "deviceId",
          "clientTime",
          "revisionId"
        ],
        "properties": {
          "mutationId": {
            "$ref": "#/components/schemas/Uuid"
          },
          "deviceId": {
            "$ref": "#/components/schemas/DeviceId"
          },
          "clientTime": {
            "type": "string",
            "format": "date-time",
            "minLength": 20,
            "maxLength": 64
          },
          "revisionId": {
            "$ref": "#/components/schemas/Uuid"
          }
        }
      },
      "RestoreRevisionInput": {
        "type": "object",
        "description": "Payload to restore a file to an earlier historic revision.",
        "additionalProperties": false,
        "required": [
          "mutationId",
          "deviceId",
          "clientTime",
          "targetRevisionId",
          "revisionId"
        ],
        "properties": {
          "mutationId": {
            "$ref": "#/components/schemas/Uuid"
          },
          "deviceId": {
            "$ref": "#/components/schemas/DeviceId"
          },
          "clientTime": {
            "type": "string",
            "format": "date-time",
            "minLength": 20,
            "maxLength": 64
          },
          "targetRevisionId": {
            "$ref": "#/components/schemas/Uuid"
          },
          "expectedHead": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "revisionId": {
            "$ref": "#/components/schemas/Uuid"
          },
          "path": {
            "$ref": "#/components/schemas/FilePath"
          },
          "message": {
            "$ref": "#/components/schemas/CheckpointMessage"
          }
        }
      },
      "RevisionInput": {
        "type": "object",
        "description": "One revision that a client submits inside a changeset.",
        "additionalProperties": false,
        "required": [
          "revisionId",
          "fileId",
          "parents",
          "path",
          "deleted",
          "content",
          "clientTime"
        ],
        "properties": {
          "revisionId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "description": "Identifier that the client assigned to this revision."
          },
          "fileId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "description": "The file that this revision belongs to."
          },
          "parents": {
            "type": "array",
            "description": "The parents of this revision. A parent is either an earlier revision of the same file in this submission or an accepted revision of that file.",
            "maxItems": 2,
            "items": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          "path": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FilePath"
              }
            ],
            "description": "The path that the file has after this revision."
          },
          "deleted": {
            "type": "boolean",
            "description": "True for a tombstone, which records a deletion."
          },
          "content": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ContentInput"
              }
            ],
            "description": "The content of this revision."
          },
          "clientTime": {
            "type": "string",
            "description": "The device clock at the moment of the change.",
            "format": "date-time",
            "minLength": 20,
            "maxLength": 64
          },
          "message": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CheckpointMessage"
              }
            ],
            "description": "Name of this checkpoint, or null."
          },
          "restoredFrom": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ],
            "description": "The historic revision that this one restores, or null."
          }
        }
      },
      "Role": {
        "type": "string",
        "description": "The role of an account in one workspace. Every workspace has one member, its owner, so the only role is owner. The installation role of an account is a separate fact and grants no workspace access.",
        "enum": [
          "owner"
        ]
      },
      "SearchExcerptPart": {
        "type": "object",
        "description": "One part of a search excerpt. A part with `marked` true is a word that the query matched. The excerpt quotes the text that a reader sees, with no Markdown mark and no link address, and it carries no markup, so a reader renders every part as text and decides itself how a marked part looks.",
        "additionalProperties": false,
        "required": [
          "text",
          "marked"
        ],
        "properties": {
          "text": {
            "type": "string",
            "readOnly": true,
            "maxLength": 1024
          },
          "marked": {
            "type": "boolean",
            "readOnly": true
          }
        }
      },
      "SearchHit": {
        "type": "object",
        "description": "One accepted live note that matched a search.",
        "additionalProperties": false,
        "required": [
          "fileId",
          "path",
          "revisionId",
          "excerpt"
        ],
        "properties": {
          "fileId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true
          },
          "path": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FilePath"
              }
            ],
            "readOnly": true
          },
          "revisionId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true
          },
          "excerpt": {
            "type": "array",
            "readOnly": true,
            "description": "The matching part of the note, in reading order, as the plain text that a reader sees: no Markdown mark and no link address.",
            "maxItems": 128,
            "items": {
              "$ref": "#/components/schemas/SearchExcerptPart"
            }
          }
        }
      },
      "SearchResults": {
        "type": "object",
        "description": "Search results from current accepted note revisions.",
        "additionalProperties": false,
        "required": [
          "hits"
        ],
        "properties": {
          "hits": {
            "type": "array",
            "readOnly": true,
            "maxItems": 100,
            "items": {
              "$ref": "#/components/schemas/SearchHit"
            }
          }
        }
      },
      "SessionsRevoked": {
        "type": "object",
        "description": "How many sessions ended.",
        "additionalProperties": false,
        "required": [
          "revoked"
        ],
        "properties": {
          "revoked": {
            "type": "integer",
            "readOnly": true,
            "description": "The number of sessions that ended.",
            "minimum": 0
          }
        }
      },
      "SettingSource": {
        "type": "string",
        "description": "Where a group of settings comes from (record 0148). environment is the server environment, which wins and cannot change in the application. application is what an administrator set. none is no setting.",
        "enum": [
          "environment",
          "application",
          "none"
        ]
      },
      "SignUpAccepted": {
        "type": "object",
        "description": "The one answer of a sign-up. It is the same for every address, so it states nothing about the address.",
        "additionalProperties": false,
        "required": [
          "accepted"
        ],
        "properties": {
          "accepted": {
            "type": "boolean",
            "const": true,
            "readOnly": true,
            "description": "The server took the request and sent a message if it could."
          }
        }
      },
      "SignUpChallenge": {
        "type": "object",
        "description": "A challenge of the proof of work of a sign-up. The digest of the value, a colon and the solution must start with `difficulty` zero bits.",
        "additionalProperties": false,
        "required": [
          "challenge",
          "value",
          "difficulty",
          "expiresAt"
        ],
        "properties": {
          "challenge": {
            "type": "string",
            "readOnly": true,
            "description": "The signed challenge, which the sign-up sends back unchanged.",
            "minLength": 1,
            "maxLength": 512,
            "pattern": "^[A-Za-z0-9_.-]+$"
          },
          "value": {
            "type": "string",
            "readOnly": true,
            "description": "The random value whose digest a solution reduces.",
            "minLength": 1,
            "maxLength": 128
          },
          "difficulty": {
            "type": "integer",
            "readOnly": true,
            "description": "How many leading zero bits the digest of a solution needs.",
            "minimum": 8,
            "maximum": 28
          },
          "expiresAt": {
            "type": "string",
            "readOnly": true,
            "description": "Instant after which the challenge counts for nothing.",
            "format": "date-time",
            "maxLength": 64
          }
        }
      },
      "SignUpInput": {
        "type": "object",
        "description": "What a person gives to ask for an account under open registration.",
        "additionalProperties": false,
        "required": [
          "email",
          "password",
          "proof"
        ],
        "properties": {
          "email": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EmailAddress"
              }
            ],
            "description": "The address of the new account. A link goes to it."
          },
          "password": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Password"
              }
            ],
            "description": "The password of the new account."
          },
          "name": {
            "type": "string",
            "description": "The display name of the new account.",
            "minLength": 1,
            "maxLength": 256
          },
          "proof": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SignUpProof"
              }
            ],
            "description": "The proof of work of this sign-up (record 0115)."
          },
          "consent": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ConsentInput"
              }
            ],
            "description": "The versions of the legal documents that the person accepts. It is required when the installation names its documents (record 0120)."
          }
        }
      },
      "SignUpProof": {
        "type": "object",
        "description": "The solution of one challenge of the proof of work.",
        "additionalProperties": false,
        "required": [
          "challenge",
          "solution"
        ],
        "properties": {
          "challenge": {
            "type": "string",
            "description": "The signed challenge, as the server answered it.",
            "minLength": 1,
            "maxLength": 512,
            "pattern": "^[A-Za-z0-9_.-]+$"
          },
          "solution": {
            "type": "string",
            "description": "The solution that the browser found.",
            "minLength": 1,
            "maxLength": 32,
            "pattern": "^[0-9a-z]+$"
          }
        }
      },
      "SnapshotItem": {
        "type": "object",
        "description": "One pinned file of a snapshot. The revision identifier is immutable, so a later commit cannot change what a page shows.",
        "additionalProperties": false,
        "required": [
          "fileId",
          "revisionId",
          "path",
          "kind",
          "deleted"
        ],
        "properties": {
          "fileId": {
            "$ref": "#/components/schemas/Uuid"
          },
          "revisionId": {
            "$ref": "#/components/schemas/Uuid"
          },
          "path": {
            "$ref": "#/components/schemas/FilePath"
          },
          "kind": {
            "type": "string",
            "readOnly": true,
            "description": "Whether the file holds Markdown or an attachment.",
            "enum": [
              "note",
              "attachment"
            ]
          },
          "deleted": {
            "type": "boolean",
            "readOnly": true,
            "description": "Whether the file was deleted when captured. Always false."
          }
        }
      },
      "SnapshotPage": {
        "type": "object",
        "description": "One page of the items that a snapshot captured.",
        "additionalProperties": false,
        "required": [
          "token",
          "cursor",
          "expiresAt",
          "position",
          "nextPosition",
          "totalItems",
          "items"
        ],
        "properties": {
          "token": {
            "type": "string",
            "readOnly": true,
            "description": "The token of the snapshot, echoed for the client.",
            "minLength": 43,
            "maxLength": 43,
            "pattern": "^[A-Za-z0-9_-]{43}$"
          },
          "cursor": {
            "type": "string",
            "readOnly": true,
            "description": "The captured high-water cursor.",
            "minLength": 1,
            "maxLength": 32,
            "pattern": "^[0-9]+$"
          },
          "expiresAt": {
            "type": "string",
            "readOnly": true,
            "description": "Instant at which the snapshot expires.",
            "format": "date-time"
          },
          "position": {
            "type": "integer",
            "readOnly": true,
            "description": "Ordinal of the first item of this page.",
            "minimum": 0
          },
          "nextPosition": {
            "oneOf": [
              {
                "type": "integer",
                "minimum": 0
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "Ordinal of the next page, or null on the last page."
          },
          "totalItems": {
            "type": "integer",
            "readOnly": true,
            "description": "How many items the snapshot holds now.",
            "minimum": 0
          },
          "items": {
            "type": "array",
            "readOnly": true,
            "description": "The captured items of this page, ordered by file.",
            "maxItems": 500,
            "items": {
              "$ref": "#/components/schemas/SnapshotItem"
            }
          }
        }
      },
      "SnapshotStarted": {
        "type": "object",
        "description": "The captured snapshot and its opaque page token.",
        "additionalProperties": false,
        "required": [
          "token",
          "expiresAt",
          "cursor",
          "itemCount",
          "pageSize"
        ],
        "properties": {
          "token": {
            "type": "string",
            "readOnly": true,
            "description": "Opaque token that addresses the materialized pages for 15 minutes.",
            "minLength": 43,
            "maxLength": 43,
            "pattern": "^[A-Za-z0-9_-]{43}$"
          },
          "expiresAt": {
            "type": "string",
            "readOnly": true,
            "description": "Instant at which the snapshot expires.",
            "format": "date-time"
          },
          "cursor": {
            "type": "string",
            "readOnly": true,
            "description": "The captured high-water cursor. A sync client asks for changes after this position.",
            "minLength": 1,
            "maxLength": 32,
            "pattern": "^[0-9]+$"
          },
          "itemCount": {
            "type": "integer",
            "readOnly": true,
            "description": "How many items the snapshot captured.",
            "minimum": 0
          },
          "pageSize": {
            "type": "integer",
            "readOnly": true,
            "description": "The page size stored with the snapshot.",
            "minimum": 1,
            "maximum": 500
          }
        }
      },
      "StartSnapshotInput": {
        "type": "object",
        "description": "Snapshot start payload.",
        "additionalProperties": false,
        "required": [
          "syncVersion"
        ],
        "properties": {
          "syncVersion": {
            "type": "integer",
            "description": "Sync protocol version of the client. Only version 1 is served; any other value is rejected without changing data.",
            "enum": [
              1
            ]
          },
          "pageSize": {
            "type": "integer",
            "description": "Largest number of snapshot items in one page. The server uses 100 when the value is absent and never stores more than 500.",
            "minimum": 1,
            "maximum": 500
          }
        }
      },
      "StartWorkspaceImportInput": {
        "type": "object",
        "description": "The size of the zip archive that one import sends.",
        "additionalProperties": false,
        "required": [
          "size"
        ],
        "properties": {
          "size": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "The bytes of the whole archive. An archive above the bound of one import answers payload_too_large before a part is sent."
          }
        }
      },
      "SupersededHead": {
        "type": "object",
        "description": "One file whose accepted head moved between the read of the client and this changeset. The workspace rebased the save on the current head, so the later save still wins and the head that it passed stays in history. The record carries no text and no path: the accepted revision of the same answer already names the path.",
        "additionalProperties": false,
        "required": [
          "fileId",
          "previousHeadRevisionId",
          "acceptedRevisionId"
        ],
        "properties": {
          "fileId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "The file whose accepted head moved."
          },
          "previousHeadRevisionId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "The accepted head that the client did not see. It is now a history entry of the file, and its text is not lost."
          },
          "acceptedRevisionId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "The revision of this changeset that became the new accepted head of the file."
          }
        }
      },
      "SyncChanges": {
        "type": "object",
        "description": "Ordered incremental changes after a cursor.",
        "additionalProperties": false,
        "required": [
          "changes",
          "nextCursor"
        ],
        "properties": {
          "changes": {
            "type": "array",
            "readOnly": true,
            "description": "Ordered changes after the requested cursor, oldest first. The page holds whole commits only. One commit larger than the requested limit comes as one whole page, and a commit holds at most 1000 records.",
            "maxItems": 1000,
            "items": {
              "$ref": "#/components/schemas/SyncRecord"
            }
          },
          "nextCursor": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncCursorValue"
              }
            ],
            "readOnly": true,
            "description": "The cursor the client sends to continue."
          }
        }
      },
      "SyncCursorValue": {
        "type": "string",
        "description": "One commit ordered position in the feed of a workspace. It is the decimal text of the position, and a reader sends the last one it applied to continue.",
        "minLength": 1,
        "maxLength": 32,
        "pattern": "^[0-9]+$"
      },
      "SyncDocumentRecord": {
        "type": "object",
        "description": "One whole document of a note. The feed emits it when the generation of the note changes, because identities of one generation say nothing about another, and a reader cannot join the two by an update.",
        "additionalProperties": false,
        "required": [
          "kind",
          "cursor",
          "fileId",
          "revisionId",
          "path",
          "deleted",
          "digest",
          "epoch",
          "document"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "description": "Names this record form.",
            "enum": [
              "document"
            ]
          },
          "cursor": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncCursorValue"
              }
            ],
            "readOnly": true,
            "description": "The position of this record in the ordered feed."
          },
          "fileId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "The note that this record states."
          },
          "revisionId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "The accepted revision that this document holds."
          },
          "path": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FilePath"
              }
            ],
            "readOnly": true,
            "description": "The accepted path of the note at this record."
          },
          "deleted": {
            "type": "boolean",
            "readOnly": true,
            "description": "True when the note is in Trash at this record."
          },
          "digest": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ContentDigest"
              }
            ],
            "readOnly": true,
            "description": "Digest of the text that this document derives."
          },
          "epoch": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DocumentEpoch"
              }
            ],
            "readOnly": true,
            "description": "The generation that this document starts for the reader."
          },
          "document": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DocumentUpdate"
              }
            ],
            "readOnly": true,
            "description": "The whole document of the note at this record."
          }
        }
      },
      "SyncMembershipRecord": {
        "type": "object",
        "description": "One change of the membership of the workspace. A reader reads its own access again when it meets one.",
        "additionalProperties": false,
        "required": [
          "kind",
          "cursor",
          "accountId",
          "removed"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "description": "Names this record form.",
            "enum": [
              "membership"
            ]
          },
          "cursor": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncCursorValue"
              }
            ],
            "readOnly": true,
            "description": "The position of this record in the ordered feed."
          },
          "accountId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "The account whose membership changed."
          },
          "removed": {
            "type": "boolean",
            "readOnly": true,
            "description": "True when the account no longer belongs to the workspace."
          }
        }
      },
      "SyncNoticeAccount": {
        "type": "object",
        "description": "The state or the controls of the account of the stream changed, for example it was locked or unlocked (records 0189 and 0201). The client reads the account again. The message names nothing of the change.",
        "additionalProperties": false,
        "required": [
          "kind"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "const": "account"
          }
        }
      },
      "SyncNoticeChanged": {
        "type": "object",
        "description": "A commit changed the feed of one subscribed workspace. The client reads the feed of that workspace through the HTTP operations. The notice carries no cursor and no content, and only an applied feed page moves the stored cursor. A missed or repeated notice changes no result.",
        "additionalProperties": false,
        "required": [
          "kind",
          "generation",
          "workspaceId"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "const": "changed"
          },
          "generation": {
            "$ref": "#/components/schemas/SyncNoticeGeneration"
          },
          "workspaceId": {
            "$ref": "#/components/schemas/Uuid"
          }
        }
      },
      "SyncNoticeGeneration": {
        "type": "integer",
        "description": "The number of one subscription set on one connection. The client raises it for each new set, starting at 1. The server echoes it on every answer and notice for that set, so a late message of an older set cannot act on a newer one.",
        "minimum": 1,
        "maximum": 9007199254740991
      },
      "SyncNoticeProtocol": {
        "type": "string",
        "description": "The WebSocket subprotocol of the sync notice stream. The browser names it when it opens the stream, and the server accepts no other value. A later version gets a new name, so an old client and a new server never read each other's messages.",
        "const": "notesapp.sync.1"
      },
      "SyncNoticeReady": {
        "type": "object",
        "description": "The first message of the server on a new connection. It names the account of the session that opened the stream. The connection holds no subscription until the client sends a set.",
        "additionalProperties": false,
        "required": [
          "kind",
          "accountId"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "const": "ready"
          },
          "accountId": {
            "$ref": "#/components/schemas/Uuid"
          }
        }
      },
      "SyncNoticeReconcile": {
        "type": "object",
        "description": "The server could have missed a commit, for example after its database listener reconnected. The client reads the feed of every workspace of the set.",
        "additionalProperties": false,
        "required": [
          "kind",
          "generation"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "const": "reconcile"
          },
          "generation": {
            "$ref": "#/components/schemas/SyncNoticeGeneration"
          }
        }
      },
      "SyncNoticeRefused": {
        "type": "object",
        "description": "The server refused a subscription set as a whole. The set before it stays in force. `forbidden` means that the account cannot read one workspace of the set, so the client asks the HTTP operations which access it holds. `stale_generation` means that the generation is not above the last one.",
        "additionalProperties": false,
        "required": [
          "kind",
          "generation",
          "reason"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "const": "refused"
          },
          "generation": {
            "$ref": "#/components/schemas/SyncNoticeGeneration"
          },
          "reason": {
            "type": "string",
            "enum": [
              "forbidden",
              "stale_generation"
            ]
          }
        }
      },
      "SyncNoticeStop": {
        "type": "object",
        "description": "The last message before the server closes the stream. The client keeps its local work in every case. `session_ended` means that the session or the account is no longer valid, so the client checks the session through the HTTP operations and does not reconnect. `malformed` means that the client sent a message outside this contract, so it does not reconnect with the same build. `draining` and `overloaded` ask the client to reconnect after a delay. `unavailable` means that the server cannot send notices now, so the client reads the feed on its own schedule and tries the stream again later.",
        "additionalProperties": false,
        "required": [
          "kind",
          "reason"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "const": "stop"
          },
          "reason": {
            "type": "string",
            "enum": [
              "session_ended",
              "malformed",
              "draining",
              "overloaded",
              "unavailable"
            ]
          }
        }
      },
      "SyncNoticeSubscribe": {
        "type": "object",
        "description": "The complete set of workspaces that the client wants notices for. It replaces the set before it as a whole. The server checks the access of the account to every workspace before it accepts the set, and refuses the whole set when one check fails. An empty set stops every notice.",
        "additionalProperties": false,
        "required": [
          "kind",
          "generation",
          "workspaceIds"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "const": "subscribe"
          },
          "generation": {
            "$ref": "#/components/schemas/SyncNoticeGeneration"
          },
          "workspaceIds": {
            "type": "array",
            "description": "Every workspace of the set, at most as many as one workspace list holds.",
            "maxItems": 1000,
            "uniqueItems": true,
            "items": {
              "$ref": "#/components/schemas/Uuid"
            }
          }
        }
      },
      "SyncNoticeSubscribed": {
        "type": "object",
        "description": "The server accepted a subscription set and registered it. A commit after this message sends a notice. The client reads each workspace of the set from its stored cursor after this message, so a commit before it is not lost.",
        "additionalProperties": false,
        "required": [
          "kind",
          "generation"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "const": "subscribed"
          },
          "generation": {
            "$ref": "#/components/schemas/SyncNoticeGeneration"
          }
        }
      },
      "SyncProtocolReport": {
        "type": "object",
        "description": "The sync protocol versions that push and pull accept.",
        "additionalProperties": false,
        "required": [
          "versions"
        ],
        "properties": {
          "versions": {
            "type": "array",
            "readOnly": true,
            "description": "Every served sync protocol version, oldest first. The list is never empty.",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "type": "integer",
              "minimum": 1
            }
          },
          "notificationProtocols": {
            "type": "array",
            "readOnly": true,
            "description": "The notice stream subprotocols that this deployment opens now. The list is empty while this process cannot send notices. A server that omits the member predates the notice stream, so the client reads the feed on its own schedule.",
            "maxItems": 1,
            "uniqueItems": true,
            "items": {
              "$ref": "#/components/schemas/SyncNoticeProtocol"
            }
          }
        }
      },
      "SyncPurgeRecord": {
        "type": "object",
        "description": "One note that the workspace removed for good. Its revisions no longer exist, so the record names the note itself and carries no revision.",
        "additionalProperties": false,
        "required": [
          "kind",
          "cursor",
          "fileId"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "description": "Names this record form.",
            "enum": [
              "purge"
            ]
          },
          "cursor": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncCursorValue"
              }
            ],
            "readOnly": true,
            "description": "The position of this record in the ordered feed."
          },
          "fileId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "The note that the workspace removed for good."
          }
        }
      },
      "SyncRecord": {
        "description": "One record of the ordered feed. The kind states which form applies: the work of one save, a whole document at a new generation, a note that the workspace removed for good, or a change of the membership.",
        "oneOf": [
          {
            "$ref": "#/components/schemas/SyncUpdateRecord"
          },
          {
            "$ref": "#/components/schemas/SyncDocumentRecord"
          },
          {
            "$ref": "#/components/schemas/SyncPurgeRecord"
          },
          {
            "$ref": "#/components/schemas/SyncMembershipRecord"
          }
        ]
      },
      "SyncUpdateRecord": {
        "type": "object",
        "description": "One accepted change of a note, as the work that follows the state the reader already holds. The record binds the update, the derived text digest, the revision, and the generation to one committed state.",
        "additionalProperties": false,
        "required": [
          "kind",
          "cursor",
          "fileId",
          "revisionId",
          "path",
          "deleted",
          "digest",
          "kindOfFile",
          "epoch",
          "update",
          "stateVector"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "description": "Names this record form.",
            "enum": [
              "update"
            ]
          },
          "cursor": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncCursorValue"
              }
            ],
            "readOnly": true,
            "description": "The position of this record in the ordered feed."
          },
          "fileId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "The note that this record changes."
          },
          "revisionId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "The accepted revision that this record carries."
          },
          "path": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FilePath"
              }
            ],
            "readOnly": true,
            "description": "The accepted path of the note after this record."
          },
          "deleted": {
            "type": "boolean",
            "readOnly": true,
            "description": "True when the note is in Trash after this record."
          },
          "kindOfFile": {
            "type": "string",
            "readOnly": true,
            "description": "Whether the record states a note or an attachment.",
            "enum": [
              "note",
              "attachment"
            ]
          },
          "digest": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ContentDigest"
              }
            ],
            "readOnly": true,
            "description": "Digest of the text that the accepted document derives, or of the bytes of an attachment."
          },
          "epoch": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DocumentEpoch"
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "The generation that this update belongs to, or null for an attachment revision, which holds no document."
          },
          "update": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DocumentUpdate"
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "The work that this record adds to the document, or null for an attachment revision."
          },
          "stateVector": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DocumentStateVector"
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "The state vector of the document at this revision, so a reader can ask for exactly the work that it lacks. Null for an attachment."
          }
        }
      },
      "TemplateSettings": {
        "type": "object",
        "description": "The template settings that one member keeps in one workspace.",
        "additionalProperties": false,
        "required": [
          "folder"
        ],
        "properties": {
          "folder": {
            "type": "string",
            "readOnly": true,
            "description": "The folder whose notes are the templates, for example Templates or Work/Templates. A note in a subfolder is a template as well.",
            "minLength": 1,
            "maxLength": 1024
          }
        }
      },
      "TemplateSettingsInput": {
        "type": "object",
        "description": "The template settings to store for the signed in member.",
        "additionalProperties": false,
        "required": [
          "folder"
        ],
        "properties": {
          "folder": {
            "type": "string",
            "description": "The folder whose notes are the templates, as a folder path with no slash at either end.",
            "minLength": 1,
            "maxLength": 1024
          }
        }
      },
      "ThemeColour": {
        "type": "string",
        "description": "One colour of an imported theme, as a hash and six hexadecimal digits.",
        "minLength": 7,
        "maxLength": 7,
        "pattern": "^#[0-9a-fA-F]{6}$"
      },
      "ThemeFamily": {
        "type": "string",
        "description": "Identifier of a theme family in the client theme registry, for example tokyo-night, or custom- and the identifier of a theme that the account imported. An identifier that the client does not know falls back to the default family, so a stored value never stops the page painting.",
        "minLength": 1,
        "maxLength": 64,
        "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
      },
      "ThemeImportInput": {
        "type": "object",
        "description": "A theme to keep for the signed in account: a name and a light palette, a dark palette or both.",
        "additionalProperties": false,
        "required": [
          "name"
        ],
        "minProperties": 2,
        "properties": {
          "name": {
            "$ref": "#/components/schemas/ThemeName"
          },
          "light": {
            "$ref": "#/components/schemas/ThemePalette"
          },
          "dark": {
            "$ref": "#/components/schemas/ThemePalette"
          }
        }
      },
      "ThemeName": {
        "type": "string",
        "description": "The name of an imported theme, as a person reads it.",
        "minLength": 1,
        "maxLength": 60
      },
      "ThemePalette": {
        "type": "object",
        "description": "The light or the dark palette of one imported theme.",
        "additionalProperties": false,
        "required": [
          "tokens",
          "syntax"
        ],
        "properties": {
          "tokens": {
            "$ref": "#/components/schemas/ThemePaletteTokens"
          },
          "syntax": {
            "$ref": "#/components/schemas/ThemePaletteSyntax"
          }
        }
      },
      "ThemePaletteSyntax": {
        "type": "object",
        "description": "The colours of code inside a fenced block of one palette.",
        "additionalProperties": false,
        "required": [
          "keyword",
          "string",
          "comment",
          "number",
          "tag",
          "attribute",
          "heading",
          "link",
          "punctuation"
        ],
        "properties": {
          "keyword": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "string": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "comment": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "number": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "tag": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "attribute": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "heading": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "link": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "punctuation": {
            "$ref": "#/components/schemas/ThemeColour"
          }
        }
      },
      "ThemePaletteTokens": {
        "type": "object",
        "description": "The interface colours of one palette. Each member is a token of the theme registry of the client.",
        "additionalProperties": false,
        "required": [
          "background",
          "surface",
          "surfaceCard",
          "surfaceHover",
          "surfaceActive",
          "text",
          "textStrong",
          "textMuted",
          "accentText",
          "accentFill",
          "accentOnFill",
          "successText",
          "dangerText",
          "dangerFill",
          "onDanger",
          "border",
          "borderSubtle",
          "focus",
          "scrim"
        ],
        "properties": {
          "background": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "surface": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "surfaceCard": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "surfaceHover": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "surfaceActive": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "text": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "textStrong": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "textMuted": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "accentText": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "accentFill": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "accentOnFill": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "successText": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "dangerText": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "dangerFill": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "onDanger": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "border": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "borderSubtle": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "focus": {
            "$ref": "#/components/schemas/ThemeColour"
          },
          "scrim": {
            "$ref": "#/components/schemas/ThemeColour"
          }
        }
      },
      "UnlockPublishedLinkInput": {
        "type": "object",
        "description": "The password of one published link.",
        "additionalProperties": false,
        "required": [
          "password"
        ],
        "properties": {
          "password": {
            "type": "string",
            "writeOnly": true,
            "description": "The password that the owner gave the link. Any value is accepted here and a wrong value takes the one refusal, so the answer states nothing about the link or about the password policy.",
            "minLength": 1,
            "maxLength": 512
          }
        }
      },
      "UpdateFileInput": {
        "type": "object",
        "description": "The identifiers and the new content or path of a file.",
        "additionalProperties": false,
        "required": [
          "revisionId",
          "mutationId",
          "deviceId"
        ],
        "properties": {
          "revisionId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "description": "Identifier of the new revision."
          },
          "mutationId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "description": "Identity of this operation, which makes a retry safe."
          },
          "deviceId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DeviceId"
              }
            ],
            "description": "The device that submitted the change."
          },
          "path": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FilePath"
              }
            ],
            "description": "New path of the file. The path of the expected head is kept when this member is absent."
          },
          "document": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DocumentSave"
              }
            ],
            "description": "The document work of this save. The text of the expected head is kept when this member is absent, which is how a plain rename is written."
          },
          "message": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CheckpointMessage"
              }
            ],
            "description": "Name of this checkpoint, or null."
          }
        }
      },
      "UploadAttachmentInput": {
        "type": "object",
        "description": "Multipart form upload payload that contains the binary attachment file.",
        "additionalProperties": false,
        "required": [
          "file"
        ],
        "properties": {
          "file": {
            "type": "string",
            "format": "binary",
            "description": "Binary bytes of the image attachment."
          }
        }
      },
      "UsageLimit": {
        "type": "string",
        "description": "The limit of the month that refused a request (record 0193), on the codes download_limit and storage_busy only. downloads is the download limit of the account or the download cap of the installation, object_reads the object read cap and object_writes the object write cap of the installation. A client names the cause from it, and never shows the value.",
        "enum": [
          "downloads",
          "object_reads",
          "object_writes"
        ]
      },
      "UsageMonth": {
        "type": "string",
        "description": "One calendar month in UTC, as the year and the month.",
        "minLength": 7,
        "maxLength": 7,
        "pattern": "^[0-9]{4}-(0[1-9]|1[0-2])$"
      },
      "Uuid": {
        "type": "string",
        "description": "A UUID that names one record.",
        "format": "uuid",
        "minLength": 36,
        "maxLength": 36,
        "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
      },
      "ValidationIssue": {
        "type": "object",
        "description": "One value that a boundary check rejected.",
        "additionalProperties": false,
        "required": [
          "path",
          "message"
        ],
        "properties": {
          "path": {
            "type": "string",
            "readOnly": true,
            "description": "JSON Pointer of the rejected value inside its request slot.",
            "maxLength": 256
          },
          "message": {
            "type": "string",
            "readOnly": true,
            "description": "Reason the value was rejected. It never repeats the value.",
            "maxLength": 256
          }
        }
      },
      "Workspace": {
        "type": "object",
        "description": "One workspace as its member sees it.",
        "additionalProperties": false,
        "required": [
          "workspaceId",
          "name",
          "role",
          "personal"
        ],
        "properties": {
          "workspaceId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "Identifier of the workspace."
          },
          "name": {
            "type": "string",
            "readOnly": true,
            "description": "Name of the workspace.",
            "minLength": 1,
            "maxLength": 200
          },
          "role": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Role"
              }
            ],
            "readOnly": true,
            "description": "The role of the reading account in this workspace."
          },
          "personal": {
            "type": "boolean",
            "readOnly": true,
            "description": "True for the workspace that was created with the account."
          }
        }
      },
      "WorkspaceDeletedFileList": {
        "type": "object",
        "description": "One page of the deleted files of a workspace.",
        "additionalProperties": false,
        "required": [
          "files",
          "nextCursor"
        ],
        "properties": {
          "files": {
            "type": "array",
            "readOnly": true,
            "description": "The deleted files of this page, in the requested order.",
            "maxItems": 500,
            "items": {
              "$ref": "#/components/schemas/WorkspaceDeletedFileSummary"
            }
          },
          "nextCursor": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/FilePageToken"
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "Cursor of the next page, or null when this page is the last one. It continues the sort that produced it."
          }
        }
      },
      "WorkspaceDeletedFileSummary": {
        "type": "object",
        "description": "One deleted file of a workspace, without its content.",
        "additionalProperties": false,
        "required": [
          "fileId",
          "path",
          "kind",
          "headRevisionId",
          "createdAt",
          "deletedAt"
        ],
        "properties": {
          "fileId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "Stable identifier of the file. A rename never changes it."
          },
          "path": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FilePath"
              }
            ],
            "readOnly": true,
            "description": "The path that the file held when it was deleted."
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FileKind"
              }
            ],
            "readOnly": true,
            "description": "Whether the file holds Markdown or an attachment."
          },
          "headRevisionId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "The tombstone revision that deleted the file, which is its accepted head and its entity tag. A restore states it as the expected head."
          },
          "createdAt": {
            "type": "string",
            "readOnly": true,
            "description": "Instant at which the file was created.",
            "format": "date-time",
            "maxLength": 64
          },
          "deletedAt": {
            "type": "string",
            "readOnly": true,
            "description": "Instant at which the workspace accepted the deletion.",
            "format": "date-time",
            "maxLength": 64
          }
        }
      },
      "WorkspaceFile": {
        "type": "object",
        "description": "One live file and the content of its accepted head.",
        "additionalProperties": false,
        "required": [
          "fileId",
          "path",
          "kind",
          "headRevisionId",
          "createdAt",
          "updatedAt",
          "head"
        ],
        "properties": {
          "fileId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "Stable identifier of the file."
          },
          "path": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FilePath"
              }
            ],
            "readOnly": true,
            "description": "The accepted path of the file."
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FileKind"
              }
            ],
            "readOnly": true,
            "description": "Whether the file holds Markdown or an attachment."
          },
          "headRevisionId": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "The accepted head, which is also the entity tag."
          },
          "createdAt": {
            "type": "string",
            "readOnly": true,
            "description": "Instant at which the file was created.",
            "format": "date-time",
            "maxLength": 64
          },
          "updatedAt": {
            "type": "string",
            "readOnly": true,
            "description": "Instant at which the workspace accepted the last change.",
            "format": "date-time",
            "maxLength": 64
          },
          "head": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/FileRevision"
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "The head revision with its content, or null for a file that has no accepted revision yet."
          }
        }
      },
      "WorkspaceFileList": {
        "type": "object",
        "description": "One page of the live files of a workspace.",
        "additionalProperties": false,
        "required": [
          "files",
          "nextCursor"
        ],
        "properties": {
          "files": {
            "type": "array",
            "readOnly": true,
            "description": "The files of this page, in the requested order.",
            "maxItems": 500,
            "items": {
              "$ref": "#/components/schemas/WorkspaceFileSummary"
            }
          },
          "nextCursor": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/FilePageToken"
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "Cursor of the next page, or null when this page is the last one. It continues the sort that produced it."
          }
        }
      },
      "WorkspaceFileSummary": {
        "type": "object",
        "description": "One live file of a workspace, without its content.",
        "additionalProperties": false,
        "required": [
          "fileId",
          "path",
          "kind",
          "headRevisionId",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "fileId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "readOnly": true,
            "description": "Stable identifier of the file. A rename never changes it."
          },
          "path": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FilePath"
              }
            ],
            "readOnly": true,
            "description": "The accepted path of the file."
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FileKind"
              }
            ],
            "readOnly": true,
            "description": "Whether the file holds Markdown or an attachment."
          },
          "headRevisionId": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ],
            "readOnly": true,
            "description": "The accepted head of the file, which is also its entity tag, or null for a file that has no accepted revision yet."
          },
          "createdAt": {
            "type": "string",
            "readOnly": true,
            "description": "Instant at which the file was created.",
            "format": "date-time",
            "maxLength": 64
          },
          "updatedAt": {
            "type": "string",
            "readOnly": true,
            "description": "Instant at which the workspace accepted the last change.",
            "format": "date-time",
            "maxLength": 64
          }
        }
      },
      "WorkspaceImportPart": {
        "type": "string",
        "format": "binary",
        "description": "The bytes of one part of a portable workspace zip archive."
      },
      "WorkspaceImportPartReceived": {
        "type": "object",
        "description": "One part of an import that the server stored.",
        "additionalProperties": false,
        "required": [
          "partNumber",
          "size"
        ],
        "properties": {
          "partNumber": {
            "type": "integer",
            "minimum": 1,
            "description": "The place of the part in the archive, from 1."
          },
          "size": {
            "type": "integer",
            "minimum": 1,
            "description": "The bytes of the part that the server stored."
          }
        }
      },
      "WorkspaceImportStarted": {
        "type": "object",
        "description": "An import upload that waits for its parts.",
        "additionalProperties": false,
        "required": [
          "importId",
          "partBytes"
        ],
        "properties": {
          "importId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              }
            ],
            "description": "The identifier that each part and the completion name."
          },
          "partBytes": {
            "type": "integer",
            "minimum": 1,
            "description": "The bytes of each part but the last. The last part holds the rest of the archive."
          }
        }
      },
      "WorkspaceList": {
        "type": "object",
        "description": "Every workspace of the signed in account.",
        "additionalProperties": false,
        "required": [
          "workspaces"
        ],
        "properties": {
          "workspaces": {
            "type": "array",
            "readOnly": true,
            "description": "One entry for each workspace the account belongs to.",
            "maxItems": 1000,
            "items": {
              "$ref": "#/components/schemas/Workspace"
            }
          }
        }
      },
      "WorkspaceNameInput": {
        "type": "object",
        "description": "The name to give a workspace.",
        "additionalProperties": false,
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of the workspace.",
            "minLength": 1,
            "maxLength": 200
          }
        }
      }
    }
  }
}
