Jesse A. Green / notebook

Live demo: the DocCompiler guide library as a static, read-only snapshot (October 2026). No backend, no accounts, nothing to submit.

SiYuan Admin Guide

Generated June 2026 from siyuan-note/siyuan at 96dfe0b

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

This guide is the operational and architectural reference for SiYuan — its internals, HTTP/WebSocket API, configuration surface, security model, deployment options, and operations. It is written for administrators, self-hosters, integrators, plugin authors, and developers. End-user feature walkthroughs live in the companion User Guide.

SiYuan is a privacy-first personal knowledge management system from Yunnan Liandi Technology Co., Ltd. (B3log), licensed AGPL-3.0. It is composed of a Go kernel (the engine) and a TypeScript UI that ships as a desktop (Electron), mobile (Android/iOS/HarmonyOS), and browser front end. This guide is generated from the source at the commit noted in the footer.


Table of Contents

  1. Executive Summary
  2. System Architecture
  3. Repository Structure
  4. Requirements
  5. Boot Sequence and Process Model
  6. Kernel Command-Line Reference
  7. Environment Variables
  8. Configuration Reference (conf.json)
  9. The HTTP/WebSocket Server
  10. Security Model
  11. HTTP API Reference
  12. WebSocket Command Channel
  13. WebDAV, CalDAV, and CardDAV
  14. Data Model and Storage
  15. Synchronization and the Data Repo
  16. Deployment
  17. The Publish Service
  18. Operations
  19. Performance Tuning
  20. Security Hardening Checklist
  21. Extensibility: Plugins, Widgets, and the Bazaar
  22. Code Quality and Conventions
  23. Potential Improvements
  24. Troubleshooting
  25. Quick Reference

1. Executive Summary

SiYuan's defining architectural decision is the kernel/UI split. The kernel is a single Go binary that runs a local HTTP + WebSocket server (gin + melody) on port 6806. It owns all state: it parses and stores block-structured Markdown (via the Lute engine), maintains a SQLite block index, renders databases, runs spaced-repetition scheduling (riff/FSRS), performs encrypted versioned sync (dejavu), and exposes ~485 JSON endpoints. The UI — whether the Electron desktop shell, a mobile app, or a plain browser — is a thin client that talks to that local kernel over the same API.

This design yields three deployment shapes from one codebase:

Shape Kernel UI Notes
Desktop Bundled, child process of Electron Electron renderer (/stage/build/{app,desktop}) Full feature set incl. PDF/Word/HTML export
Mobile Compiled into the app (gomobile) Native shell + web view (/stage/build/mobile) Android/iOS/HarmonyOS
Self-hosted b3log/siyuan Docker image Any browser over :6806 Browser only; no desktop/mobile connect; no PDF/Word/HTML export, no MD import
Attribute Value
License AGPL-3.0
Vendor Yunnan Liandi Technology Co., Ltd. (B3log)
Kernel language Go (see go.mod for the toolchain version)
UI language TypeScript + webpack; Electron desktop shell
Default kernel port 6806 (HTTP/WS); publish service 6808
Primary data store Per-document .sy JSON files + SQLite block index
Sync Encrypted snapshots to SiYuan Cloud / S3 / WebDAV / local FS

