5128 lines
135 KiB
JSON
5128 lines
135 KiB
JSON
{
|
|
"openapi": "3.1.0",
|
|
"info": {
|
|
"title": "RawMark API",
|
|
"version": "1",
|
|
"description": "RawMark single-user API. Ordinary JSON uses {code,data,message}, with code=0 for success; HTTP semantics are preserved. Login sessions last a fixed 30 days; API tokens retain read/write permissions. Protected APIs accept Bearer authentication only, not Cookies. Files, downloads, events, 204 responses, and OpenAPI are not wrapped. Messages support Accept-Language: en or zh-CN (selected by q weight; default English), and Content-Language reports the selected language; HTTP statuses and business codes do not change. The /settings locale field stores account language (en or zh-CN); null removes the override."
|
|
},
|
|
"servers": [
|
|
{
|
|
"url": "/api/v1"
|
|
}
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"paths": {
|
|
"/health": {
|
|
"get": {
|
|
"summary": "Health check",
|
|
"tags": [
|
|
"System"
|
|
],
|
|
"security": [
|
|
{}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/Ok"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/openapi.json": {
|
|
"get": {
|
|
"summary": "This document",
|
|
"tags": [
|
|
"System"
|
|
],
|
|
"security": [
|
|
{}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "OpenAPI document",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/auth/state": {
|
|
"get": {
|
|
"summary": "Query initialization status",
|
|
"tags": [
|
|
"Authentication"
|
|
],
|
|
"security": [
|
|
{}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"required": [
|
|
"setUp"
|
|
],
|
|
"properties": {
|
|
"setUp": {
|
|
"type": "boolean"
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/auth/setup": {
|
|
"post": {
|
|
"summary": "Set the initial password and return a Bearer session",
|
|
"tags": [
|
|
"Authentication"
|
|
],
|
|
"security": [
|
|
{}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"password"
|
|
],
|
|
"properties": {
|
|
"password": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"required": [
|
|
"token",
|
|
"expiresAt"
|
|
],
|
|
"properties": {
|
|
"token": {
|
|
"type": "string"
|
|
},
|
|
"expiresAt": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Password too short",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"409": {
|
|
"description": "Already initialized",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"description": "Only uninitialized instances may set a password. The first successful setup signs in automatically; initialized instances return 409."
|
|
}
|
|
},
|
|
"/auth/login": {
|
|
"post": {
|
|
"summary": "Sign in with captcha and password; return a Bearer session",
|
|
"tags": [
|
|
"Authentication"
|
|
],
|
|
"security": [
|
|
{}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"password",
|
|
"captchaId",
|
|
"captchaCode"
|
|
],
|
|
"properties": {
|
|
"password": {
|
|
"type": "string"
|
|
},
|
|
"captchaId": {
|
|
"type": "string"
|
|
},
|
|
"captchaCode": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"required": [
|
|
"token",
|
|
"expiresAt"
|
|
],
|
|
"properties": {
|
|
"token": {
|
|
"type": "string"
|
|
},
|
|
"expiresAt": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Incorrect password",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"429": {
|
|
"description": "Too many failed attempts",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Incorrect, used, or expired captcha (40001/40002)",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/auth/logout": {
|
|
"post": {
|
|
"summary": "Sign out",
|
|
"tags": [
|
|
"Authentication"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"204": {
|
|
"description": "Server session revoked"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/auth/password": {
|
|
"post": {
|
|
"summary": "Change the login password; retain the current session and require other devices to sign in again",
|
|
"tags": [
|
|
"Authentication"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"current": {
|
|
"type": "string"
|
|
},
|
|
"next": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"required": [
|
|
"current",
|
|
"next"
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/Ok"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "New password too short",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Incorrect current password",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"429": {
|
|
"description": "Too many failed attempts",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/settings": {
|
|
"get": {
|
|
"summary": "Application settings (one JSON object shared across devices)",
|
|
"tags": [
|
|
"Settings"
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Settings",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"additionalProperties": true
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"patch": {
|
|
"summary": "Merge settings changes",
|
|
"tags": [
|
|
"Settings"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"description": "Merge top-level keys: supplied values replace existing values, and null removes a key. On success, broadcast a settings event over WebSocket. pinnedTabs stores vault-relative Markdown paths shared across devices; an empty array explicitly clears pins, while an absent key allows the browser to migrate legacy local pins. Concurrent replacements use the last server write. trashRetentionDays is a nonnegative safe integer (default 30; 0 disables automatic deletion); null restores the default. Retention applies to existing and new recycle-bin entries. Startup and hourly cleanup permanently delete expired entries based on their original deletion times.",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"additionalProperties": true,
|
|
"properties": {
|
|
"pinnedTabs": {
|
|
"type": [
|
|
"array",
|
|
"null"
|
|
],
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"description": "Ordered vault-relative Markdown paths. Empty means no pins; null removes the setting."
|
|
},
|
|
"trashRetentionDays": {
|
|
"type": [
|
|
"integer",
|
|
"null"
|
|
],
|
|
"minimum": 0,
|
|
"maximum": 9007199254740991,
|
|
"default": 30
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Merged settings",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"additionalProperties": true
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Not a JSON object, or invalid retention period",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"413": {
|
|
"description": "Exceeds 1 MB",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/tree": {
|
|
"get": {
|
|
"summary": "All notes, images, and folders (including .assets, excluding hidden entries and symlinks)",
|
|
"tags": [
|
|
"Notes"
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Directory tree",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"entries": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/Entry"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/files/{path}": {
|
|
"parameters": [
|
|
{
|
|
"name": "path",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "Vault-relative path, such as `folder/note.md` (URL-encode each segment)",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"get": {
|
|
"summary": "Read a note",
|
|
"tags": [
|
|
"Notes"
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Original Markdown",
|
|
"headers": {
|
|
"ETag": {
|
|
"description": "Content revision (rev), enclosed in double quotes",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"content": {
|
|
"text/markdown": {
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"put": {
|
|
"summary": "Write a note (missing parent folders are created automatically)",
|
|
"tags": [
|
|
"Notes"
|
|
],
|
|
"description": "Use the entire request body as note content. `If-Match: \"rev\"` requires the current revision; otherwise return 412 with the latest rev. `If-None-Match: *` requires a new note. Omitting both overwrites unconditionally.",
|
|
"parameters": [
|
|
{
|
|
"name": "If-Match",
|
|
"in": "header",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "If-None-Match",
|
|
"in": "header",
|
|
"schema": {
|
|
"type": "string",
|
|
"enum": [
|
|
"*"
|
|
]
|
|
}
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"text/markdown": {
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Written",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"rev": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"headers": {
|
|
"ETag": {
|
|
"description": "Content revision (rev), enclosed in double quotes",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid path",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"409": {
|
|
"description": "Already exists with If-None-Match",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"412": {
|
|
"description": "Revision conflict",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"type": "integer",
|
|
"minimum": 1
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"error": {
|
|
"type": "string"
|
|
},
|
|
"rev": {
|
|
"type": "string",
|
|
"description": "Current server revision; empty if the file no longer exists"
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"413": {
|
|
"description": "Exceeds 20 MB",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"delete": {
|
|
"summary": "Move a note, image, or folder to the recycle bin (notes include their .assets directory)",
|
|
"tags": [
|
|
"Notes"
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Recycle-bin entry",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/TrashItem"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/move": {
|
|
"post": {
|
|
"summary": "Move or rename a note, image, or folder",
|
|
"tags": [
|
|
"Notes"
|
|
],
|
|
"description": "A note's .assets directory follows its move; renaming rewrites links to that image directory. Image moves/renames preserve the extension and update local references in vault notes. Maintain local inbound links and relative outbound links.",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"from": {
|
|
"type": "string"
|
|
},
|
|
"to": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"required": [
|
|
"from",
|
|
"to"
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/Ok"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Source not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"409": {
|
|
"description": "Destination already exists",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/folders": {
|
|
"post": {
|
|
"summary": "Create a folder",
|
|
"tags": [
|
|
"Notes"
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"path": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"required": [
|
|
"path"
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/Ok"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"409": {
|
|
"description": "Already exists",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/assets": {
|
|
"post": {
|
|
"summary": "Upload an image to the note's sibling assets directory",
|
|
"tags": [
|
|
"Images"
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "note",
|
|
"in": "query",
|
|
"required": false,
|
|
"description": "Owning note path",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "folder",
|
|
"in": "query",
|
|
"description": "Folder upload destination for image management; an empty string means the root. Mutually exclusive with note.",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"multipart/form-data": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"file": {
|
|
"type": "string",
|
|
"format": "binary"
|
|
}
|
|
},
|
|
"required": [
|
|
"file"
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Link relative to the note's folder, ready for Markdown",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"link": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"413": {
|
|
"description": "Exceeds 50 MB",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"description": "Specify exactly one of note and folder. note uploads to the note's sibling assets directory; folder uploads to that folder's assets subdirectory."
|
|
}
|
|
},
|
|
"/assets/import": {
|
|
"post": {
|
|
"summary": "Download a public image to the note's sibling assets directory",
|
|
"tags": [
|
|
"Images"
|
|
],
|
|
"description": "Accept only public HTTP/HTTPS URLs; validate actual connections and redirects. Do not forward login credentials or use environment proxies. At most 5 requests per redirect chain, 2 download attempts, and a 10-second timeout per attempt; retry only timeouts, 429, and 5xx. Support PNG/JPEG/GIF/WebP, detected by file signature, up to 50 MB.",
|
|
"parameters": [
|
|
{
|
|
"name": "note",
|
|
"in": "query",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"url"
|
|
],
|
|
"properties": {
|
|
"url": {
|
|
"type": "string",
|
|
"format": "uri"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Image link relative to the note's folder",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"link": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid source URL or note path, or nonpublic destination",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Owning note not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"413": {
|
|
"description": "Image exceeds 50 MB",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"422": {
|
|
"description": "Unsupported image type",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"502": {
|
|
"description": "Source request failed",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/raw/{path}": {
|
|
"parameters": [
|
|
{
|
|
"name": "path",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "Vault-relative path, such as `folder/note.md` (URL-encode each segment)",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"get": {
|
|
"summary": "Read a raw vault file, such as an image",
|
|
"tags": [
|
|
"Images"
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "File contents",
|
|
"content": {
|
|
"application/octet-stream": {
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "binary"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/search": {
|
|
"get": {
|
|
"summary": "Full-text search",
|
|
"tags": [
|
|
"Notes"
|
|
],
|
|
"description": "Space-separated terms must all match; return at most 50 results.",
|
|
"parameters": [
|
|
{
|
|
"name": "q",
|
|
"in": "query",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Results",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"results": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/SearchResult"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/trash": {
|
|
"get": {
|
|
"summary": "List the recycle bin",
|
|
"tags": [
|
|
"Recycle bin"
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Entries",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"items": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/TrashItem"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"delete": {
|
|
"summary": "Empty all recycle-bin entries",
|
|
"description": "Permanent and irreversible deletion. Report per-entry results and retain failed entries. Read-only tokens are forbidden.",
|
|
"tags": [
|
|
"Recycle bin"
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Per-entry success and failure results",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/TrashPurgeResult"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/trash/{id}/restore": {
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"post": {
|
|
"summary": "Restore from the recycle bin",
|
|
"tags": [
|
|
"Recycle bin"
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Restored entry",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/TrashItem"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"409": {
|
|
"description": "A file already exists at the original path",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/trash/{id}": {
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"delete": {
|
|
"summary": "Permanently delete a recycle-bin entry",
|
|
"tags": [
|
|
"Recycle bin"
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/Ok"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/events": {
|
|
"get": {
|
|
"summary": "WebSocket vault-change events",
|
|
"tags": [
|
|
"Notes"
|
|
],
|
|
"description": "After upgrading to WebSocket, the server sends JSON arrays of Event objects. Clients send no messages.",
|
|
"responses": {
|
|
"101": {
|
|
"description": "Upgrade to WebSocket"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/tokens": {
|
|
"get": {
|
|
"summary": "List API tokens",
|
|
"tags": [
|
|
"API tokens"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Tokens",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"tokens": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/APIToken"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"post": {
|
|
"summary": "Create an API token",
|
|
"tags": [
|
|
"API tokens"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {
|
|
"type": "string"
|
|
},
|
|
"scope": {
|
|
"type": "string",
|
|
"enum": [
|
|
"read",
|
|
"write"
|
|
]
|
|
}
|
|
},
|
|
"required": [
|
|
"name",
|
|
"scope"
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Plaintext token is returned only once",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"token": {
|
|
"type": "string"
|
|
},
|
|
"info": {
|
|
"$ref": "#/components/schemas/APIToken"
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid name or scope",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/tokens/{id}": {
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"delete": {
|
|
"summary": "Revoke an API token",
|
|
"tags": [
|
|
"API tokens"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/Ok"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/themes": {
|
|
"get": {
|
|
"summary": "List themes, including built-in defaults",
|
|
"tags": [
|
|
"Appearance"
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Theme list",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"themes": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/Theme"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/themes/{id}": {
|
|
"get": {
|
|
"summary": "Read theme CSS",
|
|
"tags": [
|
|
"Appearance"
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Theme metadata and CSS",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"allOf": [
|
|
{
|
|
"$ref": "#/components/schemas/Theme"
|
|
},
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"css": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Theme not found or incomplete files"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/plugins": {
|
|
"get": {
|
|
"summary": "List installed plugins and their enabled state",
|
|
"tags": [
|
|
"Plugins"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"plugins": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/Plugin"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Login session required"
|
|
},
|
|
"400": {
|
|
"description": "Invalid request or plugin archive"
|
|
},
|
|
"403": {
|
|
"description": "API tokens are not accepted"
|
|
}
|
|
}
|
|
},
|
|
"post": {
|
|
"summary": "Install a ZIP plugin; disabled by default after installation; reject an existing id",
|
|
"tags": [
|
|
"Plugins"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"201": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/Plugin"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Login session required"
|
|
},
|
|
"400": {
|
|
"description": "Invalid request or plugin archive"
|
|
},
|
|
"403": {
|
|
"description": "API tokens are not accepted"
|
|
},
|
|
"409": {
|
|
"description": "A plugin with this name is already installed"
|
|
},
|
|
"413": {
|
|
"description": "ZIP exceeds 10 MiB"
|
|
}
|
|
},
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"multipart/form-data": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"file"
|
|
],
|
|
"properties": {
|
|
"file": {
|
|
"type": "string",
|
|
"format": "binary"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/plugins/{id}": {
|
|
"patch": {
|
|
"summary": "Change plugin enablement preferences across devices",
|
|
"tags": [
|
|
"Plugins"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/Plugin"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Login session required"
|
|
},
|
|
"400": {
|
|
"description": "Invalid request or plugin archive"
|
|
},
|
|
"403": {
|
|
"description": "API tokens are not accepted"
|
|
},
|
|
"404": {
|
|
"description": "Plugin or requested resource version not found"
|
|
}
|
|
},
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"enabled"
|
|
],
|
|
"properties": {
|
|
"enabled": {
|
|
"type": "boolean"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"delete": {
|
|
"summary": "Disable and uninstall a plugin package while retaining private plugin data",
|
|
"tags": [
|
|
"Plugins"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/Ok"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Login session required"
|
|
},
|
|
"400": {
|
|
"description": "Invalid request or plugin archive"
|
|
},
|
|
"403": {
|
|
"description": "API tokens are not accepted"
|
|
},
|
|
"404": {
|
|
"description": "Plugin or requested resource version not found"
|
|
}
|
|
},
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"/plugins/{id}/data": {
|
|
"get": {
|
|
"summary": "Read private plugin JSON; null when no data exists",
|
|
"tags": [
|
|
"Plugins"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"required": [
|
|
"data"
|
|
],
|
|
"properties": {
|
|
"data": {}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Login session required"
|
|
},
|
|
"400": {
|
|
"description": "Invalid request or plugin archive"
|
|
},
|
|
"403": {
|
|
"description": "API tokens are not accepted"
|
|
},
|
|
"404": {
|
|
"description": "Plugin or requested resource version not found"
|
|
}
|
|
},
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"put": {
|
|
"summary": "Replace private plugin JSON, up to 1 MiB",
|
|
"tags": [
|
|
"Plugins"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"required": [
|
|
"data"
|
|
],
|
|
"properties": {
|
|
"data": {}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Login session required"
|
|
},
|
|
"400": {
|
|
"description": "Invalid request or plugin archive"
|
|
},
|
|
"403": {
|
|
"description": "API tokens are not accepted"
|
|
},
|
|
"404": {
|
|
"description": "Plugin or requested resource version not found"
|
|
}
|
|
},
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"data"
|
|
],
|
|
"properties": {
|
|
"data": {}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/plugins/{id}/assets/{revision}/{path}": {
|
|
"get": {
|
|
"summary": "Read authenticated package resources for a specific installed version",
|
|
"tags": [
|
|
"Plugins"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success"
|
|
},
|
|
"401": {
|
|
"description": "Login session required"
|
|
},
|
|
"400": {
|
|
"description": "Invalid request or plugin archive"
|
|
},
|
|
"403": {
|
|
"description": "API tokens are not accepted"
|
|
},
|
|
"404": {
|
|
"description": "Plugin or requested resource version not found"
|
|
}
|
|
},
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "revision",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "path",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"/import": {
|
|
"post": {
|
|
"summary": "Import Markdown files or a ZIP vault",
|
|
"tags": [
|
|
"Files"
|
|
],
|
|
"description": "Accept multiple .md files or one ZIP, up to 100 MB total. ZIP imports require a new folder name. The destination directory must exist; conflicts do not overwrite. After extraction and organization: up to 512 MiB, 10,000 entries, 20 MiB per note, and 50 MiB per attachment. Markdown and ZIP filenames must be UTF-8. Preserve ZIP hierarchy; normalize local images into sibling assets directories and rewrite references. Remove migrated originals only when unreferenced; retain other attachments. Do not download external links; return warnings for missing local targets.",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"multipart/form-data": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"files"
|
|
],
|
|
"properties": {
|
|
"dir": {
|
|
"type": "string",
|
|
"description": "Destination folder; an empty string means the root"
|
|
},
|
|
"folder": {
|
|
"type": "string",
|
|
"description": "New folder name for ZIP import; leave empty for plain Markdown"
|
|
},
|
|
"files": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string",
|
|
"format": "binary"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"201": {
|
|
"description": "Import succeeded",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"required": [
|
|
"paths",
|
|
"notes",
|
|
"assets",
|
|
"warnings"
|
|
],
|
|
"properties": {
|
|
"paths": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"notes": {
|
|
"type": "integer"
|
|
},
|
|
"assets": {
|
|
"type": "integer",
|
|
"description": "Total retained attachment files, including shared images and other original attachments"
|
|
},
|
|
"warnings": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid format, path, or encoding"
|
|
},
|
|
"401": {
|
|
"description": "Not signed in or invalid token"
|
|
},
|
|
"403": {
|
|
"description": "Read-only tokens cannot import"
|
|
},
|
|
"404": {
|
|
"description": "Destination folder not found"
|
|
},
|
|
"409": {
|
|
"description": "Destination already exists; no overwrite"
|
|
},
|
|
"413": {
|
|
"description": "Upload, expanded-size, entry-count, or per-file size limit exceeded"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/assets/{path}": {
|
|
"put": {
|
|
"summary": "Replace an existing image in place, preserving its path and references",
|
|
"tags": [
|
|
"Images"
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "path",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "Image path within the vault",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"description": "The multipart file extension must match the target image. Do not create new files; maximum 50 MB. The old image is not sent to the recycle bin.",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"multipart/form-data": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"file": {
|
|
"type": "string",
|
|
"format": "binary"
|
|
}
|
|
},
|
|
"required": [
|
|
"file"
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Replacement succeeded",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/Ok"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid path, empty file, or mismatched extension"
|
|
},
|
|
"404": {
|
|
"description": "Target image not found"
|
|
},
|
|
"413": {
|
|
"description": "Exceeds 50 MB"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/export": {
|
|
"post": {
|
|
"summary": "Export original Markdown and local attachments",
|
|
"description": "Accept a nonempty path list. Return .md for a single note without attachments; folders, multiple selections, or notes with attachments return ZIP. ZIP preserves vault-relative paths. Do not download external resources or follow unselected notes. Missing attachments or invalid paths return errors. This POST does not modify data and accepts read-only tokens.",
|
|
"tags": [
|
|
"Files"
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"paths"
|
|
],
|
|
"properties": {
|
|
"paths": {
|
|
"type": "array",
|
|
"minItems": 1,
|
|
"items": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Original Markdown or ZIP attachment",
|
|
"content": {
|
|
"application/zip": {
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "binary"
|
|
}
|
|
},
|
|
"text/markdown": {
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid path"
|
|
},
|
|
"404": {
|
|
"description": "File or attachment not found"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/metadata": {
|
|
"get": {
|
|
"summary": "Read the note-relationship, tag, and resource-reference index",
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Index readiness and metadata list, excluding note contents",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"required": [
|
|
"notes",
|
|
"ready"
|
|
],
|
|
"properties": {
|
|
"notes": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/NoteMetadata"
|
|
}
|
|
},
|
|
"ready": {
|
|
"type": "boolean"
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/assets/cleanup": {
|
|
"post": {
|
|
"summary": "Recheck vault-wide references and move unreferenced images to the recycle bin",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"paths"
|
|
],
|
|
"properties": {
|
|
"paths": {
|
|
"type": "array",
|
|
"minItems": 1,
|
|
"maxItems": 1000,
|
|
"items": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Images moved to the recycle bin and reasons for skipped items",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/CleanupImagesResult"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid request or note metadata prevents reference verification"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/tree-icon": {
|
|
"put": {
|
|
"summary": "Set a file or folder icon; null restores the default",
|
|
"tags": [
|
|
"Files"
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"path",
|
|
"icon"
|
|
],
|
|
"properties": {
|
|
"path": {
|
|
"type": "string"
|
|
},
|
|
"icon": {
|
|
"oneOf": [
|
|
{
|
|
"$ref": "#/components/schemas/TreeIcon"
|
|
},
|
|
{
|
|
"type": "null"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/Ok"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid path or icon"
|
|
},
|
|
"404": {
|
|
"description": "File not found"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/fonts": {
|
|
"get": {
|
|
"summary": "List imported fonts",
|
|
"tags": [
|
|
"Settings"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"required": [
|
|
"fonts"
|
|
],
|
|
"properties": {
|
|
"fonts": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/CustomFont"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Not signed in"
|
|
},
|
|
"403": {
|
|
"description": "Login sessions only"
|
|
}
|
|
}
|
|
},
|
|
"post": {
|
|
"summary": "Import a font with content deduplication (TTF/OTF/WOFF/WOFF2, up to 30 MB)",
|
|
"tags": [
|
|
"Settings"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"201": {
|
|
"description": "New font imported",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/CustomFont"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Not signed in"
|
|
},
|
|
"403": {
|
|
"description": "Login sessions only"
|
|
},
|
|
"200": {
|
|
"description": "Identical font contents already exist; return the original font",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/CustomFont"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"multipart/form-data": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"file"
|
|
],
|
|
"properties": {
|
|
"file": {
|
|
"type": "string",
|
|
"format": "binary"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/fonts/{id}": {
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"delete": {
|
|
"summary": "Delete an imported font and reset interface, text, and code fonts using it to Maple; Maple cannot be deleted",
|
|
"tags": [
|
|
"Settings"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/Ok"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Not signed in"
|
|
},
|
|
"403": {
|
|
"description": "Login sessions only"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/fonts/{id}/file": {
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"get": {
|
|
"summary": "Read an imported font file",
|
|
"tags": [
|
|
"Settings"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success"
|
|
},
|
|
"401": {
|
|
"description": "Not signed in"
|
|
},
|
|
"403": {
|
|
"description": "Login sessions only"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/storage": {
|
|
"get": {
|
|
"summary": "Calculate storage usage on demand",
|
|
"description": "Login sessions only. Count regular-file bytes in the data directory and actual vault, deduplicating nested roots and ignoring internal symlinks. Attachments/recycle bin are subsets of the vault and do not add to totalSize twice. calculatedAt is the completion time in Unix milliseconds. Scanning failures return errors, not partial results.",
|
|
"tags": [
|
|
"Settings"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Storage totals",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/StorageUsage"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "Login sessions only"
|
|
},
|
|
"500": {
|
|
"description": "Scan failed"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/maintenance/status": {
|
|
"get": {
|
|
"summary": "Maintenance status",
|
|
"tags": [
|
|
"Maintenance"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/MaintenanceStatus"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Not signed in",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "API tokens are not accepted",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/maintenance/export/{kind}": {
|
|
"post": {
|
|
"summary": "Export a full instance or settings archive",
|
|
"tags": [
|
|
"Maintenance"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "ZIP download",
|
|
"content": {
|
|
"application/zip": {
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "binary"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid operation or input",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Not signed in",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "API tokens are not accepted",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Maintenance in progress, insufficient disk space, or operation unsupported by the current service",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Filesystem, database, or other internal failure",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"parameters": [
|
|
{
|
|
"name": "kind",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"/maintenance/notes/export": {
|
|
"post": {
|
|
"summary": "Export a plain Markdown vault",
|
|
"tags": [
|
|
"Maintenance"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "ZIP download",
|
|
"content": {
|
|
"application/zip": {
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "binary"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid operation or input",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Not signed in",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "API tokens are not accepted",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Maintenance in progress, insufficient disk space, or operation unsupported by the current service",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Filesystem, database, or other internal failure",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/maintenance/uploads": {
|
|
"post": {
|
|
"summary": "Create a backup upload, up to 2 GiB compressed and 8 MiB per chunk",
|
|
"tags": [
|
|
"Maintenance"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"400": {
|
|
"description": "Invalid operation or input",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Not signed in",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "API tokens are not accepted",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Maintenance in progress, insufficient disk space, or operation unsupported by the current service",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"201": {
|
|
"description": "Return upload id",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"required": [
|
|
"id"
|
|
],
|
|
"properties": {
|
|
"id": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Filesystem, database, or other internal failure",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"kind",
|
|
"size"
|
|
],
|
|
"properties": {
|
|
"kind": {
|
|
"type": "string",
|
|
"enum": [
|
|
"full",
|
|
"settings"
|
|
]
|
|
},
|
|
"size": {
|
|
"type": "integer",
|
|
"minimum": 1,
|
|
"maximum": 2147483648
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/maintenance/uploads/{id}": {
|
|
"put": {
|
|
"summary": "Append backup chunks sequentially",
|
|
"tags": [
|
|
"Maintenance"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"required": [
|
|
"offset"
|
|
],
|
|
"properties": {
|
|
"offset": {
|
|
"type": "integer"
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid operation or input",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Not signed in",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "API tokens are not accepted",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Maintenance in progress, insufficient disk space, or operation unsupported by the current service",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Filesystem, database, or other internal failure",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "Upload-Offset",
|
|
"in": "header",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "integer",
|
|
"minimum": 0
|
|
}
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/octet-stream": {
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "binary"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"delete": {
|
|
"summary": "Cancel an upload owned by the current session",
|
|
"tags": [
|
|
"Maintenance"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/Ok"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid operation or input",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Not signed in",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "API tokens are not accepted",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Maintenance in progress, insufficient disk space, or operation unsupported by the current service",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Filesystem, database, or other internal failure",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"/maintenance/uploads/{id}/validate": {
|
|
"post": {
|
|
"summary": "Validate an archive and produce a summary, up to 8 GiB expanded and 100,000 entries",
|
|
"tags": [
|
|
"Maintenance"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/BackupSummary"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid operation or input",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Not signed in",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "API tokens are not accepted",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Maintenance in progress, insufficient disk space, or operation unsupported by the current service",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Filesystem, database, or other internal failure",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"/maintenance/settings/import": {
|
|
"post": {
|
|
"summary": "Import confirmed settings and resources after creating a backup",
|
|
"tags": [
|
|
"Maintenance"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/Ok"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid operation or input",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Not signed in",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "API tokens are not accepted",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Maintenance in progress, insufficient disk space, or operation unsupported by the current service",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Filesystem, database, or other internal failure",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"confirmed",
|
|
"id"
|
|
],
|
|
"properties": {
|
|
"confirmed": {
|
|
"type": "boolean",
|
|
"const": true
|
|
},
|
|
"id": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/maintenance/settings/reset": {
|
|
"post": {
|
|
"summary": "Reset confirmed preferences while retaining plugin storage",
|
|
"description": "Reset application preferences and plugin activation while preserving plugin data and credentials. Store pinnedTabs as an explicit empty array so legacy browser caches cannot migrate cleared pins back to the server.",
|
|
"tags": [
|
|
"Maintenance"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/Ok"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid operation or input",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Not signed in",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "API tokens are not accepted",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Maintenance in progress, insufficient disk space, or operation unsupported by the current service",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Filesystem, database, or other internal failure",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"confirmed"
|
|
],
|
|
"properties": {
|
|
"confirmed": {
|
|
"type": "boolean",
|
|
"const": true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/maintenance/restore": {
|
|
"post": {
|
|
"summary": "Restore a confirmed full instance after backup; require signing in again",
|
|
"tags": [
|
|
"Maintenance"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"400": {
|
|
"description": "Invalid operation or input",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Not signed in",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "API tokens are not accepted",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Maintenance in progress, insufficient disk space, or operation unsupported by the current service",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"202": {
|
|
"description": "Restore submitted; the service will briefly enter maintenance and require signing in again",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"required": [
|
|
"restarting"
|
|
],
|
|
"properties": {
|
|
"restarting": {
|
|
"type": "boolean"
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Filesystem, database, or other internal failure",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"confirmed",
|
|
"id"
|
|
],
|
|
"properties": {
|
|
"confirmed": {
|
|
"type": "boolean",
|
|
"const": true
|
|
},
|
|
"id": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/maintenance/index/{operation}": {
|
|
"post": {
|
|
"summary": "Optimize or rebuild the index",
|
|
"tags": [
|
|
"Maintenance"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/Ok"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid operation or input",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Not signed in",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "API tokens are not accepted",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Maintenance in progress, insufficient disk space, or operation unsupported by the current service",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Filesystem, database, or other internal failure",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"parameters": [
|
|
{
|
|
"name": "operation",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"/maintenance/temp/clear": {
|
|
"post": {
|
|
"summary": "Clean unused application temporary files",
|
|
"tags": [
|
|
"Maintenance"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"$ref": "#/components/schemas/ClearTempResult"
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid operation or input",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Not signed in",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "API tokens are not accepted",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Maintenance in progress, insufficient disk space, or operation unsupported by the current service",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Filesystem, database, or other internal failure",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/maintenance/logs/export": {
|
|
"post": {
|
|
"summary": "Export application logs and a runtime summary",
|
|
"tags": [
|
|
"Maintenance"
|
|
],
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "ZIP download",
|
|
"content": {
|
|
"application/zip": {
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "binary"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid operation or input",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Not signed in",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "API tokens are not accepted",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Maintenance in progress, insufficient disk space, or operation unsupported by the current service",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Filesystem, database, or other internal failure",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/auth/me": {
|
|
"get": {
|
|
"summary": "Restore login-session identity and permissions",
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"required": [
|
|
"permissions",
|
|
"expiresAt"
|
|
],
|
|
"properties": {
|
|
"permissions": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"expiresAt": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Invalid or expired login credential",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "Login session required; API tokens cannot call this endpoint",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/auth/captcha": {
|
|
"post": {
|
|
"summary": "Issue a single-use sign-in captcha valid for 5 minutes",
|
|
"security": [
|
|
{}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [],
|
|
"properties": {
|
|
"replaceId": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"required": [
|
|
"captchaId",
|
|
"imageDataUrl",
|
|
"expiresAt"
|
|
],
|
|
"properties": {
|
|
"captchaId": {
|
|
"type": "string"
|
|
},
|
|
"imageDataUrl": {
|
|
"type": "string"
|
|
},
|
|
"expiresAt": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"429": {
|
|
"description": "Captcha issuance rate or capacity limit reached",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/auth/tickets": {
|
|
"post": {
|
|
"summary": "Issue resource-read or one-use event tickets bound to the current session",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"kind"
|
|
],
|
|
"properties": {
|
|
"kind": {
|
|
"enum": [
|
|
"images",
|
|
"fonts",
|
|
"plugin",
|
|
"events"
|
|
]
|
|
},
|
|
"pluginId": {
|
|
"type": "string"
|
|
},
|
|
"revision": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Success",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"const": 0
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"required": [
|
|
"url",
|
|
"expiresAt"
|
|
],
|
|
"properties": {
|
|
"url": {
|
|
"type": "string"
|
|
},
|
|
"expiresAt": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
}
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Invalid or expired login credential",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "Login session required; API tokens cannot call this endpoint",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/resources/{ticket}/{kind}/{path}": {
|
|
"get": {
|
|
"summary": "Restricted native resource. Event tickets are single-use and expire after 60 seconds; other tickets expire with the parent session. Check the parent session on every request.",
|
|
"security": [
|
|
{}
|
|
],
|
|
"parameters": [
|
|
{
|
|
"name": "ticket",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "kind",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "path",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Raw resource contents"
|
|
},
|
|
"101": {
|
|
"description": "WebSocket event upgrade"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"components": {
|
|
"securitySchemes": {
|
|
"bearer": {
|
|
"type": "http",
|
|
"scheme": "bearer",
|
|
"description": "API token (prefixed with rm_)"
|
|
}
|
|
},
|
|
"schemas": {
|
|
"Error": {
|
|
"type": "object",
|
|
"required": [
|
|
"code",
|
|
"data",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"code": {
|
|
"type": "integer",
|
|
"minimum": 1
|
|
},
|
|
"data": {
|
|
"type": [
|
|
"object",
|
|
"null"
|
|
]
|
|
},
|
|
"message": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"Ok": {
|
|
"type": "object",
|
|
"properties": {
|
|
"ok": {
|
|
"type": "boolean"
|
|
}
|
|
},
|
|
"required": [
|
|
"ok"
|
|
]
|
|
},
|
|
"Entry": {
|
|
"type": "object",
|
|
"properties": {
|
|
"path": {
|
|
"type": "string"
|
|
},
|
|
"dir": {
|
|
"type": "boolean"
|
|
},
|
|
"size": {
|
|
"type": "integer"
|
|
},
|
|
"mtime": {
|
|
"type": "integer",
|
|
"description": "Modification time (Unix milliseconds)"
|
|
},
|
|
"icon": {
|
|
"$ref": "#/components/schemas/TreeIcon"
|
|
}
|
|
}
|
|
},
|
|
"TrashItem": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {
|
|
"type": "string"
|
|
},
|
|
"path": {
|
|
"type": "string",
|
|
"description": "Original path"
|
|
},
|
|
"dir": {
|
|
"type": "boolean"
|
|
},
|
|
"deletedAt": {
|
|
"type": "integer",
|
|
"description": "Unix milliseconds"
|
|
},
|
|
"assets": {
|
|
"type": "string",
|
|
"description": "Legacy image directory retained with the entry; optional"
|
|
}
|
|
},
|
|
"required": [
|
|
"id",
|
|
"path",
|
|
"dir",
|
|
"deletedAt"
|
|
]
|
|
},
|
|
"SearchResult": {
|
|
"type": "object",
|
|
"properties": {
|
|
"path": {
|
|
"type": "string"
|
|
},
|
|
"line": {
|
|
"type": "integer",
|
|
"description": "First matching line, starting at 1; 0 when only the path matches"
|
|
},
|
|
"snippet": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"Event": {
|
|
"type": "object",
|
|
"description": "tree: directory structure changed; changed: contents changed (rev is the new revision); deleted: deletion; moved: move (from -> path); settings: settings changed",
|
|
"properties": {
|
|
"type": {
|
|
"type": "string",
|
|
"enum": [
|
|
"tree",
|
|
"changed",
|
|
"deleted",
|
|
"moved",
|
|
"settings"
|
|
]
|
|
},
|
|
"path": {
|
|
"type": "string"
|
|
},
|
|
"from": {
|
|
"type": "string"
|
|
},
|
|
"rev": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"APIToken": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {
|
|
"type": "string"
|
|
},
|
|
"name": {
|
|
"type": "string"
|
|
},
|
|
"scope": {
|
|
"type": "string",
|
|
"enum": [
|
|
"read",
|
|
"write"
|
|
]
|
|
},
|
|
"createdAt": {
|
|
"type": "integer"
|
|
},
|
|
"lastUsedAt": {
|
|
"type": "integer",
|
|
"description": "Unix milliseconds; 0 means never used"
|
|
}
|
|
}
|
|
},
|
|
"Theme": {
|
|
"type": "object",
|
|
"required": [
|
|
"id",
|
|
"name",
|
|
"version"
|
|
],
|
|
"properties": {
|
|
"id": {
|
|
"type": "string"
|
|
},
|
|
"name": {
|
|
"type": "string"
|
|
},
|
|
"version": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"Plugin": {
|
|
"type": "object",
|
|
"required": [
|
|
"id",
|
|
"name",
|
|
"version",
|
|
"apiVersion",
|
|
"revision",
|
|
"enabled"
|
|
],
|
|
"properties": {
|
|
"id": {
|
|
"type": "string"
|
|
},
|
|
"name": {
|
|
"type": "string"
|
|
},
|
|
"version": {
|
|
"type": "string"
|
|
},
|
|
"revision": {
|
|
"type": "string"
|
|
},
|
|
"apiVersion": {
|
|
"type": "integer",
|
|
"const": 1
|
|
},
|
|
"enabled": {
|
|
"type": "boolean"
|
|
}
|
|
}
|
|
},
|
|
"TreeIcon": {
|
|
"type": "object",
|
|
"required": [
|
|
"kind",
|
|
"value"
|
|
],
|
|
"properties": {
|
|
"kind": {
|
|
"type": "string",
|
|
"enum": [
|
|
"emoji",
|
|
"builtin"
|
|
]
|
|
},
|
|
"value": {
|
|
"type": "string",
|
|
"description": "Emoji character or built-in outline icon name, up to 64 bytes"
|
|
}
|
|
}
|
|
},
|
|
"TrashPurgeResult": {
|
|
"type": "object",
|
|
"required": [
|
|
"deleted",
|
|
"failed"
|
|
],
|
|
"properties": {
|
|
"deleted": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"failed": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"required": [
|
|
"id",
|
|
"error"
|
|
],
|
|
"properties": {
|
|
"id": {
|
|
"type": "string"
|
|
},
|
|
"error": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"StorageUsage": {
|
|
"type": "object",
|
|
"required": [
|
|
"totalSize",
|
|
"categories",
|
|
"assetsSize",
|
|
"trashSize",
|
|
"calculatedAt",
|
|
"builtinFontsSize",
|
|
"customFontsSize"
|
|
],
|
|
"properties": {
|
|
"totalSize": {
|
|
"type": "integer",
|
|
"minimum": 0
|
|
},
|
|
"assetsSize": {
|
|
"type": "integer",
|
|
"minimum": 0
|
|
},
|
|
"trashSize": {
|
|
"type": "integer",
|
|
"minimum": 0
|
|
},
|
|
"calculatedAt": {
|
|
"type": "integer",
|
|
"minimum": 0
|
|
},
|
|
"categories": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"required": [
|
|
"id",
|
|
"size"
|
|
],
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"enum": [
|
|
"vault",
|
|
"databases",
|
|
"fonts",
|
|
"themes",
|
|
"plugins",
|
|
"other"
|
|
]
|
|
},
|
|
"size": {
|
|
"type": "integer",
|
|
"minimum": 0
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"builtinFontsSize": {
|
|
"type": "integer",
|
|
"minimum": 0
|
|
},
|
|
"customFontsSize": {
|
|
"type": "integer",
|
|
"minimum": 0
|
|
}
|
|
}
|
|
},
|
|
"NoteReference": {
|
|
"type": "object",
|
|
"required": [
|
|
"target",
|
|
"line"
|
|
],
|
|
"properties": {
|
|
"target": {
|
|
"type": "string"
|
|
},
|
|
"line": {
|
|
"type": "integer"
|
|
}
|
|
}
|
|
},
|
|
"NoteMetadata": {
|
|
"type": "object",
|
|
"required": [
|
|
"path",
|
|
"rev",
|
|
"title",
|
|
"tags",
|
|
"links",
|
|
"assets",
|
|
"warnings"
|
|
],
|
|
"properties": {
|
|
"path": {
|
|
"type": "string"
|
|
},
|
|
"rev": {
|
|
"type": "string"
|
|
},
|
|
"title": {
|
|
"type": "string"
|
|
},
|
|
"tags": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"links": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/NoteReference"
|
|
}
|
|
},
|
|
"assets": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/NoteReference"
|
|
}
|
|
},
|
|
"warnings": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"CleanupImagesResult": {
|
|
"type": "object",
|
|
"required": [
|
|
"deleted",
|
|
"skipped"
|
|
],
|
|
"properties": {
|
|
"deleted": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/TrashItem"
|
|
}
|
|
},
|
|
"skipped": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"required": [
|
|
"path",
|
|
"reason"
|
|
],
|
|
"properties": {
|
|
"path": {
|
|
"type": "string"
|
|
},
|
|
"reason": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"CustomFont": {
|
|
"type": "object",
|
|
"required": [
|
|
"id",
|
|
"name",
|
|
"format"
|
|
],
|
|
"properties": {
|
|
"id": {
|
|
"type": "string"
|
|
},
|
|
"name": {
|
|
"type": "string"
|
|
},
|
|
"format": {
|
|
"type": "string",
|
|
"enum": [
|
|
"ttf",
|
|
"otf",
|
|
"woff",
|
|
"woff2"
|
|
]
|
|
}
|
|
}
|
|
},
|
|
"MaintenanceStatus": {
|
|
"type": "object",
|
|
"required": [
|
|
"busy",
|
|
"operation",
|
|
"error",
|
|
"finishedAt"
|
|
],
|
|
"properties": {
|
|
"busy": {
|
|
"type": "boolean"
|
|
},
|
|
"operation": {
|
|
"type": "string"
|
|
},
|
|
"error": {
|
|
"type": "string"
|
|
},
|
|
"finishedAt": {
|
|
"type": "integer"
|
|
},
|
|
"backup": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"BackupSummary": {
|
|
"type": "object",
|
|
"required": [
|
|
"kind",
|
|
"createdAt",
|
|
"entries",
|
|
"size"
|
|
],
|
|
"properties": {
|
|
"kind": {
|
|
"type": "string",
|
|
"enum": [
|
|
"full",
|
|
"settings"
|
|
]
|
|
},
|
|
"createdAt": {
|
|
"type": "integer"
|
|
},
|
|
"entries": {
|
|
"type": "integer"
|
|
},
|
|
"size": {
|
|
"type": "integer"
|
|
}
|
|
}
|
|
},
|
|
"ClearTempResult": {
|
|
"type": "object",
|
|
"required": [
|
|
"files",
|
|
"bytes",
|
|
"failed"
|
|
],
|
|
"properties": {
|
|
"files": {
|
|
"type": "integer"
|
|
},
|
|
"bytes": {
|
|
"type": "integer"
|
|
},
|
|
"failed": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"x-business-codes": {
|
|
"0": "Success",
|
|
"40000": "Invalid parameters",
|
|
"40001": "Incorrect or already-used captcha",
|
|
"40002": "Expired captcha",
|
|
"40003": "Incorrect current password",
|
|
"40100": "Invalid authentication",
|
|
"40101": "Incorrect sign-in password",
|
|
"40300": "Insufficient permissions",
|
|
"40400": "Resource not found",
|
|
"40900": "Resource conflict",
|
|
"41200": "Document revision conflict; data.rev is the latest revision",
|
|
"41300": "Size limit exceeded",
|
|
"42900": "Too many requests",
|
|
"50000": "Server error",
|
|
"50300": "Maintenance in progress"
|
|
}
|
|
}
|