A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
1[English](https://github.com/siyuan-note/siyuan/blob/master/API.md)
2
3* [规范](#规范)
4 * [参数和返回值](#参数和返回值)
5 * [鉴权](#鉴权)
6* [笔记本](#笔记本)
7 * [列出笔记本](#列出笔记本)
8 * [打开笔记本](#打开笔记本)
9 * [关闭笔记本](#关闭笔记本)
10 * [重命名笔记本](#重命名笔记本)
11 * [创建笔记本](#创建笔记本)
12 * [删除笔记本](#删除笔记本)
13 * [获取笔记本配置](#获取笔记本配置)
14 * [保存笔记本配置](#保存笔记本配置)
15* [文档](#文档)
16 * [通过 Markdown 创建文档](#通过-markdown-创建文档)
17 * [重命名文档](#重命名文档)
18 * [删除文档](#删除文档)
19 * [移动文档](#移动文档)
20 * [根据路径获取人类可读路径](#根据路径获取人类可读路径)
21 * [根据 ID 获取人类可读路径](#根据-ID-获取人类可读路径)
22 * [根据 ID 获取存储路径](#根据-ID-获取存储路径)
23 * [根据人类可读路径获取 IDs](#根据人类可读路径获取-IDs)
24* [资源文件](#资源文件)
25 * [上传资源文件](#上传资源文件)
26* [块](#块)
27 * [插入块](#插入块)
28 * [插入前置子块](#插入前置子块)
29 * [插入后置子块](#插入后置子块)
30 * [更新块](#更新块)
31 * [删除块](#删除块)
32 * [移动块](#移动块)
33 * [折叠块](#折叠块)
34 * [展开块](#展开块)
35 * [获取块 kramdown 源码](#获取块-kramdown-源码)
36 * [获取子块](#获取子块)
37 * [转移块引用](#转移块引用)
38* [属性](#属性)
39 * [设置块属性](#设置块属性)
40 * [获取块属性](#获取块属性)
41* [SQL](#SQL)
42 * [执行 SQL 查询](#执行-SQL-查询)
43 * [提交事务](#提交事务)
44* [模板](#模板)
45 * [渲染模板](#渲染模板)
46 * [渲染 Sprig](#渲染-Sprig)
47* [文件](#文件)
48 * [获取文件](#获取文件)
49 * [写入文件](#写入文件)
50 * [删除文件](#删除文件)
51 * [重命名文件](#重命名文件)
52 * [列出文件](#列出文件)
53* [导出](#导出)
54 * [导出 Markdown 文本](#导出-markdown-文本)
55 * [导出文件与目录](#导出文件与目录)
56* [转换](#转换)
57 * [Pandoc](#Pandoc)
58* [通知](#通知)
59 * [推送消息](#推送消息)
60 * [推送报错消息](#推送报错消息)
61* [网络](#网络)
62 * [正向代理](#正向代理)
63* [系统](#系统)
64 * [获取启动进度](#获取启动进度)
65 * [获取系统版本](#获取系统版本)
66 * [获取系统当前时间](#获取系统当前时间)
67
68---
69
70## 规范
71
72### 参数和返回值
73
74* 端点:`http://127.0.0.1:6806`
75* 均是 POST 方法
76* 需要带参的接口,参数为 JSON 字符串,放置到 body 里,标头 Content-Type 为 `application/json`
77* 返回值
78
79 ```json
80 {
81 "code": 0,
82 "msg": "",
83 "data": {}
84 }
85 ```
86
87 * `code`:非 0 为异常情况
88 * `msg`:正常情况下是空字符串,异常情况下会返回错误文案
89 * `data`:可能为 `{}`、`[]` 或者 `NULL`,根据不同接口而不同
90
91### 鉴权
92
93在 <kbd>设置 - 关于</kbd> 里查看 API token,请求标头:`Authorization: Token xxx`
94
95## 笔记本
96
97### 列出笔记本
98
99* `/api/notebook/lsNotebooks`
100* 不带参
101* 返回值
102
103 ```json
104 {
105 "code": 0,
106 "msg": "",
107 "data": {
108 "notebooks": [
109 {
110 "id": "20210817205410-2kvfpfn",
111 "name": "测试笔记本",
112 "icon": "1f41b",
113 "sort": 0,
114 "closed": false
115 },
116 {
117 "id": "20210808180117-czj9bvb",
118 "name": "思源笔记用户指南",
119 "icon": "1f4d4",
120 "sort": 1,
121 "closed": false
122 }
123 ]
124 }
125 }
126 ```
127
128### 打开笔记本
129
130* `/api/notebook/openNotebook`
131* 参数
132
133 ```json
134 {
135 "notebook": "20210831090520-7dvbdv0"
136 }
137 ```
138
139 * `notebook`:笔记本 ID
140* 返回值
141
142 ```json
143 {
144 "code": 0,
145 "msg": "",
146 "data": null
147 }
148 ```
149
150### 关闭笔记本
151
152* `/api/notebook/closeNotebook`
153* 参数
154
155 ```json
156 {
157 "notebook": "20210831090520-7dvbdv0"
158 }
159 ```
160
161 * `notebook`:笔记本 ID
162* 返回值
163
164 ```json
165 {
166 "code": 0,
167 "msg": "",
168 "data": null
169 }
170 ```
171
172### 重命名笔记本
173
174* `/api/notebook/renameNotebook`
175* 参数
176
177 ```json
178 {
179 "notebook": "20210831090520-7dvbdv0",
180 "name": "笔记本的新名称"
181 }
182 ```
183
184 * `notebook`:笔记本 ID
185* 返回值
186
187 ```json
188 {
189 "code": 0,
190 "msg": "",
191 "data": null
192 }
193 ```
194
195### 创建笔记本
196
197* `/api/notebook/createNotebook`
198* 参数
199
200 ```json
201 {
202 "name": "笔记本的名称"
203 }
204 ```
205* 返回值
206
207 ```json
208 {
209 "code": 0,
210 "msg": "",
211 "data": {
212 "notebook": {
213 "id": "20220126215949-r1wvoch",
214 "name": "笔记本的名称",
215 "icon": "",
216 "sort": 0,
217 "closed": false
218 }
219 }
220 }
221 ```
222
223### 删除笔记本
224
225* `/api/notebook/removeNotebook`
226* 参数
227
228 ```json
229 {
230 "notebook": "20210831090520-7dvbdv0"
231 }
232 ```
233
234 * `notebook`:笔记本 ID
235* 返回值
236
237 ```json
238 {
239 "code": 0,
240 "msg": "",
241 "data": null
242 }
243 ```
244
245### 获取笔记本配置
246
247* `/api/notebook/getNotebookConf`
248* 参数
249
250 ```json
251 {
252 "notebook": "20210817205410-2kvfpfn"
253 }
254 ```
255
256 * `notebook`:笔记本 ID
257* 返回值
258
259 ```json
260 {
261 "code": 0,
262 "msg": "",
263 "data": {
264 "box": "20210817205410-2kvfpfn",
265 "conf": {
266 "name": "测试笔记本",
267 "closed": false,
268 "refCreateSavePath": "",
269 "createDocNameTemplate": "",
270 "dailyNoteSavePath": "/daily note/{{now | date \"2006/01\"}}/{{now | date \"2006-01-02\"}}",
271 "dailyNoteTemplatePath": ""
272 },
273 "name": "测试笔记本"
274 }
275 }
276 ```
277
278### 保存笔记本配置
279
280* `/api/notebook/setNotebookConf`
281* 参数
282
283 ```json
284 {
285 "notebook": "20210817205410-2kvfpfn",
286 "conf": {
287 "name": "测试笔记本",
288 "closed": false,
289 "refCreateSavePath": "",
290 "createDocNameTemplate": "",
291 "dailyNoteSavePath": "/daily note/{{now | date \"2006/01\"}}/{{now | date \"2006-01-02\"}}",
292 "dailyNoteTemplatePath": ""
293 }
294 }
295 ```
296
297 * `notebook`:笔记本 ID
298* 返回值
299
300 ```json
301 {
302 "code": 0,
303 "msg": "",
304 "data": {
305 "name": "测试笔记本",
306 "closed": false,
307 "refCreateSavePath": "",
308 "createDocNameTemplate": "",
309 "dailyNoteSavePath": "/daily note/{{now | date \"2006/01\"}}/{{now | date \"2006-01-02\"}}",
310 "dailyNoteTemplatePath": ""
311 }
312 }
313 ```
314
315## 文档
316
317### 通过 Markdown 创建文档
318
319* `/api/filetree/createDocWithMd`
320* 参数
321
322 ```json
323 {
324 "notebook": "20210817205410-2kvfpfn",
325 "path": "/foo/bar",
326 "markdown": ""
327 }
328 ```
329
330 * `notebook`:笔记本 ID
331 * `path`:文档路径,需要以 / 开头,中间使用 / 分隔层级(这里的 path 对应数据库 hpath 字段)
332 * `markdown`:GFM Markdown 内容
333* 返回值
334
335 ```json
336 {
337 "code": 0,
338 "msg": "",
339 "data": "20210914223645-oj2vnx2"
340 }
341 ```
342
343 * `data`:创建好的文档 ID
344 * 如果使用同一个 `path` 重复调用该接口,不会覆盖已有文档
345
346### 重命名文档
347
348* `/api/filetree/renameDoc`
349* 参数
350
351 ```json
352 {
353 "notebook": "20210831090520-7dvbdv0",
354 "path": "/20210902210113-0avi12f.sy",
355 "title": "文档新标题"
356 }
357 ```
358
359 * `notebook`:笔记本 ID
360 * `path`:文档路径
361 * `title`:新标题
362* 返回值
363
364 ```json
365 {
366 "code": 0,
367 "msg": "",
368 "data": null
369 }
370 ```
371
372通过 `id` 重命名文档:
373
374* `/api/filetree/renameDocByID`
375* 参数
376
377 ```json
378 {
379 "id": "20210902210113-0avi12f",
380 "title": "文档新标题"
381 }
382 ```
383
384 * `id`:文档 ID
385 * `title`:新标题
386* 返回值
387
388 ```json
389 {
390 "code": 0,
391 "msg": "",
392 "data": null
393 }
394 ```
395
396### 删除文档
397
398* `/api/filetree/removeDoc`
399* 参数
400
401 ```json
402 {
403 "notebook": "20210831090520-7dvbdv0",
404 "path": "/20210902210113-0avi12f.sy"
405 }
406 ```
407
408 * `notebook`:笔记本 ID
409 * `path`:文档路径
410* 返回值
411
412 ```json
413 {
414 "code": 0,
415 "msg": "",
416 "data": null
417 }
418 ```
419
420通过 `id` 删除文档:
421
422* `/api/filetree/removeDocByID`
423* 参数
424
425 ```json
426 {
427 "id": "20210902210113-0avi12f"
428 }
429 ```
430
431 * `id`:文档 ID
432* 返回值
433
434 ```json
435 {
436 "code": 0,
437 "msg": "",
438 "data": null
439 }
440 ```
441
442### 移动文档
443
444* `/api/filetree/moveDocs`
445* 参数
446
447 ```json
448 {
449 "fromPaths": ["/20210917220056-yxtyl7i.sy"],
450 "toNotebook": "20210817205410-2kvfpfn",
451 "toPath": "/"
452 }
453 ```
454
455 * `fromPaths`:源路径
456 * `toNotebook`:目标笔记本 ID
457 * `toPath`:目标路径
458* 返回值
459
460 ```json
461 {
462 "code": 0,
463 "msg": "",
464 "data": null
465 }
466 ```
467
468通过 `id` 移动文档:
469
470* `/api/filetree/moveDocsByID`
471* 参数
472
473 ```json
474 {
475 "fromIDs": ["20210917220056-yxtyl7i"],
476 "toID": "20210817205410-2kvfpfn"
477 }
478 ```
479
480 * `fromIDs`:源文档 ID
481 * `toID`:目标父文档 ID 或笔记本 ID
482* 返回值
483
484 ```json
485 {
486 "code": 0,
487 "msg": "",
488 "data": null
489 }
490 ```
491
492### 根据路径获取人类可读路径
493
494* `/api/filetree/getHPathByPath`
495* 参数
496
497 ```json
498 {
499 "notebook": "20210831090520-7dvbdv0",
500 "path": "/20210917220500-sz588nq/20210917220056-yxtyl7i.sy"
501 }
502 ```
503
504 * `notebook`:笔记本 ID
505 * `path`:路径
506* 返回值
507
508 ```json
509 {
510 "code": 0,
511 "msg": "",
512 "data": "/foo/bar"
513 }
514 ```
515
516### 根据 ID 获取人类可读路径
517
518* `/api/filetree/getHPathByID`
519* 参数
520
521 ```json
522 {
523 "id": "20210917220056-yxtyl7i"
524 }
525 ```
526
527 * `id`:块 ID
528* 返回值
529
530 ```json
531 {
532 "code": 0,
533 "msg": "",
534 "data": "/foo/bar"
535 }
536 ```
537
538### 根据 ID 获取存储路径
539
540* `/api/filetree/getPathByID`
541* 参数
542
543 ```json
544 {
545 "id": "20210808180320-fqgskfj"
546 }
547 ```
548
549 * `id`:块 ID
550* 返回值
551
552 ```json
553 {
554 "code": 0,
555 "msg": "",
556 "data": {
557 "notebook": "20210808180117-czj9bvb",
558 "path": "/20200812220555-lj3enxa/20210808180320-fqgskfj.sy"
559 }
560 }
561 ```
562
563### 根据人类可读路径获取 IDs
564
565* `/api/filetree/getIDsByHPath`
566* 参数
567
568 ```json
569 {
570 "path": "/foo/bar",
571 "notebook": "20210808180117-czj9bvb"
572 }
573 ```
574
575 * `path`:人类可读路径
576 * `notebook`:笔记本 ID
577* 返回值
578
579 ```json
580 {
581 "code": 0,
582 "msg": "",
583 "data": [
584 "20200813004931-q4cu8na"
585 ]
586 }
587 ```
588
589## 资源文件
590
591### 上传资源文件
592
593* `/api/asset/upload`
594* 参数为 HTTP Multipart 表单
595
596 * `assetsDirPath`:资源文件存放的文件夹路径,以 data 文件夹作为根路径,比如:
597 * `"/assets/"`:工作空间/data/assets/ 文件夹
598 * `"/assets/sub/"`:工作空间/data/assets/sub/ 文件夹
599
600 常规情况下建议用第一种,统一存放到工作空间资源文件夹下,放在子目录有一些副作用,请参考用户指南资源文件章节。
601 * `file[]`:上传的文件列表
602* 返回值
603
604 ```json
605 {
606 "code": 0,
607 "msg": "",
608 "data": {
609 "errFiles": [""],
610 "succMap": {
611 "foo.png": "assets/foo-20210719092549-9j5y79r.png"
612 }
613 }
614 }
615 ```
616
617 * `errFiles`:处理时遇到错误的文件名
618 * `succMap`:处理成功的文件,key 为上传时的文件名,value 为 assets/foo-id.png,用于将已有 Markdown 内容中的资源文件链接地址替换为上传后的地址
619
620## 块
621
622### 插入块
623
624* `/api/block/insertBlock`
625* 参数
626
627 ```json
628 {
629 "dataType": "markdown",
630 "data": "foo**bar**{: style=\"color: var(--b3-font-color8);\"}baz",
631 "nextID": "",
632 "previousID": "20211229114650-vrek5x6",
633 "parentID": ""
634 }
635 ```
636
637 * `dataType`:待插入数据类型,值可选择 `markdown` 或者 `dom`
638 * `data`:待插入的数据
639 * `nextID`:后一个块的 ID,用于锚定插入位置
640 * `previousID`:前一个块的 ID,用于锚定插入位置
641 * `parentID`:父块 ID,用于锚定插入位置
642
643 `nextID`、`previousID`、`parentID` 三个参数必须至少存在一个有值,优先级为 `nextID` > `previousID` > `parentID`
644* 返回值
645
646 ```json
647 {
648 "code": 0,
649 "msg": "",
650 "data": [
651 {
652 "doOperations": [
653 {
654 "action": "insert",
655 "data": "<div data-node-id=\"20211230115020-g02dfx0\" data-node-index=\"1\" data-type=\"NodeParagraph\" class=\"p\"><div contenteditable=\"true\" spellcheck=\"false\">foo<strong style=\"color: var(--b3-font-color8);\">bar</strong>baz</div><div class=\"protyle-attr\" contenteditable=\"false\"></div></div>",
656 "id": "20211230115020-g02dfx0",
657 "parentID": "",
658 "previousID": "20211229114650-vrek5x6",
659 "retData": null
660 }
661 ],
662 "undoOperations": null
663 }
664 ]
665 }
666 ```
667
668 * `action.data`:新插入块生成的 DOM
669 * `action.id`:新插入块的 ID
670
671### 插入前置子块
672
673* `/api/block/prependBlock`
674* 参数
675
676 ```json
677 {
678 "data": "foo**bar**{: style=\"color: var(--b3-font-color8);\"}baz",
679 "dataType": "markdown",
680 "parentID": "20220107173950-7f9m1nb"
681 }
682 ```
683
684 * `dataType`:待插入数据类型,值可选择 `markdown` 或者 `dom`
685 * `data`:待插入的数据
686 * `parentID`:父块的 ID,用于锚定插入位置
687* 返回值
688
689 ```json
690 {
691 "code": 0,
692 "msg": "",
693 "data": [
694 {
695 "doOperations": [
696 {
697 "action": "insert",
698 "data": "<div data-node-id=\"20220108003710-hm0x9sc\" data-node-index=\"1\" data-type=\"NodeParagraph\" class=\"p\"><div contenteditable=\"true\" spellcheck=\"false\">foo<strong style=\"color: var(--b3-font-color8);\">bar</strong>baz</div><div class=\"protyle-attr\" contenteditable=\"false\"></div></div>",
699 "id": "20220108003710-hm0x9sc",
700 "parentID": "20220107173950-7f9m1nb",
701 "previousID": "",
702 "retData": null
703 }
704 ],
705 "undoOperations": null
706 }
707 ]
708 }
709 ```
710
711 * `action.data`:新插入块生成的 DOM
712 * `action.id`:新插入块的 ID
713
714### 插入后置子块
715
716* `/api/block/appendBlock`
717* 参数
718
719 ```json
720 {
721 "data": "foo**bar**{: style=\"color: var(--b3-font-color8);\"}baz",
722 "dataType": "markdown",
723 "parentID": "20220107173950-7f9m1nb"
724 }
725 ```
726
727 * `dataType`:待插入数据类型,值可选择 `markdown` 或者 `dom`
728 * `data`:待插入的数据
729 * `parentID`:父块的 ID,用于锚定插入位置
730* 返回值
731
732 ```json
733 {
734 "code": 0,
735 "msg": "",
736 "data": [
737 {
738 "doOperations": [
739 {
740 "action": "insert",
741 "data": "<div data-node-id=\"20220108003642-y2wmpcv\" data-node-index=\"1\" data-type=\"NodeParagraph\" class=\"p\"><div contenteditable=\"true\" spellcheck=\"false\">foo<strong style=\"color: var(--b3-font-color8);\">bar</strong>baz</div><div class=\"protyle-attr\" contenteditable=\"false\"></div></div>",
742 "id": "20220108003642-y2wmpcv",
743 "parentID": "20220107173950-7f9m1nb",
744 "previousID": "20220108003615-7rk41t1",
745 "retData": null
746 }
747 ],
748 "undoOperations": null
749 }
750 ]
751 }
752 ```
753
754 * `action.data`:新插入块生成的 DOM
755 * `action.id`:新插入块的 ID
756
757### 更新块
758
759* `/api/block/updateBlock`
760* 参数
761
762 ```json
763 {
764 "dataType": "markdown",
765 "data": "foobarbaz",
766 "id": "20211230161520-querkps"
767 }
768 ```
769
770 * `dataType`:待更新数据类型,值可选择 `markdown` 或者 `dom`
771 * `data`:待更新的数据
772 * `id`:待更新块的 ID
773* 返回值
774
775 ```json
776 {
777 "code": 0,
778 "msg": "",
779 "data": [
780 {
781 "doOperations": [
782 {
783 "action": "update",
784 "data": "<div data-node-id=\"20211230161520-querkps\" data-node-index=\"1\" data-type=\"NodeParagraph\" class=\"p\"><div contenteditable=\"true\" spellcheck=\"false\">foo<strong>bar</strong>baz</div><div class=\"protyle-attr\" contenteditable=\"false\"></div></div>",
785 "id": "20211230161520-querkps",
786 "parentID": "",
787 "previousID": "",
788 "retData": null
789 }
790 ],
791 "undoOperations": null
792 }
793 ]
794 }
795 ```
796
797 * `action.data`:更新块生成的 DOM
798
799### 删除块
800
801* `/api/block/deleteBlock`
802* 参数
803
804 ```json
805 {
806 "id": "20211230161520-querkps"
807 }
808 ```
809
810 * `id`:待删除块的 ID
811* 返回值
812
813 ```json
814 {
815 "code": 0,
816 "msg": "",
817 "data": [
818 {
819 "doOperations": [
820 {
821 "action": "delete",
822 "data": null,
823 "id": "20211230162439-vtm09qo",
824 "parentID": "",
825 "previousID": "",
826 "retData": null
827 }
828 ],
829 "undoOperations": null
830 }
831 ]
832 }
833 ```
834
835### 移动块
836
837* `/api/block/moveBlock`
838* 参数
839
840 ```json
841 {
842 "id": "20230406180530-3o1rqkc",
843 "previousID": "20230406152734-if5kyx6",
844 "parentID": "20230404183855-woe52ko"
845 }
846 ```
847
848 * `id`:待移动块 ID
849 * `previousID`:前一个块的 ID,用于锚定插入位置
850 * `parentID`:父块的 ID,用于锚定插入位置,`previousID` 和 `parentID` 不能同时为空,同时存在的话优先使用 `previousID`
851* 返回值
852
853 ```json
854 {
855 "code": 0,
856 "msg": "",
857 "data": [
858 {
859 "doOperations": [
860 {
861 "action": "move",
862 "data": null,
863 "id": "20230406180530-3o1rqkc",
864 "parentID": "20230404183855-woe52ko",
865 "previousID": "20230406152734-if5kyx6",
866 "nextID": "",
867 "retData": null,
868 "srcIDs": null,
869 "name": "",
870 "type": ""
871 }
872 ],
873 "undoOperations": null
874 }
875 ]
876 }
877 ```
878
879### 折叠块
880
881* `/api/block/foldBlock`
882* 参数
883
884 ```json
885 {
886 "id": "20231224160424-2f5680o"
887 }
888 ```
889
890 * `id`:待折叠块的 ID
891* 返回值
892
893 ```json
894 {
895 "code": 0,
896 "msg": "",
897 "data": null
898 }
899 ```
900
901### 展开块
902
903* `/api/block/unfoldBlock`
904* 参数
905
906 ```json
907 {
908 "id": "20231224160424-2f5680o"
909 }
910 ```
911
912 * `id`:待展开块的 ID
913* 返回值
914
915 ```json
916 {
917 "code": 0,
918 "msg": "",
919 "data": null
920 }
921 ```
922
923### 获取块 kramdown 源码
924
925* `/api/block/getBlockKramdown`
926* 参数
927
928 ```json
929 {
930 "id": "20201225220955-l154bn4"
931 }
932 ```
933
934 * `id`:待获取块的 ID
935* 返回值
936
937 ```json
938 {
939 "code": 0,
940 "msg": "",
941 "data": {
942 "id": "20201225220955-l154bn4",
943 "kramdown": "* {: id=\"20201225220955-2nn1mns\"}新建笔记本,在笔记本下新建文档\n {: id=\"20210131155408-3t627wc\"}\n* {: id=\"20201225220955-uwhqnug\"}在编辑器中输入 <kbd>/</kbd> 触发功能菜单\n {: id=\"20210131155408-btnfw88\"}\n* {: id=\"20201225220955-04ymi2j\"}((20200813131152-0wk5akh \"在内容块中遨游\"))、((20200822191536-rm6hwid \"窗口和页签\"))\n {: id=\"20210131155408-hh1z442\"}"
944 }
945 }
946 ```
947
948### 获取子块
949
950* `/api/block/getChildBlocks`
951* 参数
952
953 ```json
954 {
955 "id": "20230506212712-vt9ajwj"
956 }
957 ```
958
959 * `id`:父块 ID
960 * 标题下方块也算作子块
961* 返回值
962
963 ```json
964 {
965 "code": 0,
966 "msg": "",
967 "data": [
968 {
969 "id": "20230512083858-mjdwkbn",
970 "type": "h",
971 "subType": "h1"
972 },
973 {
974 "id": "20230513213727-thswvfd",
975 "type": "s"
976 },
977 {
978 "id": "20230513213633-9lsj4ew",
979 "type": "l",
980 "subType": "u"
981 }
982 ]
983 }
984 ```
985
986### 转移块引用
987
988* `/api/block/transferBlockRef`
989* 参数
990
991 ```json
992 {
993 "fromID": "20230612160235-mv6rrh1",
994 "toID": "20230613093045-uwcomng",
995 "refIDs": ["20230613092230-cpyimmd"]
996 }
997 ```
998
999 * `fromID`:定义块 ID
1000 * `toID`:目标块 ID
1001 * `refIDs`:指向定义块 ID 的引用所在块 ID,可选,如果不指定,所有指向定义块 ID 的块引用 ID 都会被转移
1002* 返回值
1003
1004 ```json
1005 {
1006 "code": 0,
1007 "msg": "",
1008 "data": null
1009 }
1010 ```
1011
1012## 属性
1013
1014### 设置块属性
1015
1016* `/api/attr/setBlockAttrs`
1017* 参数
1018
1019 ```json
1020 {
1021 "id": "20210912214605-uhi5gco",
1022 "attrs": {
1023 "custom-attr1": "line1\nline2"
1024 }
1025 }
1026 ```
1027
1028 * `id`:块 ID
1029 * `attrs`:块属性,自定义属性必须以 `custom-` 作为前缀
1030* 返回值
1031
1032 ```json
1033 {
1034 "code": 0,
1035 "msg": "",
1036 "data": null
1037 }
1038 ```
1039
1040### 获取块属性
1041
1042* `/api/attr/getBlockAttrs`
1043* 参数
1044
1045 ```json
1046 {
1047 "id": "20210912214605-uhi5gco"
1048 }
1049 ```
1050
1051 * `id`:块 ID
1052* 返回值
1053
1054 ```json
1055 {
1056 "code": 0,
1057 "msg": "",
1058 "data": {
1059 "custom-attr1": "line1\nline2",
1060 "id": "20210912214605-uhi5gco",
1061 "title": "PDF 标注双链演示",
1062 "type": "doc",
1063 "updated": "20210916120715"
1064 }
1065 }
1066 ```
1067
1068## SQL
1069
1070### 执行 SQL 查询
1071
1072* `/api/query/sql`
1073* 参数
1074
1075 ```json
1076 {
1077 "stmt": "SELECT * FROM blocks WHERE content LIKE'%content%' LIMIT 7"
1078 }
1079 ```
1080
1081 * `stmt`:SQL 脚本
1082* 返回值
1083
1084 ```json
1085 {
1086 "code": 0,
1087 "msg": "",
1088 "data": [
1089 { "列": "值" }
1090 ]
1091 }
1092 ```
1093
1094### 提交事务
1095
1096* `/api/sqlite/flushTransaction`
1097* 不带参
1098* 返回值
1099
1100 ```json
1101 {
1102 "code": 0,
1103 "msg": "",
1104 "data": null
1105 }
1106 ```
1107
1108## 模板
1109
1110### 渲染模板
1111
1112* `/api/template/render`
1113* 参数
1114
1115 ```json
1116 {
1117 "id": "20220724223548-j6g0o87",
1118 "path": "F:\\SiYuan\\data\\templates\\foo.md"
1119 }
1120 ```
1121 * `id`:调用渲染所在的文档 ID
1122 * `path`:模板文件绝对路径
1123* 返回值
1124
1125 ```json
1126 {
1127 "code": 0,
1128 "msg": "",
1129 "data": {
1130 "content": "<div data-node-id=\"20220729234848-dlgsah7\" data-node-index=\"1\" data-type=\"NodeParagraph\" class=\"p\" updated=\"20220729234840\"><div contenteditable=\"true\" spellcheck=\"false\">foo</div><div class=\"protyle-attr\" contenteditable=\"false\"></div></div>",
1131 "path": "F:\\SiYuan\\data\\templates\\foo.md"
1132 }
1133 }
1134 ```
1135
1136### 渲染 Sprig
1137
1138* `/api/template/renderSprig`
1139* 参数
1140
1141 ```json
1142 {
1143 "template": "/daily note/{{now | date \"2006/01\"}}/{{now | date \"2006-01-02\"}}"
1144 }
1145 ```
1146 * `template`:模板内容
1147* 返回值
1148
1149 ```json
1150 {
1151 "code": 0,
1152 "msg": "",
1153 "data": "/daily note/2023/03/2023-03-24"
1154 }
1155 ```
1156
1157## 文件
1158
1159### 获取文件
1160
1161* `/api/file/getFile`
1162* 参数
1163
1164 ```json
1165 {
1166 "path": "/data/20210808180117-6v0mkxr/20200923234011-ieuun1p.sy"
1167 }
1168 ```
1169 * `path`:工作空间路径下的文件路径
1170* 返回值
1171
1172 * 响应状态码 `200`: 文件内容
1173 * 响应状态码 `202`: 异常信息
1174
1175 ```json
1176 {
1177 "code": 404,
1178 "msg": "",
1179 "data": null
1180 }
1181 ```
1182
1183 * `code`: 非零的异常值
1184
1185 * `-1`: 参数解析错误
1186 * `403`: 无访问权限 (文件不在工作空间下)
1187 * `404`: 未找到 (文件不存在)
1188 * `405`: 方法不被允许 (这是一个目录)
1189 * `500`: 服务器错误 (文件查询失败 / 文件读取失败)
1190 * `msg`: 一段描述错误的文本
1191
1192### 写入文件
1193
1194* `/api/file/putFile`
1195* 参数为 HTTP Multipart 表单
1196
1197 * `path`:工作空间路径下的文件路径
1198 * `isDir`:是否为创建文件夹,为 `true` 时仅创建文件夹,忽略 `file`
1199 * `modTime`:最近访问和修改时间,Unix time
1200 * `file`:上传的文件
1201* 返回值
1202
1203 ```json
1204 {
1205 "code": 0,
1206 "msg": "",
1207 "data": null
1208 }
1209 ```
1210
1211### 删除文件
1212
1213* `/api/file/removeFile`
1214* 参数
1215
1216 ```json
1217 {
1218 "path": "/data/20210808180117-6v0mkxr/20200923234011-ieuun1p.sy"
1219 }
1220 ```
1221 * `path`:工作空间路径下的文件路径
1222* 返回值
1223
1224 ```json
1225 {
1226 "code": 0,
1227 "msg": "",
1228 "data": null
1229 }
1230 ```
1231
1232### 重命名文件
1233
1234* `/api/file/renameFile`
1235* 参数
1236
1237 ```json
1238 {
1239 "path": "/data/assets/image-20230523085812-k3o9t32.png",
1240 "newPath": "/data/assets/test-20230523085812-k3o9t32.png"
1241 }
1242 ```
1243 * `path`:工作空间路径下的文件路径
1244 * `newPath`:新的文件路径
1245* 返回值
1246
1247 ```json
1248 {
1249 "code": 0,
1250 "msg": "",
1251 "data": null
1252 }
1253 ```
1254
1255### 列出文件
1256
1257* `/api/file/readDir`
1258* 参数
1259
1260 ```json
1261 {
1262 "path": "/data/20210808180117-6v0mkxr/20200923234011-ieuun1p"
1263 }
1264 ```
1265 * `path`:工作空间路径下的文件夹路径
1266* 返回值
1267
1268 ```json
1269 {
1270 "code": 0,
1271 "msg": "",
1272 "data": [
1273 {
1274 "isDir": true,
1275 "isSymlink": false,
1276 "name": "20210808180303-6yi0dv5",
1277 "updated": 1691467624
1278 },
1279 {
1280 "isDir": false,
1281 "isSymlink": false,
1282 "name": "20210808180303-6yi0dv5.sy",
1283 "updated": 1663298365
1284 }
1285 ]
1286 }
1287 ```
1288
1289## 导出
1290
1291### 导出 Markdown 文本
1292
1293* `/api/export/exportMdContent`
1294* 参数
1295
1296 ```json
1297 {
1298 "id": ""
1299 }
1300 ```
1301
1302 * `id`:要导出的文档块 ID
1303* 返回值
1304
1305 ```json
1306 {
1307 "code": 0,
1308 "msg": "",
1309 "data": {
1310 "hPath": "/0 请从这里开始",
1311 "content": "## 🍫 内容块\n\n在思源中,唯一重要的核心概念是..."
1312 }
1313 }
1314 ```
1315
1316 * `hPath`:人类可读的路径
1317 * `content`:Markdown 内容
1318
1319### 导出文件与目录
1320
1321* `/api/export/exportResources`
1322* 参数
1323
1324 ```json
1325 {
1326 "paths": [
1327 "/conf/appearance/boot",
1328 "/conf/appearance/langs",
1329 "/conf/appearance/emojis/conf.json",
1330 "/conf/appearance/icons/index.html"
1331 ],
1332 "name": "zip-file-name"
1333 }
1334 ```
1335
1336 * `paths`:要导出的文件或文件夹路径列表,相同名称的文件/文件夹会被覆盖
1337 * `name`:(可选)导出的文件名,未设置时默认为 `export-YYYY-MM-DD_hh-mm-ss.zip`
1338* 返回值
1339
1340 ```json
1341 {
1342 "code": 0,
1343 "msg": "",
1344 "data": {
1345 "path": "temp/export/zip-file-name.zip"
1346 }
1347 }
1348 ```
1349
1350 * `path`:创建的 `*.zip` 文件路径
1351 * `zip-file-name.zip` 中的目录结构如下所示:
1352 * `zip-file-name`
1353 * `boot`
1354 * `langs`
1355 * `conf.json`
1356 * `index.html`
1357
1358## 转换
1359
1360### Pandoc
1361
1362* `/api/convert/pandoc`
1363* 工作目录
1364 * 执行调用 pandoc 命令时工作目录会被设置在 `工作空间/temp/convert/pandoc/${test}` 下
1365 * 可先通过 API [`写入文件`](#写入文件) 将待转换文件写入该目录
1366 * 然后再调用该 API 进行转换,转换后的文件也会被写入该目录
1367 * 最后调用 API [`获取文件`](#获取文件) 获取转换后的文件内容
1368 * 或者调用 API [`通过 Markdown 创建文档`](#通过-markdown-创建文档)
1369 * 或者调用内部 API `importStdMd` 将转换后的文件夹直接导入
1370* 参数
1371
1372 ```json
1373 {
1374 "dir": "test",
1375 "args": [
1376 "--to", "markdown_strict-raw_html",
1377 "foo.epub",
1378 "-o", "foo.md"
1379 ]
1380 }
1381 ```
1382
1383 * `args`:Pandoc 命令行参数
1384* 返回值
1385
1386 ```json
1387 {
1388 "code": 0,
1389 "msg": "",
1390 "data": {
1391 "path": "/temp/convert/pandoc/test"
1392 }
1393 }
1394 ```
1395 * `path`:工作空间下的路径
1396
1397## 通知
1398
1399### 推送消息
1400
1401* `/api/notification/pushMsg`
1402* 参数
1403
1404 ```json
1405 {
1406 "msg": "test",
1407 "timeout": 7000
1408 }
1409 ```
1410 * `timeout`:消息持续显示时间,单位为毫秒。可以不传入该字段,默认为 7000 毫秒
1411* 返回值
1412
1413 ```json
1414 {
1415 "code": 0,
1416 "msg": "",
1417 "data": {
1418 "id": "62jtmqi"
1419 }
1420 }
1421 ```
1422 * `id`:消息 ID
1423
1424### 推送报错消息
1425
1426* `/api/notification/pushErrMsg`
1427* 参数
1428
1429 ```json
1430 {
1431 "msg": "test",
1432 "timeout": 7000
1433 }
1434 ```
1435 * `timeout`:消息持续显示时间,单位为毫秒。可以不传入该字段,默认为 7000 毫秒
1436* 返回值
1437
1438 ```json
1439 {
1440 "code": 0,
1441 "msg": "",
1442 "data": {
1443 "id": "qc9znut"
1444 }
1445 }
1446 ```
1447 * `id`:消息 ID
1448
1449## 网络
1450
1451### 正向代理
1452
1453* `/api/network/forwardProxy`
1454* 参数
1455
1456 ```json
1457 {
1458 "url": "https://b3log.org/siyuan/",
1459 "method": "GET",
1460 "timeout": 7000,
1461 "contentType": "text/html",
1462 "headers": [
1463 {
1464 "Cookie": ""
1465 }
1466 ],
1467 "payload": {},
1468 "payloadEncoding": "text",
1469 "responseEncoding": "text"
1470 }
1471 ```
1472
1473 * `url`:转发的 URL
1474 * `method`:HTTP 方法,默认为 `GET`
1475 * `timeout`:超时时间,单位为毫秒,默认为 `7000` 毫秒
1476 * `contentType`:HTTP Content-Type,默认为 `application/json`
1477 * `headers`:HTTP 请求标头
1478 * `payload`:HTTP 请求体,对象或者是字符串
1479 * `payloadEncoding`:`pyaload` 所使用的编码方案,默认为 `text`,可选值如下所示
1480
1481 * `text`
1482 * `base64` | `base64-std`
1483 * `base64-url`
1484 * `base32` | `base32-std`
1485 * `base32-hex`
1486 * `hex`
1487 * `responseEncoding`:响应数据中 `body` 字段所使用的编码方案,默认为 `text`,可选值如下所示
1488
1489 * `text`
1490 * `base64` | `base64-std`
1491 * `base64-url`
1492 * `base32` | `base32-std`
1493 * `base32-hex`
1494 * `hex`
1495* 返回值
1496
1497 ```json
1498 {
1499 "code": 0,
1500 "msg": "",
1501 "data": {
1502 "body": "",
1503 "bodyEncoding": "text",
1504 "contentType": "text/html",
1505 "elapsed": 1976,
1506 "headers": {
1507 },
1508 "status": 200,
1509 "url": "https://b3log.org/siyuan"
1510 }
1511 }
1512 ```
1513
1514 * `bodyEncoding`:`body` 所使用的编码方案,与请求中 `responseEncoding` 字段一致,默认为 `text`,可能的值如下所示
1515
1516 * `text`
1517 * `base64` | `base64-std`
1518 * `base64-url`
1519 * `base32` | `base32-std`
1520 * `base32-hex`
1521 * `hex`
1522
1523## 系统
1524
1525### 获取启动进度
1526
1527* `/api/system/bootProgress`
1528* 不带参
1529* 返回值
1530
1531 ```json
1532 {
1533 "code": 0,
1534 "msg": "",
1535 "data": {
1536 "details": "Finishing boot...",
1537 "progress": 100
1538 }
1539 }
1540 ```
1541
1542### 获取系统版本
1543
1544* `/api/system/version`
1545* 不带参
1546* 返回值
1547
1548 ```json
1549 {
1550 "code": 0,
1551 "msg": "",
1552 "data": "1.3.5"
1553 }
1554 ```
1555
1556### 获取系统当前时间
1557
1558* `/api/system/currentTime`
1559* 不带参
1560* 返回值
1561
1562 ```json
1563 {
1564 "code": 0,
1565 "msg": "",
1566 "data": 1631850968131
1567 }
1568 ```
1569
1570 * `data`: 精度为毫秒