2. System Architecture

                    ┌──────────────────────────────────────────────┐
                    │  Front ends (thin clients)                    │
                    │  Electron desktop · Android/iOS/HarmonyOS ·   │
                    │  Browser (self-hosted)                        │
                    └───────────────┬──────────────────────────────┘
                                    │ HTTP (JSON, POST /api/*)
                                    │ WebSocket (/ws, melody) — realtime push & commands
                                    ▼
   ┌───────────────────────────────────────────────────────────────────────┐
   │  Kernel (Go, single binary)                                            │
   │                                                                         │
   │  gin HTTP engine  ──► middleware: ControlConcurrency → Timing →         │
   │                       Recover → CORS → JWT → gzip → sessions            │
   │                                                                         │
   │  kernel/api      REST handlers (~485 endpoints, /api/{domain}/{action}) │
   │  kernel/server   HTTP/WS wiring, WebDAV/CalDAV/CardDAV, static serving  │
   │  kernel/model    Business logic (the largest package)                  │
   │  kernel/cmd      WebSocket command dispatch                            │
   │  kernel/sql      SQLite block / history / asset-content indexes        │
   │  kernel/av       Attribute views (databases)                          │
   │  kernel/treenode Block tree + block-tree index                        │
   │  kernel/filesys  .sy document (de)serialization                       │
   │  kernel/bazaar   Marketplace (plugins/widgets/themes/icons/templates) │
   │  kernel/conf     Configuration structs (conf.json)                    │
   │  kernel/job      Cron jobs (history, sync, cleanup)                    │
   │  kernel/task     Background task queue                                 │
   │  kernel/util     Boot, paths, TLS, OCR, pandoc, device, working dir   │
   │  kernel/cache    In-memory caches (assets, etc.)                      │
   │  kernel/mobile   gomobile entry points for mobile apps                │
   │  kernel/harmony  HarmonyOS-specific glue                              │
   └───────────────────────────────┬───────────────────────────────────────┘
                                    │ uses
                                    ▼
   Lute (Markdown engine) · dejavu (data repo) · riff/go-fsrs (flashcards) ·
   go-sqlite3 (index) · pdfium/pdfcpu (PDF) · gosseract (OCR) · go-openai (AI) ·
   aws-sdk-go-v2/s3 · gowebdav/go-webdav (sync, CalDAV/CardDAV) · excelize (xlsx)

2.1 Request lifecycle (REST)

  1. A client sends POST /api/{domain}/{action} with a JSON body.
  2. gin runs the global middleware chain: ControlConcurrency (serializes kernel API requests), Timing, Recover, CORS, JWT (parses the X-Auth-Token and sets the request role), gzip, and sessions.
  3. Per-route middleware enforces auth: CheckAuth → optionally CheckAdminRole → optionally CheckReadonly.
  4. The handler in kernel/api/*.go validates the request, calls into kernel/model, and returns a JSON envelope {code, msg, data}.

2.2 Realtime channel

The UI maintains a WebSocket to /ws (melody). The kernel pushes progress, notifications, and UI-reload events to clients, and also accepts commands over the socket (parsed into cmd.NewCommand and run via cmd.Exec). This is how long-running operations (sync, indexing, transactions) report progress live.

2.3 One kernel, three UIs

The root route (/) inspects the User-Agent and redirects to the correct static bundle: Electron → /stage/build/app/, tablets/Pad/non-mobile Android → /stage/build/desktop/, mobile → /stage/build/mobile/, otherwise desktop. All three bundles are produced from the app/ TypeScript source via separate webpack configs.


3. Repository Structure

The repo is a polyglot monorepo: app/ (TypeScript front end) + kernel/ (Go back end).

Path Purpose
kernel/main.go Desktop/server kernel entry point (boot sequence)
kernel/api/ REST handlers + router.go (the authoritative endpoint list)
kernel/server/ HTTP/WS server, WebDAV/CalDAV/CardDAV, static serving, proxy
kernel/model/ Core business logic (largest package): documents, blocks, sync, export, import, history, flashcards, attribute views, etc.
kernel/cmd/ WebSocket command registry and executor
kernel/sql/ SQLite schema and queries (block, history, asset-content DBs)
kernel/av/ Attribute views (databases)
kernel/treenode/ Block tree and block-tree index
kernel/filesys/ .sy document read/write
kernel/bazaar/ Marketplace client (install/stage/readme)
kernel/conf/ Configuration structs (one struct per concern)
kernel/job/, kernel/task/ Cron scheduler and background task queue
kernel/util/ Boot, path resolution, TLS certs, OCR, pandoc, device id, working dir
kernel/cache/ In-memory caches
kernel/mobile/, kernel/harmony/ Mobile (gomobile) and HarmonyOS entry points
app/electron/main.js Electron main process (window/workspace/tray/kernel-child management)
app/src/ UI source: editor/, protyle/ (editor core), layout/, menus/, dialog/, config/, search/, plugin/, mobile/, window/, asset/, emoji/
app/stage/ Static runtime assets and vendored renderers (KaTeX, Mermaid, ECharts, PDF.js, highlight.js, PlantUML, Graphviz, abcjs)
app/appearance/ Themes, icons, emojis, language packs (langs/)
app/pandoc/ Bundled Pandoc resources
app/changelogs/, app/guide/ Release changelogs and the built-in user-guide notebook
scripts/ Build/packaging helpers

Note

app/changelogs/ and app/guide/ are large by file count but are content, not code — the guide folders are SiYuan notebooks (.sy documents with ID-named subfolders), not source to be deployed as logic.


4. Requirements

4.1 Runtime (end users)

Deployment Requirement
Desktop Windows / macOS / Linux (x64 and arm64 builds available)
Mobile Android / iOS / iPadOS / HarmonyOS
Self-hosted Docker host; a modern browser to access the UI

The desktop app bundles the kernel, Electron runtime, and Pandoc — no separate installs needed.

4.2 Build / development

Component Toolchain
Kernel Go (version pinned in kernel/go.mod); CGO for SQLite
UI Node.js + pnpm (version pinned in app/package.json packageManager); webpack; TypeScript
Desktop packaging electron + electron-builder (per-platform/arch electron-builder*.yml configs)
Export Pandoc (bundled for the desktop)
OCR Tesseract (bundled/available for OCR features)

UI build scripts (app/package.json):

pnpm run dev            # webpack dev build (app)
pnpm run dev:desktop    # dev build, desktop bundle
pnpm run dev:mobile     # dev build, mobile bundle
pnpm run build          # production build of all bundles
pnpm run dist           # electron-builder package (current platform)
pnpm run dist-darwin    # macOS package, etc. (see all dist-* scripts)

Note

The kernel uses a forked SQLite driver (88250/go-sqlite3) and a forked pdfcpu (88250/pdfcpu) via replace directives in go.mod. Build from the module graph as-is; don't substitute upstream versions without testing.


5. Boot Sequence and Process Model

kernel/main.go defines the startup order (desktop/server build; the //go:build !mobile tag separates it from mobile entry points):

util.Boot()                       // parse flags, resolve workspace/paths, logging, lock
model.InitConf()                  // load conf.json (defaults via conf.NewX())
go server.Serve(false, CookieKey) // start gin HTTP/WS server (async)
model.InitAppearance()            // themes, icons, languages
sql.InitDatabase(false)           // main block index (SQLite)
sql.InitHistoryDatabase(false)    // history index
sql.InitAssetContentDatabase(false) // asset-content (search) index
model.BootSyncData()              // boot-time sync if enabled
model.InitBoxes()                 // open notebooks
model.LoadFlashcards()            // FSRS decks
job.StartCron()                   // scheduled jobs
... watchers (assets, emojis, themes) + HandleSignal()

Key facts:

  • Workspace lock: only one kernel may use a workspace at a time (the "workspace is locked" error indicates a second kernel).
  • Port file: the kernel writes its chosen port keyed by PID to ~/.config/siyuan/port.json so launchers and tools can discover it.
  • Desktop child process: the Electron main process (app/electron/main.js) launches the kernel as a child with flags --port, --wd <appDir>, --workspace, --lang, and (in dev) --mode dev. It manages multiple workspaces/windows, a system tray per workspace, single-instance locking, and the siyuan:// protocol handler.

Important

On desktop you never start the kernel yourself — Electron does. For self-hosting you run the kernel binary directly (the Docker entrypoint does this for you), so the CLI flags below matter.


6. Kernel Command-Line Reference

Flags parsed in kernel/util/working.go:

Flag Default Purpose
--workspace ~/SiYuan/ Workspace directory path
--wd (binary working dir) Working directory of SiYuan (where stage/, appearance/, etc. live)
--port 0 HTTP server port (0 = pick a free port; conventionally 6806)
--readonly false Start in read-only mode (blocks all write operations)
--accessAuthCode "" Access authorization code (the kernel's password)
--ssl false Enable HTTPS/WSS
--lang "" Interface language (e.g. en_US, zh_CN, ja_JP, de_DE, es_ES, fr_FR, ko_KR, ru_RU, pt_BR, tr_TR, zh_CHT, …)
--mode prod dev or prod (dev enables /debug/pprof and dev asset paths)

The Docker entrypoint additionally honors --workspace= and forwards any extra arguments to the kernel.

# Run the kernel directly (self-host without Docker)
./kernel --workspace=/data/siyuan --port=6806 --accessAuthCode=please-change-me --lang=en_US

7. Environment Variables

The kernel reads these via os.Getenv (UI/Electron reads NODE_ENV):

Variable Used by Effect
SIYUAN_WORKSPACE_PATH Docker entrypoint Workspace path (CLI --workspace wins if both set)
SIYUAN_ACCESS_AUTH_CODE Docker entrypoint Access auth code (CLI --accessAuthCode wins)
SIYUAN_ACCESS_AUTH_CODE_BYPASS kernel/util/working.go If true, bypasses the access auth code (insecure; use only in trusted/dev contexts)
SIYUAN_OPENAI_API_KEY kernel/conf/ai.go Default OpenAI API key
SIYUAN_OPENAI_API_TIMEOUT kernel/conf/ai.go OpenAI request timeout (seconds; default 30)
SIYUAN_OPENAI_API_PROXY kernel/conf/ai.go Proxy for OpenAI calls
SIYUAN_OPENAI_API_MAX_TOKENS kernel/conf/ai.go Max tokens
SIYUAN_OPENAI_API_TEMPERATURE kernel/conf/ai.go Sampling temperature (default 1.0)
SIYUAN_OPENAI_API_MAX_CONTEXTS kernel/conf/ai.go Number of context messages (default 7)
SIYUAN_OPENAI_API_BASE_URL kernel/conf/ai.go API base URL (default https://api.openai.com/v1)
SIYUAN_OPENAI_API_USER_AGENT kernel/conf/ai.go Custom user agent
SIYUAN_TESSERACT_ENABLED kernel/util/ocr.go Enable Tesseract OCR
SIYUAN_TESSERACT_TIMEOUT kernel/util/ocr.go OCR timeout
SIYUAN_TESSERACT_MAX_SIZE kernel/util/ocr.go Max image size for OCR
SIYUAN_TESSERACT_LANGS kernel/util/ocr.go OCR languages
SIYUAN_PDF_ASSET_CONTENT_INDEX_MAX_SIZE kernel/model/asset_content.go Max PDF size to index for asset-content search
SIYUAN_SYNC_INDEX_TIMING kernel/model/conf.go Sync-index timing threshold
SIYUAN_PERFORMANCE_TIMING kernel/model/session.go Enable performance timing logs
PUID / PGID Docker entrypoint Run-as user/group IDs inside the container (default 1000/1000)
NODE_ENV app/electron/main.js Electron dev/prod mode
APPDATA / ProgramData / USERPROFILE kernel/util/path.go, working.go Windows path resolution

Caution

SIYUAN_ACCESS_AUTH_CODE_BYPASS=true disables authentication entirely. Never set it on an instance reachable by anyone but you.


8. Configuration Reference (conf.json)

Runtime configuration lives in workspace/conf/conf.json, deserialized into the AppConf aggregate. Each concern is its own struct in kernel/conf/*.go, with JSON keys and defaults defined by the corresponding NewX() constructor. Per-notebook settings live in each notebook's .siyuan/conf.json (BoxConf).

Note

Most settings are managed through the in-app Settings UI (which calls the /api/setting/* and /api/system/* endpoints). Editing conf.json by hand is possible but should be done with the kernel stopped.

8.1 System (kernel/conf/system.go)

Key Type Notes
id, name string Device ID and name
kernelVersion, os, osPlatform string Runtime info
container string docker / android / ios / harmony / std
isMicrosoftStore, isInsider bool Build flavor
homeDir, workspaceDir, appDir, confDir, dataDir string Resolved paths
networkServe bool Bind to 0.0.0.0 (LAN serving) instead of 127.0.0.1
networkServeTLS bool Enable HTTPS (requires networkServe)
networkProxy object {scheme, host, port} outbound proxy
downloadInstallPkg bool Auto-download update packages
autoLaunch2 int 0 off / 1 on / 2 on+hidden
lockScreenMode int 0 manual / 1 manual+follow-system
disabledFeatures []string Feature flags to disable
microsoftDefenderExcluded bool Whether the workspace was added to Defender exclusions

8.2 Editor (kernel/conf/editor.go) — selected keys

Key Default Notes
fontSize 16
allowSVGScript, allowHTMLBLockScript false Execute scripts inside SVG/HTML blocks (security-sensitive)
codeSyntaxHighlightLineNum, codeLineWrap, codeLigatures false Code-block rendering
codeTabSpaces 0 Tab→spaces in code (0 = off)
generateHistoryInterval 10 File-history interval (minutes)
historyRetentionDays 30 History retention
virtualBlockRef false Virtual references; virtualBlockRefInclude/Exclude keyword lists
blockRefDynamicAnchorTextMaxLen 96
plantUMLServePath https://www.plantuml.com/plantuml/svg/~1 PlantUML render server
fullWidth true Max-width layout
katexMacros {} KaTeX macro definitions
readOnly false Editor read-only
dynamicLoadBlocks 192 Blocks loaded per chunk (range 48–1024)
spellcheck / spellcheckLanguages false / ["en-US"]
backlinkExpandCount 8
floatWindowMode / floatWindowDelay 0 / 620ms Hover-preview behavior
markdown object Markdown parsing settings

8.3 Appearance (kernel/conf/appearance.go)

Key Default Notes
mode / modeOS 0 (light) / true Theme mode; follow OS
themeDark / themeLight midnight / daylight
codeBlockThemeDark / codeBlockThemeLight base16/dracula / github
icon material Icon set
lang en_US UI language
closeButtonBehavior 0 0 quit / 1 minimize to tray
hideStatusBar false

8.4 Sync (kernel/conf/sync.go)

Key Default Notes
enabled false Master sync toggle
cloudName main Cloud sync directory name
mode 1 1 auto / 2 manual / 3 fully manual
interval 30 Auto-sync seconds
provider 0 0 SiYuan / 2 S3 / 3 WebDAV / 4 Local
perception false Sync awareness
generateConflictDoc false Create a conflict doc on conflict
s3 object endpoint, accessKey, secretKey, bucket, region, pathStyle, skipTlsVerify, timeout, concurrentReqs
webdav object endpoint, username, password, skipTlsVerify, timeout, concurrentReqs
local object endpoint (local dir), timeout, concurrentReqs

8.5 Repo (kernel/conf/repo.go)

Key Default Notes
key — AES key for the encrypted data repo (binary)
syncIndexTiming 12000 ms threshold to warn about slow indexing
indexRetentionDays 180 Auto-purge local indexes older than this
retentionIndexesDaily 2 Indexes kept per day

8.6 Publish (kernel/conf/publish.go)

Key Default Notes
enable false Enable the publish service
port 6808 Publish service port
auth.enable true Basic auth on the publish service
auth.accounts[] [] {username, password, memo} accounts

8.7 Other config structs

Struct File Highlights
AI / OpenAI ai.go API key, base URL, model, provider (OpenAI/Azure), temperature 1.0, contexts 7, timeout 30
API api.go token (16-char API token, randomly generated)
Search search.go Per-block-type search toggles, limit 64, caseSensitive, name/alias/memo/IAL flags, asset-path indexing, backlink/virtual-ref matching
Export export.go Block-ref/embed modes, PDF footer %page / %pages, watermarks, Pandoc bin/params, YAML front matter, include sub/related docs
Flashcard flashcard.go New/review limits 20/200, card-making modes, FSRS requestRetention/maximumInterval/weights
Graph graph.go maxBlocks 10240, local/global graph type filters and D3 force params
FileTree filetree.go Sort, maxListCount 512, maxOpenTabCount 8, deep-create guard, large-file warning
Bazaar bazaar.go trust, petalDisabled (disable plugin system)
Tag tag.go Sort mode
Snippet/Snpt snippet.go enabledCSS, enabledJS; per-snippet {id,name,type,enabled,disabledInPublish,content}
Account, User, Stat account.go, user.go, stat.go Cloud account display, membership/traffic fields, content statistics
BoxConf box.go Per-notebook: name, icon, sort, create/daily-note paths + template

9. The HTTP/WebSocket Server

Defined in kernel/server/serve.go (Serve(fastMode, cookieKey)).

9.1 Binding and ports

if model.Conf.System.NetworkServe || util.ContainerDocker == util.Container {
    host = "0.0.0.0"   // LAN-accessible (or always in Docker)
} else {
    host = "127.0.0.1" // localhost only (default)
}
  • Default bind is loopback only. Setting networkServe (or running in Docker) binds to all interfaces.
  • The actual port is recorded to ~/.config/siyuan/port.json keyed by PID.
  • HTTP/2 cleartext (UseH2C) is enabled; max multipart upload memory is 32 MiB.

9.2 TLS

When networkServeTLS and networkServe are both on, the kernel obtains/creates a self-signed CA + cert (util.GetOrCreateTLSCert) and serves HTTPS, multiplexing TLS and plain connections on a fixed port via cmux. You can export the CA cert/bundle via API (/api/system/exportTLSCACert, exportTLSCABundle) and import a bundle.

9.3 Middleware chain (global)

ControlConcurrency (serialize kernel API requests — see [issue #9939]) → Timing → Recover → corsMiddleware → jwtMiddleware → gzip (excluding already-compressed media) → sessions (cookie store named siyuan, HttpOnly, Secure when SSL).

9.4 Static and special route groups

Route Auth Serves
/ CheckAuth Redirects to /stage/build/{app,desktop,mobile} by User-Agent
/stage/* CheckAuth UI bundles and static assets
/appearance/*filepath CheckAuth Themes/icons/langs (fills missing lang keys from en_US)
/assets/*path CheckAuth Workspace assets (path-escaped, publish-access-checked, thumbnail/SVG handling)
/history/*path CheckAuth + Admin File history
/repo/diff/*path CheckAuth + Admin Repo snapshot diffs
/export/*filepath CheckAuth Export downloads (sub-path + sensitive-file guarded; forces attachment download)
/widgets/, /plugins/, /emojis/, /templates/ CheckAuth Static dirs under data/
/public/ (open) data/public/ contents
/snippets/*filepath CheckAuth Snippet content (conf.json requires admin role)
/upload CheckAuth + Admin + ¬Readonly File upload
/check-auth (open) Auth page (HTML)
/ws (handshake auth) WebSocket
/webdav/*, /caldav/*, /carddav/*, /.well-known/{caldav,carddav} CheckAuth + Admin WebDAV/CalDAV/CardDAV
/debug/pprof/* dev mode only Go profiling
favicon.ico, manifest.json, service-worker.js (open) PWA fixed files

Warning

/debug/pprof/* is registered only when --mode dev. Production builds do not expose pprof (per [issue #10152]).

9.5 CORS

The CORS middleware sets Access-Control-Allow-Origin: * with credentials allowed, and tailors Access-Control-Allow-Methods per route family (standard HTTP, WebDAV, CalDAV, CardDAV methods). OPTIONS preflight returns 204 with a 600-second max-age.

Caution

Access-Control-Allow-Origin: * combined with Allow-Credentials: true means any web origin can attempt authenticated requests if it has valid credentials/token. Authentication is enforced by the auth code / token, not by origin. Treat the access auth code and API token as secrets and never expose the kernel directly to the internet without a reverse proxy and strong auth.


10. Security Model

SiYuan's authorization is enforced by three composable gin middlewares plus a role system. Defined in kernel/model and applied in kernel/api/router.go and kernel/server/serve.go.

10.1 Authentication layers

  1. Access Auth Code — the workspace "password" (Conf.AccessAuthCode). When set, clients must authenticate (via the /check-auth page → session cookie). Can be supplied at launch via --accessAuthCode / SIYUAN_ACCESS_AUTH_CODE, or bypassed (insecurely) with SIYUAN_ACCESS_AUTH_CODE_BYPASS=true.
  2. API Token — Conf.API.Token (a random 16-char token). Sent as X-Auth-Token for programmatic/API access; parsed by jwtMiddleware.
  3. Session cookie — gin cookie session (siyuan), HttpOnly, Secure under TLS.

10.2 Roles

The JWT/token carries a role; jwtMiddleware sets it on the request (defaulting to Visitor when no valid token):

Role Capability
Administrator Full read/write/admin
Editor Read/write
Reader Read-only
Visitor Minimal/unauthenticated

10.3 Authorization middleware

Middleware Enforces
CheckAuth A valid session or token (authenticated)
CheckAdminRole The request role is administrator (write/admin endpoints)
CheckReadonly The kernel is not in read-only mode (blocks mutations when --readonly or Editor.ReadOnly)

A typical mutating endpoint stacks all three: CheckAuth, CheckAdminRole, CheckReadonly. Read endpoints often use only CheckAuth. A handful of bootstrap endpoints (bootProgress, version, currentTime, loginAuth, logoutAuth, getCaptcha, getDynamicIcon) require no auth.

10.4 Publish-access checks

When an asset is requested by a non-admin context, the server consults the document's publish access settings (GetPublishAccess / CheckAbsPathAccessableByPublishAccess) before serving — so published/shared documents only expose what they're allowed to.

10.5 Content-execution safeguards

  • SVG sanitization: SVG assets are sanitized unless Editor.AllowSVGScript is enabled.
  • HTML block scripts: disabled unless Editor.AllowHTMLBLockScript is on.
  • Sensitive paths: the export server refuses to serve files it deems sensitive and enforces sub-path containment to prevent path traversal.
  • IP allow/deny: the network forward-proxy endpoint rejects prohibited IPs (ip address [%s] is prohibited) to mitigate SSRF.
  • CA/JWT: TLS CA management and JWT parsing live in kernel/util/cert.go and kernel/model respectively.

Important

The single most important hardening step for any networked instance is a strong access auth code plus a reverse proxy terminating TLS. See the hardening checklist.


11. HTTP API Reference

The kernel exposes a JSON REST API registered in kernel/api/router.go. All endpoints accept POST (a few also GET) at /api/{domain}/{action} and return {code, msg, data}. Authenticate with the API token via the X-Auth-Token header. There are ~485 endpoints; they are grouped by domain below. The official endpoint catalog is also published as API.md.

Auth legend: 🔓 no auth · 🔑 CheckAuth · 🛡 +Admin role · 🔒 +Readonly guard (mutating).

11.1 Calling convention

curl -X POST http://127.0.0.1:6806/api/notebook/lsNotebooks \
  -H "Authorization: Token <your-api-token>" \
  -H "X-Auth-Token: <your-api-token>" \
  -H "Content-Type: application/json" \
  -d '{}'

Note

Request/response bodies vary per endpoint; consult kernel/api/*.go handlers (or API.md) for exact fields. The tables below are the authoritative endpoint inventory grouped by function.

11.2 System & lifecycle (/api/system/*)

Endpoint Auth Purpose
bootProgress (GET/POST) 🔓 Boot progress
version (GET/POST), currentTime 🔓 Kernel version / server time
getConf 🔑 Full configuration
getNetwork, getSysFonts, getChangelog, getWorkspaceInfo 🔑/🛡 System info
setNetworkServe, setNetworkServeTLS, setNetworkProxy 🛡🔒 Network serving / TLS / proxy
exportTLSCACert, exportTLSCABundle, importTLSCABundle 🛡(🔒) TLS CA management
setAccessAuthCode, setFollowSystemLockScreen, setAPIToken 🛡🔒 Auth settings
setWorkspaceDir, getWorkspaces, getMobileWorkspaces, checkWorkspaceDir, createWorkspaceDir, removeWorkspaceDir, removeWorkspaceDirPhysically 🛡(🔒) Workspace management
setAppearanceMode, setUILayout 🛡🔒 UI/appearance
setAutoLaunch, setDownloadInstallPkg, checkUpdate 🛡(🔒) Launch & updates
exportConf, importConf, exportLog 🛡(🔒) Config import/export, logs
vacuumDataIndex, rebuildDataIndex, clearTempFiles 🛡🔒 Index/temp maintenance
addMicrosoftDefenderExclusion, ignoreAddMicrosoftDefenderExclusion 🛡🔒 Windows Defender
exit, reloadUI (deprecated→/api/ui/reloadUI) 🛡 Lifecycle

11.3 Notebooks (/api/notebook/*)

lsNotebooks 🔑 · openNotebook closeNotebook createNotebook removeNotebook renameNotebook changeSortNotebook setNotebookIcon 🛡🔒 · getNotebookConf getNotebookInfo 🔑 · setNotebookConf 🛡🔒.

11.4 File tree / documents (/api/filetree/*)

Group Endpoints
Read 🔑 searchDocs, listDocsByPath, getDoc, getDocCreateSavePath, getRefCreateSavePath, getHPathByPath, getHPathsByPaths, getHPathByID, getPathByID, getFullHPathByID, getIDsByHPath
Create/modify 🛡🔒 createDoc, createDocWithMd, createDailyNote, renameDoc, renameDocByID, removeDoc, removeDocByID, removeDocs, moveDocs, moveDocsByID, duplicateDoc, changeSort
Restructure 🛡🔒 doc2Heading, heading2Doc, li2Doc
Index/publish 🛡🔒 upsertIndexes, removeIndexes, listDocTree, moveLocalShorthands, setPublishAccess, getPublishAccess, authFilePublishAccess

11.5 Blocks (/api/block/*)

The richest domain. Read operations (🔑/🛡): getBlockInfo, getBlockDOM(s), getBlockDOM(s)WithEmbed, getBlockKramdown(s), getChildBlocks, getTailChildBlocks, getBlockBreadcrumb, getBlockIndex, getBlocksIndexes, getRefIDs, getRefText, getDOMText, getTreeStat, getBlocksWordCount, getContentWordCount, getRecentUpdatedBlocks, getDocInfo(s), checkBlockExist, checkBlockFold, getUnfoldedParentID, getBlockSiblingID, getBlockRelevantIDs, getBlockTreeInfos, checkBlockRef, heading transactions (getHeadingLevelTransaction, getHeadingDeleteTransaction, getHeadingInsertTransaction, getHeadingChildrenIDs/DOM).

Mutations (🛡🔒): insertBlock, batchInsertBlock, prependBlock, appendBlock (+ batch + daily-note variants), updateBlock, batchUpdateBlock, deleteBlock, moveBlock, moveOutlineHeading, foldBlock, unfoldBlock, setBlockReminder, swapBlockRef, transferBlockRef, appendHeadingChildren, updateTaskListItemMarker (+ batch).

11.6 Attribute views / databases (/api/av/*)

Render: renderAttributeView, renderHistoryAttributeView, renderSnapshotAttributeView. Keys/fields: getAttributeViewKeys, addAttributeViewKey, removeAttributeViewKey, sortAttributeViewKey, sortAttributeViewViewKey. Rows/blocks: addAttributeViewBlocks, removeAttributeViewBlocks, batchReplaceAttributeViewBlocks, duplicateAttributeViewBlock, appendAttributeViewDetachedBlocksWithValues. Values/filters: setAttributeViewBlockAttr, batchSetAttributeViewBlockAttrs, getAttributeViewFilterSort, setAttrViewGroup, changeAttrViewLayout, setDatabaseBlockView. Search/relations: searchAttributeView, searchAttributeViewRelationKey, searchAttributeViewRollupDestKeys, getMirrorDatabaseBlocks, getAttributeViewKeysByAvID/ByID. Cleanup: getUnusedAttributeViews, removeUnusedAttributeView(s).

11.7 Search (/api/search/*)

fullTextSearchBlock, fullTextSearchAssetContent, searchTag, searchTemplate, searchWidget, searchRefBlock, searchEmbedBlock, getEmbedBlock, updateEmbedBlock, searchAsset, getAssetContent, findReplace 🛡🔒, removeTemplate 🛡🔒, listInvalidBlockRefs.

11.8 Editing pipeline & queries

Domain Endpoints
/api/transactions performTransactions 🛡🔒 — the core batched edit operation the editor uses
/api/query/sql SQL 🛡🔒 — run a SQL query against the block index
/api/sqlite/flushTransaction flush pending DB writes
/api/lute/* spinBlockDOM, html2BlockDOM, copyStdMarkdown — Markdown engine ops
/api/template/* render, renderSprig, docSaveAsTemplate
/api/convert/pandoc Pandoc conversion
/api/format/* autoSpace, netImg2LocalAssets, netAssets2LocalAssets

11.9 Assets & files

Domain Endpoints
/api/asset/* upload, insertLocalAssets, resolveAssetPath, uploadCloud(ByAssetsPaths), getUnusedAssets, getMissingAssets, removeUnusedAsset(s), getDocImageAssets, getDocAssets, renameAsset, statAsset, setFileAnnotation, getFileAnnotation, ocr, getImageOCRText, setImageOCRText, fullReindexAssetContent
/api/file/* getFile, putFile, copyFile, globalCopyFiles, workspaceCopyFiles, removeFile, renameFile, readDir, getUniqueFilename
/api/archive/* zip, unzip 🛡🔒
/api/clipboard/* readFilePaths, writeFilePath
/api/extension/copy Web-clipper copy

11.10 Export & import

Export (/api/export/*, 🛡): exportMd, exportMds, exportNotebookMd, exportSY(s), exportNotebookSY, exportMdContent, exportHTML, exportPreviewHTML, exportMdHTML, exportBrowserHTML, exportDocx, processPDF, exportResources, exportAsFile, exportData, exportDataInFolder, exportTempContent, export2Liandi, exportReStructuredText, exportAsciiDoc, exportTextile, exportOPML, exportOrgMode, exportMediaWiki, exportODT, exportRTF, exportEPUB, exportAttributeView, exportCodeBlock, preview.

Import (/api/import/*, 🛡🔒): importStdMd, importZipMd, importData, importSY.

11.11 Sync, repo, and cloud

Domain Endpoints
/api/sync/* setSyncEnable, setSyncInterval, setSyncMode, setSyncPerception, setSyncGenerateConflictDoc, setSyncProvider, setSyncProviderS3/WebDAV/Local, performSync, performBootSync, getBootSync, getSyncInfo, cloud-sync-dir CRUD, export/importSyncProviderS3/WebDAV
/api/repo/* initRepoKey, initRepoKeyFromPassphrase, importRepoKey, resetRepo, purgeRepo, purgeCloudRepo, createSnapshot, tagSnapshot, checkoutRepo, getRepoSnapshots, getRepoTagSnapshots, removeRepoTagSnapshot, cloud snapshot ops, diffRepoSnapshots, openRepoSnapshotFile, rollbackRepoSnapshotFile, getRepoFile, setRepoIndexRetentionDays, setRetentionIndexesDaily
/api/cloud/getCloudSpace Cloud quota
/api/account/* login, checkActivationcode, useActivationcode, deactivate, startFreeTrial
/api/setting/getCloudUser, logoutCloudUser, login2faCloudUser Cloud account

11.12 Knowledge features

Domain Endpoints
/api/ref/* getBacklink, getBacklink2, getBacklinkDoc, getBackmentionDoc, refreshBacklink
/api/attr/* getBlockAttrs, batchGetBlockAttrs, setBlockAttrs, batchSetBlockAttrs, getBookmarkLabels (resetBlockAttrs deprecated)
/api/tag/* getTag, renameTag, removeTag
/api/bookmark/* getBookmark, renameBookmark, removeBookmark
/api/outline/getDocOutline Document outline
/api/graph/* getGraph, getLocalGraph, resetGraph, resetLocalGraph
/api/riff/* Flashcard decks/cards: createRiffDeck, renameRiffDeck, removeRiffDeck, getRiffDecks, addRiffCards, removeRiffCards, getRiffDueCards (+tree/notebook), reviewRiffCard, skipReviewRiffCard, getRiffCards, resetRiffCards, batchSetRiffCardsDueTime, getRiffCardsByBlockIDs
/api/history/* getNotebookHistory, getDocHistoryContent, getHistoryItems, searchHistory, rollbackDocHistory, rollbackNotebookHistory, rollbackAssetsHistory, rollbackAttributeViewHistory, clearWorkspaceHistory, reindexHistory
/api/inbox/* getShorthands, getShorthand, removeShorthands
/api/snippet/* getSnippet, setSnippet, removeSnippet

11.13 AI, bazaar, storage, UI, network

Domain Endpoints
/api/ai/* chatGPT, chatGPTWithAction 🛡
/api/bazaar/* Per package type (plugin/widget/icon/template/theme): getBazaarX, getInstalledX, installBazaarX 🛡🔒, uninstallBazaarX 🛡🔒; plus getBazaarPackageREADME, getUpdatedPackage, batchUpdatePackage
/api/petal/* loadPetals, setPetalEnabled — plugin runtime
/api/storage/* getLocalStorage, setLocalStorageVal, removeLocalStorageVals, criteria CRUD, recent-docs tracking, outline storage
/api/setting/* setEditor, setExport, setFiletree, setSearch, setKeymap, setAppearance, setIcon, setTheme, setEmoji, setFlashcard, setAI, setBazaar, setPublish/getPublish, setSnippet, setEditorReadOnly, setAccount, virtual-block-ref include/exclude
/api/ui/* reloadUI, reloadIcon, reloadTheme, reloadAttributeView, reloadProtyle, reloadFiletree, reloadTag
/api/network/* forwardProxy (SSRF-guarded), echo
/api/notification/* pushMsg, pushErrMsg
/api/broadcast/*, /ws/broadcast, /es/broadcast/subscribe Pub/sub broadcast channels (publish, postMessage, getChannels, getChannelInfo)

Note

Deprecated endpoints are marked in router.go and log a warning when used (the deprecated handler announces a removal date of 2026-06-30). Examples being phased out: /api/system/reloadUI (→ /api/ui/reloadUI), /api/storage/setLocalStorage (→ setLocalStorageVal), /api/attr/resetBlockAttrs (→ setBlockAttrs), /api/filetree/refreshFiletree (→ /api/system/rebuildDataIndex). Migrate off them.


12. WebSocket Command Channel

The editor uses /ws (melody) for realtime, bidirectional communication, distinct from the REST API.

  • Max message size: 8 MiB.
  • Handshake auth: On connect, the kernel verifies either a valid session (matching AccessAuthCode) or a valid X-Auth-Token role (Administrator/Editor/Reader). The auth page keeps a special connection alive (?app=siyuan&id=auth&type=auth).
  • Message shape: clients send {cmd, reqId, param}. The kernel builds a cmd.Command via cmd.NewCommand(cmdStr, reqId, param, session) and runs cmd.Exec. Unknown commands return can not find command [...].
  • Read-only enforcement: Non-read commands are rejected when the kernel is read-only or the token role is Reader/Visitor.
  • Push: The kernel registers each session in a push channel set and broadcasts progress/notification/reload events to connected UIs.

Tip

For integrations, prefer the REST API for discrete operations; the WebSocket is primarily the editor's live transaction/push channel.


13. WebDAV, CalDAV, and CardDAV

The kernel embeds standards-compliant DAV servers (all under CheckAuth + CheckAdminRole, with write methods blocked in read-only mode):

Service Path Backend Use
WebDAV /webdav/* golang.org/x/net/webdav over the workspace dir Mount your workspace as a network drive
CalDAV /caldav/*, /.well-known/caldav emersion/go-webdav/caldav + SiYuan backend Expose reminders/dates as calendars
CardDAV /carddav/*, /.well-known/carddav emersion/go-webdav/carddav + SiYuan backend Expose contacts

Each DAV family advertises its extended method set (PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, REPORT, etc.) via CORS and gin Match.

Note

A known limitation: the CardDAV backend can't yet satisfy Thunderbird's PROPFIND with current-user-privilege-set.


14. Data Model and Storage

14.1 On-disk

  • Documents are .sy JSON files (a serialized block tree, kernel/filesys).
  • Workspace layout: data/ (notebooks + assets/ emojis/ snippets/ storage/ templates/ widgets/ plugins/ public/), conf/, history/, repo/, temp/ (logs at temp/siyuan.log).
  • Notebooks carry .siyuan/conf.json (BoxConf).

14.2 Indexes (SQLite)

Three SQLite databases are initialized at boot (kernel/sql): the main block index, the history index, and the asset-content index (for searching inside attachments). The block index is the backing store for full-text search and /api/query/sql. Blocks carry type, content, attributes (IAL), and relationships. The block tree is also indexed in kernel/treenode.

Important

The .sy files are the source of truth; the SQLite indexes are derived and can be rebuilt (/api/system/rebuildDataIndex, vacuumDataIndex). If search behaves oddly after manual file changes, rebuild the index.

14.3 Block IDs

Every block has a stable unique ID. References, embeds, attributes, flashcards, and the index point at IDs, which is why content can move freely without breaking links.


15. Synchronization and the Data Repo

Sync is built on dejavu, a content-addressed, encrypted, versioned data repo (analogous to a Git-like object store), stored in workspace/repo/.

15.1 Repo key

Before sync/snapshots, initialize an AES repo key (/api/repo/initRepoKey or initRepoKeyFromPassphrase). Data is encrypted with this key before upload. The same key must be set on every device (importRepoKey). Losing it (with inconsistent device keys) requires a repo reset.

15.2 Providers

Conf.Sync.Provider: 0 SiYuan Cloud (membership), 2 S3, 3 WebDAV, 4 local file system. Each has its own config block (endpoint, credentials, timeout, concurrency, TLS-verify, path-style for S3). Sync modes: 1 auto (interval, default 30s), 2 manual, 3 fully manual.

15.3 Snapshots

Independent of cloud sync: create/tag/diff/checkout snapshots and roll back individual files or whole snapshots. Auto-purge keeps indexRetentionDays (180) of indexes and retentionIndexesDaily (2) per day.

Caution

Never place the workspace inside a third-party file-sync disk (Dropbox/OneDrive/etc.) — concurrent file syncing races with the kernel and can corrupt data. Use SiYuan's own sync to S3/WebDAV/Cloud instead.


16. Deployment

16.1 Docker

docker run -d \
  -v /siyuan/workspace:/siyuan/workspace \
  -p 6806:6806 \
  -e PUID=1000 -e PGID=1000 \
  b3log/siyuan \
  --workspace=/siyuan/workspace/ \
  --accessAuthCode=please-change-me

The image entrypoint (kernel/entrypoint.sh) creates a user/group from PUID/PGID, fixes ownership of /opt/siyuan, /home/siyuan, and the workspace, then runs the kernel as that user. The program lives under /opt/siyuan/ (appearance/, guide/, stage/, kernel).

Docker Compose

services:
  main:
    image: b3log/siyuan
    command: ['--workspace=/siyuan/workspace/', '--accessAuthCode=${AuthCode}']
    ports:
      - 6806:6806
    volumes:
      - /siyuan/workspace:/siyuan/workspace
    restart: unless-stopped
    environment:
      - TZ=${YOUR_TIME_ZONE}
      - PUID=${YOUR_USER_PUID}
      - PGID=${YOUR_USER_PGID}

Reverse proxy: To hide port 6806 behind NGINX, you must proxy the WebSocket at /ws, and you should not use URL rewriting/redirects (they break authentication) — configure a straight reverse proxy.

Warning

Docker/browser limitations (by design): no desktop/mobile app connections (browser only), no PDF/HTML/Word export, no Markdown import.

16.2 Unraid / TrueNAS

Both are supported via the same image; set ownership of the appdata/dataset folder to your PUID:PGID first (e.g. chown -R 1000:1000 ...), then map port 6806 and pass --accessAuthCode. See the project README for ready-made templates.

16.3 Desktop packaging

electron-builder produces per-platform/arch artifacts via the dist-* scripts and electron-builder*.yml configs (base, arm64, darwin, darwin-arm64, linux, linux-arm64). The Electron app uses @electron/remote and disables web security in the renderer because it loads the UI from the local kernel over http://127.0.0.1:<port>.


17. The Publish Service

When Conf.Publish.Enable is on, the kernel runs a separate publish service (default port 6808, kernel/server/proxy.InitPublishService) that exposes selected documents publicly. It supports HTTP Basic auth (Publish.Auth.Enable, default on) with a list of {username, password, memo} accounts. Combine with per-document publish access controls so only intended content is reachable.

Caution

The publish service makes content reachable without the main access auth code. Keep Basic auth enabled, use strong credentials, and front it with TLS if exposed beyond your LAN.


18. Operations

18.1 Health and status

  • Boot progress: GET /api/system/bootProgress.
  • Version: GET /api/system/version.
  • Logs: workspace/temp/siyuan.log (export via /api/system/exportLog).
  • Port discovery: ~/.config/siyuan/port.json (PID → port).

18.2 Scheduled jobs

kernel/job starts a cron (job.StartCron) at boot; model.AutoGenerateFileHistory and watchers run in the background. File history is generated on Editor.GenerateHistoryInterval (default 10 min) and retained for historyRetentionDays (30).

18.3 Index maintenance

Operation Endpoint
Rebuild block index POST /api/system/rebuildDataIndex
Vacuum index POST /api/system/vacuumDataIndex
Reindex asset content POST /api/asset/fullReindexAssetContent
Reindex history POST /api/history/reindexHistory
Clear temp files POST /api/system/clearTempFiles

18.4 Backup & restore

  • Export/Import Data: /api/export/exportData (+ exportDataInFolder) and /api/import/importData.
  • Snapshots: /api/repo/createSnapshot + tagSnapshot; restore via checkoutRepo or rollbackRepoSnapshotFile.
  • Filesystem: copy workspace/data/ while the kernel is stopped.

18.5 Shutdown

POST /api/system/exit (desktop) or stop the container/process. The kernel handles OS signals (model.HandleSignal) to flush and release the workspace lock cleanly.


19. Performance Tuning

Lever Where Effect
dynamicLoadBlocks (48–1024, default 192) Editor Blocks loaded per scroll chunk in big docs
Search.limit (default 64) Search Cap on search results
Sync concurrentReqs / timeout Sync.{s3,webdav,local} Throughput vs. server limits
syncIndexTiming (12s) Repo When to warn about slow indexing → suggests purge
indexRetentionDays / retentionIndexesDaily Repo Local repo size vs. history depth
SIYUAN_PDF_ASSET_CONTENT_INDEX_MAX_SIZE env Skip indexing huge PDFs
Graph.maxBlocks (10240) Graph Graph render size
ControlConcurrency server Kernel API requests are serialized for consistency
  • The kernel uses worker pools (panjf2000/ants) and in-process caches (ristretto, patrickmn/go-cache) for hot paths.
  • For very large workspaces, periodically vacuum the index and purge old repo indexes.

Tip

If indexing is slow (>12s), SiYuan prompts to purge the data repo, which compacts local indexes and usually restores responsiveness.


20. Security Hardening Checklist

  • [ ] Set a strong access auth code (--accessAuthCode / SIYUAN_ACCESS_AUTH_CODE); never leave it blank on a networked instance.
  • [ ] Never set SIYUAN_ACCESS_AUTH_CODE_BYPASS=true on anything reachable by others.
  • [ ] Keep the kernel bound to 127.0.0.1 unless you intentionally enable networkServe.
  • [ ] Front any LAN/internet exposure with a reverse proxy terminating TLS; proxy /ws; avoid URL rewrites.
  • [ ] Treat the API token (Conf.API.Token) as a secret; rotate via /api/system/setAPIToken.
  • [ ] Enable HTTPS (networkServeTLS) for direct network serving; distribute the CA via exportTLSCACert.
  • [ ] Leave SVG/HTML block scripts disabled (AllowSVGScript/AllowHTMLBLockScript = false) unless you fully trust all content.
  • [ ] On the publish service, keep Basic auth on with strong credentials; scope per-document publish access.
  • [ ] Only install plugins/snippets from trusted sources (they run with app privileges).
  • [ ] Back up the repo key; use a passphrase-derived key for portability.
  • [ ] For Docker, align PUID/PGID with volume ownership; don't expose port 6806 directly to the internet.

21. Extensibility: Plugins, Widgets, and the Bazaar

  • Plugins use the petal API; they're loaded via /api/petal/loadPetals and toggled with setPetalEnabled. Globally disable the plugin system with Bazaar.PetalDisabled (or per-plugin). Installed plugins live in data/plugins/ and are served (auth-gated) under /plugins/.
  • Widgets are embeddable mini-apps under data/widgets/, served under /widgets/.
  • Themes/Icons/Templates install into the appearance/data/templates folders; the marketplace (kernel/bazaar) fetches packages and READMEs (rendered with Lute), with batch-update support.
  • Snippets (JS/CSS) provide lightweight customization without packaging a plugin; managed via /api/snippet/* and served under /snippets/ (the snippet conf.json requires admin role).

Important

Plugins and JS snippets execute with the app's privileges. For managed/shared deployments, treat the installed-plugin set and snippet list as a code allowlist and review them.


22. Code Quality and Conventions

  • Polyglot monorepo: Go kernel (kernel/) + TypeScript UI (app/), each with its own build toolchain.
  • Router as source of truth: kernel/api/router.go is the single authoritative endpoint registry; handlers live one-per-domain in kernel/api/*.go and delegate to kernel/model.
  • Config-as-structs: each kernel/conf/*.go struct owns one concern, with JSON tags and NewX() defaults — a clean, discoverable config surface.
  • Vendored renderers: heavy client-side renderers (KaTeX, Mermaid, ECharts, PDF.js, Graphviz, PlantUML, abcjs, highlight.js) are vendored under app/stage/protyle/js/ rather than npm-bundled.
  • First-party ecosystem: core capabilities are split into sibling repos the kernel imports — lute (Markdown), dejavu (repo/sync), riff (FSRS), httpclient, filelock, encryption, logging — keeping the main repo focused.
  • Forked dependencies: go.mod replaces pin a custom SQLite driver and pdfcpu fork.
  • Internationalization-first: source comments are predominantly Chinese; UI strings live in app/appearance/langs/ with English fallback fill-in at serve time.
  • Deprecation discipline: deprecated endpoints are explicitly flagged with a removal date and a migration target in router.go.

23. Potential Improvements

Observations for maintainers and contributors, grounded in the source and community issues:

  • API method semantics: nearly all endpoints are registered as POST regardless of read/write nature; adopting GET for read-only endpoints would improve cacheability and REST conventions (some read endpoints already accept GET).
  • CORS breadth: Access-Control-Allow-Origin: * with credentials relies entirely on token/auth-code secrecy. A configurable origin allowlist would reduce CSRF surface for networked deployments.
  • Deprecated-endpoint cleanup: several endpoints are slated for removal (2026-06-30); ensure plugins/integrations migrate (reloadUI, setLocalStorage, resetBlockAttrs, refreshFiletree).
  • Community-requested features (open issues): a first-class CLI (#17674), MCP (Model Context Protocol) support (#13795), an AI agent (#17797), semantic search via embeddings (#17788), and a refreshed settings UI (#17601).
  • Docker feature parity: documenting clearly (and, where feasible, closing) the export/import gaps in the headless deployment would reduce confusion.
  • CardDAV completeness: handle Thunderbird's current-user-privilege-set PROPFIND.

24. Troubleshooting

Error: boot kernel failed / exits with unavailable-port code

  • Cause: The chosen port is in use, or the kernel can't bind.
  • Solution: Check port.json and free the port, or pass a different --port. Inspect temp/siyuan.log.

Symptom: "The workspace is locked"

  • Cause: Another kernel holds the workspace lock.
  • Solution: Kill the SiYuan-Kernel process (or restart the OS); ensure only one kernel uses a workspace.

Symptom: Database/index errors at boot ("database is unavailable")

  • Cause: Corrupt or unreadable SQLite index, or insufficient permissions.
  • Solution: Verify workspace permissions and disk space; rebuild via /api/system/rebuildDataIndex once booted. Your .sy files remain intact.

Error: S3 sync put chunk failed:

  • Cause: Wrong endpoint/region/keys/bucket or TLS/path-style mismatch.
  • Solution: Re-verify Sync.s3 settings; try pathStyle/skipTlsVerify; confirm write permissions on the bucket.

Error: ip address [%s] is prohibited

  • Cause: The forward-proxy/echo endpoint blocked a request to a disallowed IP (SSRF guard).
  • Solution: Expected for private/blocked targets; route legitimate external requests through an allowed host.

Error: not found executable pandoc

  • Cause: A Pandoc-dependent export with no Pandoc available (headless/Docker or bad pandocBin).
  • Solution: Use the desktop app or set a valid Export.PandocBin.

Error: require upgrade SiYuan to use this plugin [...]

  • Cause: Plugin needs a newer kernel.
  • Solution: Update SiYuan.

Error: TLS errors (failed to decode CA certificate PEM, the provided certificate is not a CA certificate)

  • Cause: Importing an invalid TLS CA bundle.
  • Solution: Provide a valid PEM CA cert+key; regenerate via exportTLSCACert if unsure.

Symptom: Reverse proxy works for pages but realtime updates are broken

  • Cause: /ws WebSocket isn't proxied (or URL rewriting interferes with auth).
  • Solution: Add an explicit WebSocket proxy for /ws; remove rewrite rules.

25. Quick Reference

25.1 Ports & paths

Item Value
Kernel HTTP/WS 6806 (default; --port 0 picks free)
Publish service 6808
Bind 127.0.0.1 (or 0.0.0.0 with networkServe/Docker)
Port discovery file ~/.config/siyuan/port.json
Default workspace ~/SiYuan/
Log workspace/temp/siyuan.log
Config workspace/conf/conf.json
Data repo workspace/repo/

25.2 Kernel flags

--workspace --wd --port --readonly --accessAuthCode --ssl --lang --mode

25.3 Auth model

Layer Mechanism
Access auth code Session password (/check-auth)
API token X-Auth-Token (JWT; Conf.API.Token)
Roles Administrator / Editor / Reader / Visitor
Middleware CheckAuth → CheckAdminRole → CheckReadonly

25.4 Key API entry points

Need Endpoint
List notebooks POST /api/notebook/lsNotebooks
Create doc from MD POST /api/filetree/createDocWithMd
Insert/update/delete block POST /api/block/{insert,update,delete}Block
Batched edit POST /api/transactions
SQL query POST /api/query/sql
Full-text search POST /api/search/fullTextSearchBlock
Export Markdown POST /api/export/exportMd
Trigger sync POST /api/sync/performSync
Get config POST /api/system/getConf

25.5 Core dependencies

Library Role
gin-gonic/gin, olahol/melody HTTP / WebSocket
88250/lute Markdown engine
mattn/go-sqlite3 (88250 fork) Block index
siyuan-note/dejavu Encrypted data repo / sync
siyuan-note/riff + open-spaced-repetition/go-fsrs Flashcards
aws-sdk-go-v2/s3, studio-b12/gowebdav, emersion/go-webdav Sync, CalDAV/CardDAV
klippa-app/go-pdfium, pdfcpu (88250 fork) PDF
otiai10/gosseract OCR (Tesseract)
sashabaranov/go-openai AI
golang-jwt/jwt, gin-contrib/sessions, steambap/captcha Auth
xuri/excelize Spreadsheet export