benjivers/notes Public Public: anyone can read this; nobody can change it.

Files 9965609c46dc660e7b5b52f91658bb8a67c37294
701 lines · 18.6 KB · ~6.4k tok Raw History
1
{
2
  "openapi": "3.1.0",
3
  "info": {
4
    "title": "notes",
5
    "version": "1.1.0",
6
    "description": "A personal linked-notes vault — markdown, [[wikilinks]], backlinks, tags, graph."
7
  },
8
  "paths": {
9
    "/api/notes": {
10
      "get": {
11
        "summary": "Your notes, pinned first then most recently changed; with `q`, the ones a search finds (words, \"a phrase\", #tag), best first. With `space`, a shared folder's instead.",
12
        "operationId": "getApiNotes",
13
        "parameters": [
14
          {
15
            "name": "limit",
16
            "in": "query",
17
            "schema": {
18
              "type": "integer",
19
              "minimum": 1,
20
              "maximum": 5000
21
            }
22
          },
23
          {
24
            "name": "space",
25
            "in": "query",
26
            "schema": {
27
              "type": "integer"
28
            }
29
          },
30
          {
31
            "name": "q",
32
            "in": "query",
33
            "schema": {
34
              "type": "string",
35
              "maxLength": 500
36
            }
37
          }
38
        ],
39
        "responses": {
40
          "200": {
41
            "description": "Your notes, pinned first then most recently changed; with `q`, the ones a search finds (words, \"a phrase\", #tag), best first. With `space`, a shared folder's instead.",
42
            "content": {
43
              "application/json": {
44
                "schema": {
45
                  "type": "array",
46
                  "items": {
47
                    "$ref": "#/components/schemas/Note"
48
                  }
49
                }
50
              }
51
            }
52
          },
53
          "default": {
54
            "description": "{ error, message }: why not",
55
            "content": {
56
              "application/json": {
57
                "schema": {
58
                  "$ref": "#/components/schemas/Error"
59
                }
60
              }
61
            }
62
          }
63
        },
64
        "x-contract": {
65
          "resource": "note",
66
          "verb": "list",
67
          "least": "member"
68
        }
69
      },
70
      "post": {
71
        "summary": "Add a note to your vault.",
72
        "operationId": "postApiNotes",
73
        "requestBody": {
74
          "required": true,
75
          "content": {
76
            "application/json": {
77
              "schema": {
78
                "type": "object",
79
                "properties": {
80
                  "title": {
81
                    "type": "string",
82
                    "maxLength": 200,
83
                    "description": "Unique in your vault; “Untitled” when left out."
84
                  },
85
                  "body": {
86
                    "type": "string",
87
                    "maxLength": 200000,
88
                    "description": "Markdown."
89
                  },
90
                  "space": {
91
                    "type": "integer",
92
                    "description": "A shared folder you are in, to add the note there instead of your vault."
93
                  },
94
                  "folder": {
95
                    "type": "string",
96
                    "description": "In a shared folder: the folder to put it in (`ideas/q4`)."
97
                  }
98
                }
99
              }
100
            }
101
          }
102
        },
103
        "responses": {
104
          "201": {
105
            "description": "Add a note to your vault.",
106
            "content": {
107
              "application/json": {
108
                "schema": {
109
                  "$ref": "#/components/schemas/Note"
110
                }
111
              }
112
            }
113
          },
114
          "default": {
115
            "description": "{ error, message }: why not",
116
            "content": {
117
              "application/json": {
118
                "schema": {
119
                  "$ref": "#/components/schemas/Error"
120
                }
121
              }
122
            }
123
          }
124
        },
125
        "x-contract": {
126
          "resource": "note",
127
          "verb": "create",
128
          "least": "user"
129
        }
130
      }
131
    },
132
    "/api/notes/{id}": {
133
      "get": {
134
        "summary": "One of your notes.",
135
        "operationId": "getApiNotesId",
136
        "parameters": [
137
          {
138
            "name": "id",
139
            "in": "path",
140
            "required": true,
141
            "schema": {
142
              "type": "integer"
143
            }
144
          }
145
        ],
146
        "responses": {
147
          "200": {
148
            "description": "One of your notes.",
149
            "content": {
150
              "application/json": {
151
                "schema": {
152
                  "$ref": "#/components/schemas/Note"
153
                }
154
              }
155
            }
156
          },
157
          "default": {
158
            "description": "{ error, message }: why not",
159
            "content": {
160
              "application/json": {
161
                "schema": {
162
                  "$ref": "#/components/schemas/Error"
163
                }
164
              }
165
            }
166
          }
167
        },
168
        "x-contract": {
169
          "resource": "note",
170
          "verb": "read",
171
          "least": "member"
172
        }
173
      },
174
      "patch": {
175
        "summary": "Change a note's title, words or pin; a rename rewrites the links to it. `relinked` says how many notes that touched.",
176
        "operationId": "patchApiNotesId",
177
        "parameters": [
178
          {
179
            "name": "id",
180
            "in": "path",
181
            "required": true,
182
            "schema": {
183
              "type": "integer"
184
            }
185
          }
186
        ],
187
        "requestBody": {
188
          "required": true,
189
          "content": {
190
            "application/json": {
191
              "schema": {
192
                "type": "object",
193
                "properties": {
194
                  "title": {
195
                    "type": "string",
196
                    "minLength": 1,
197
                    "maxLength": 200,
198
                    "description": "A rename carries every [[link]] to the note with it."
199
                  },
200
                  "body": {
201
                    "type": "string",
202
                    "maxLength": 200000
203
                  },
204
                  "pinned": {
205
                    "type": "boolean"
206
                  },
207
                  "folder": {
208
                    "type": "string",
209
                    "description": "A shared note's folder: moves its file."
210
                  },
211
                  "base": {
212
                    "type": "string",
213
                    "format": "date-time",
214
                    "description": "The updated_at you edited from; when someone has saved since, new words are refused with 409."
215
                  }
216
                }
217
              }
218
            }
219
          }
220
        },
221
        "responses": {
222
          "200": {
223
            "description": "Change a note's title, words or pin; a rename rewrites the links to it. `relinked` says how many notes that touched.",
224
            "content": {
225
              "application/json": {
226
                "schema": {
227
                  "allOf": [
228
                    {
229
                      "type": "object",
230
                      "properties": {
231
                        "id": {
232
                          "type": "integer"
233
                        },
234
                        "title": {
235
                          "type": "string",
236
                          "minLength": 1,
237
                          "maxLength": 200
238
                        },
239
                        "body": {
240
                          "type": "string",
241
                          "maxLength": 200000
242
                        },
243
                        "pinned": {
244
                          "enum": [
245
                            0,
246
                            1
247
                          ]
248
                        },
249
                        "author_id": {
250
                          "type": "string"
251
                        },
252
                        "author_name": {
253
                          "type": "string"
254
                        },
255
                        "created_at": {
256
                          "type": "string",
257
                          "format": "date-time"
258
                        },
259
                        "updated_at": {
260
                          "type": "string",
261
                          "format": "date-time"
262
                        },
263
                        "path": {
264
                          "type": [
265
                            "string",
266
                            "null"
267
                          ],
268
                          "description": "A shared folder's note: its file in the repository. Null for a note of your own."
269
                        }
270
                      },
271
                      "required": [
272
                        "id",
273
                        "title",
274
                        "body",
275
                        "pinned",
276
                        "author_id",
277
                        "author_name",
278
                        "created_at",
279
                        "updated_at"
280
                      ]
281
                    },
282
                    {
283
                      "type": "object",
284
                      "properties": {
285
                        "relinked": {
286
                          "type": "integer"
287
                        }
288
                      },
289
                      "required": [
290
                        "relinked"
291
                      ]
292
                    }
293
                  ]
294
                }
295
              }
296
            }
297
          },
298
          "default": {
299
            "description": "{ error, message }: why not",
300
            "content": {
301
              "application/json": {
302
                "schema": {
303
                  "$ref": "#/components/schemas/Error"
304
                }
305
              }
306
            }
307
          }
308
        },
309
        "x-contract": {
310
          "resource": "note",
311
          "verb": "update",
312
          "least": "member"
313
        }
314
      },
315
      "delete": {
316
        "summary": "Remove a note.",
317
        "operationId": "deleteApiNotesId",
318
        "parameters": [
319
          {
320
            "name": "id",
321
            "in": "path",
322
            "required": true,
323
            "schema": {
324
              "type": "integer"
325
            }
326
          }
327
        ],
328
        "responses": {
329
          "200": {
330
            "description": "Remove a note.",
331
            "content": {
332
              "application/json": {
333
                "schema": {
334
                  "type": "object",
335
                  "properties": {
336
                    "id": {
337
                      "type": "integer"
338
                    }
339
                  },
340
                  "required": [
341
                    "id"
342
                  ]
343
                }
344
              }
345
            }
346
          },
347
          "default": {
348
            "description": "{ error, message }: why not",
349
            "content": {
350
              "application/json": {
351
                "schema": {
352
                  "$ref": "#/components/schemas/Error"
353
                }
354
              }
355
            }
356
          }
357
        },
358
        "x-contract": {
359
          "resource": "note",
360
          "verb": "delete",
361
          "least": "member"
362
        }
363
      }
364
    },
365
    "/api/audit": {
366
      "get": {
367
        "summary": "The audit trail, newest first; `before` pages back by id.",
368
        "operationId": "getApiAudit",
369
        "parameters": [
370
          {
371
            "name": "limit",
372
            "in": "query",
373
            "schema": {
374
              "type": "integer",
375
              "minimum": 1,
376
              "maximum": 500,
377
              "default": 100
378
            }
379
          },
380
          {
381
            "name": "before",
382
            "in": "query",
383
            "schema": {
384
              "type": "integer"
385
            }
386
          }
387
        ],
388
        "responses": {
389
          "200": {
390
            "description": "The audit trail, newest first; `before` pages back by id.",
391
            "content": {
392
              "application/json": {
393
                "schema": {
394
                  "type": "array",
395
                  "items": {
396
                    "$ref": "#/components/schemas/AuditRow"
397
                  }
398
                }
399
              }
400
            }
401
          },
402
          "default": {
403
            "description": "{ error, message }: why not",
404
            "content": {
405
              "application/json": {
406
                "schema": {
407
                  "$ref": "#/components/schemas/Error"
408
                }
409
              }
410
            }
411
          }
412
        },
413
        "x-contract": {
414
          "resource": "audit",
415
          "verb": "list",
416
          "least": "admin"
417
        }
418
      }
419
    },
420
    "/api/audit/{id}": {
421
      "get": {
422
        "summary": "One row of the audit trail.",
423
        "operationId": "getApiAuditId",
424
        "parameters": [
425
          {
426
            "name": "id",
427
            "in": "path",
428
            "required": true,
429
            "schema": {
430
              "type": "integer"
431
            }
432
          }
433
        ],
434
        "responses": {
435
          "200": {
436
            "description": "One row of the audit trail.",
437
            "content": {
438
              "application/json": {
439
                "schema": {
440
                  "$ref": "#/components/schemas/AuditRow"
441
                }
442
              }
443
            }
444
          },
445
          "default": {
446
            "description": "{ error, message }: why not",
447
            "content": {
448
              "application/json": {
449
                "schema": {
450
                  "$ref": "#/components/schemas/Error"
451
                }
452
              }
453
            }
454
          }
455
        },
456
        "x-contract": {
457
          "resource": "audit",
458
          "verb": "read",
459
          "least": "admin"
460
        }
461
      }
462
    },
463
    "/mcp": {
464
      "post": {
465
        "summary": "One JSON-RPC 2.0 message to the MCP server; its tools are the actions.",
466
        "operationId": "postMcp",
467
        "requestBody": {
468
          "required": true,
469
          "content": {
470
            "application/json": {
471
              "schema": {
472
                "type": "object",
473
                "properties": {
474
                  "jsonrpc": {
475
                    "const": "2.0"
476
                  },
477
                  "id": {},
478
                  "method": {
479
                    "type": "string"
480
                  },
481
                  "params": {
482
                    "type": "object"
483
                  }
484
                },
485
                "required": [
486
                  "jsonrpc",
487
                  "method"
488
                ]
489
              }
490
            }
491
          }
492
        },
493
        "responses": {
494
          "200": {
495
            "description": "One JSON-RPC 2.0 message to the MCP server; its tools are the actions.",
496
            "content": {
497
              "application/json": {
498
                "schema": {
499
                  "type": "object"
500
                }
501
              }
502
            }
503
          },
504
          "default": {
505
            "description": "{ error, message }: why not",
506
            "content": {
507
              "application/json": {
508
                "schema": {
509
                  "$ref": "#/components/schemas/Error"
510
                }
511
              }
512
            }
513
          }
514
        }
515
      }
516
    },
517
    "/healthz": {
518
      "get": {
519
        "summary": "Whether the app is up: its version, commit, environment and seconds since it started.",
520
        "operationId": "getHealthz",
521
        "responses": {
522
          "200": {
523
            "description": "Whether the app is up: its version, commit, environment and seconds since it started.",
524
            "content": {
525
              "application/json": {
526
                "schema": {
527
                  "type": "object",
528
                  "properties": {
529
                    "ok": {
530
                      "type": "boolean"
531
                    },
532
                    "version": {
533
                      "type": "string"
534
                    },
535
                    "commit": {
536
                      "type": "string"
537
                    },
538
                    "env": {
539
                      "type": "string"
540
                    },
541
                    "uptime": {
542
                      "type": "integer"
543
                    }
544
                  },
545
                  "required": [
546
                    "ok",
547
                    "version",
548
                    "uptime"
549
                  ]
550
                }
551
              }
552
            }
553
          },
554
          "default": {
555
            "description": "{ error, message }: why not",
556
            "content": {
557
              "application/json": {
558
                "schema": {
559
                  "$ref": "#/components/schemas/Error"
560
                }
561
              }
562
            }
563
          }
564
        }
565
      }
566
    }
567
  },
568
  "components": {
569
    "schemas": {
570
      "Note": {
571
        "type": "object",
572
        "properties": {
573
          "id": {
574
            "type": "integer"
575
          },
576
          "title": {
577
            "type": "string",
578
            "minLength": 1,
579
            "maxLength": 200
580
          },
581
          "body": {
582
            "type": "string",
583
            "maxLength": 200000
584
          },
585
          "pinned": {
586
            "enum": [
587
              0,
588
              1
589
            ]
590
          },
591
          "author_id": {
592
            "type": "string"
593
          },
594
          "author_name": {
595
            "type": "string"
596
          },
597
          "created_at": {
598
            "type": "string",
599
            "format": "date-time"
600
          },
601
          "updated_at": {
602
            "type": "string",
603
            "format": "date-time"
604
          },
605
          "path": {
606
            "type": [
607
              "string",
608
              "null"
609
            ],
610
            "description": "A shared folder's note: its file in the repository. Null for a note of your own."
611
          }
612
        },
613
        "required": [
614
          "id",
615
          "title",
616
          "body",
617
          "pinned",
618
          "author_id",
619
          "author_name",
620
          "created_at",
621
          "updated_at"
622
        ]
623
      },
624
      "AuditRow": {
625
        "type": "object",
626
        "properties": {
627
          "id": {
628
            "type": "integer"
629
          },
630
          "at": {
631
            "type": "string",
632
            "format": "date-time"
633
          },
634
          "who_id": {
635
            "type": [
636
              "string",
637
              "null"
638
            ]
639
          },
640
          "who_name": {
641
            "type": [
642
              "string",
643
              "null"
644
            ]
645
          },
646
          "role": {
647
            "enum": [
648
              "anon",
649
              "user",
650
              "admin"
651
            ]
652
          },
653
          "resource": {
654
            "type": "string"
655
          },
656
          "verb": {
657
            "type": "string"
658
          },
659
          "target": {
660
            "type": [
661
              "string",
662
              "null"
663
            ]
664
          },
665
          "allowed": {
666
            "enum": [
667
              0,
668
              1
669
            ]
670
          },
671
          "outcome": {
672
            "type": "string"
673
          }
674
        },
675
        "required": [
676
          "id",
677
          "at",
678
          "role",
679
          "resource",
680
          "verb",
681
          "allowed",
682
          "outcome"
683
        ]
684
      },
685
      "Error": {
686
        "type": "object",
687
        "properties": {
688
          "error": {
689
            "type": "string"
690
          },
691
          "message": {
692
            "type": "string"
693
          }
694
        },
695
        "required": [
696
          "error"
697
        ]
698
      }
699
    }
700
  }
701
}
↑↓ navigate ↵ open esc close
↑↓ navigate ↵ open esc close

Keyboard shortcuts