Neues pageListQuerySchema (ISO 8601, Kulanz für Datum ohne Zeit), Query-Parameter auf interner und Public-API-Seitenliste, Prisma-where mit gte; neue Indizes (pondId, createdAt)/(pondId, updatedAt) als Migration. OpenAPI-Parameter, MCP-Parität (list_pages created_since/updated_since), Doku (api-guide, mcp-guide, public-api.md), DB-Test inkl. 400 bei ungültigem Datum. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0155v2aT8AG1kZDQEZiCLBWC
147 lines
5.5 KiB
Markdown
147 lines
5.5 KiB
Markdown
# API-Handbuch
|
|
|
|
_Englisches Original: [docs/manual/api-guide.md](../../manual/api-guide.md)_
|
|
|
|
Wie du aus Skripten und Integrationen mit Dorfteich sprichst. Die
|
|
öffentliche REST-API liegt unter `/api/public/v1`; ihre
|
|
maschinenlesbare Beschreibung wird unter `/api/public/v1/openapi.json`
|
|
ausgeliefert.
|
|
|
|
## Einschalten
|
|
|
|
Die API ist **standardmäßig aus**, und zwar doppelt:
|
|
|
|
1. Ein **Site-Admin** aktiviert den Instanz-Schalter (Admin →
|
|
Einstellungen → Öffentliche API).
|
|
2. Jeder **Teich**, der erreichbar sein soll, stimmt zu
|
|
(Teich-Einstellungen → „Diesen Teich über die öffentliche API
|
|
freigeben").
|
|
|
|
Alles Nicht-Freigeschaltete antwortet mit `404` — ununterscheidbar von
|
|
einer Instanz ohne dieses Feature.
|
|
|
|
## Persönliche API-Tokens
|
|
|
|
Tokens legst du unter **Einstellungen → API-Tokens** an: ein Name, ein
|
|
Scope (`read` oder `read+write`), ein optionales Ablaufdatum und
|
|
optional eine Beschränkung auf ausgewählte Teiche. Das Geheimnis
|
|
(`dt_pat_…`) wird **ein einziges Mal** angezeigt — sofort kopieren.
|
|
Tokens sind widerrufbar und zeigen ihre letzte Verwendung.
|
|
|
|
Ein Token handelt **als du**: Es kann exakt lesen und schreiben, was du
|
|
kannst, eingeengt durch seinen Scope und die Teich-Beschränkung — nie
|
|
mehr. Die Token-Verwaltung selbst verlangt immer die Browser-Sitzung;
|
|
ein geleaktes Token kann keine neuen Tokens erzeugen.
|
|
|
|
Authentifiziere dich mit einem Bearer-Header:
|
|
|
|
```sh
|
|
curl -H "Authorization: Bearer dt_pat_..." \
|
|
https://wiki.example.com/api/public/v1/me
|
|
```
|
|
|
|
`GET /me` ist der Smoke-Test — er liefert dein Benutzerkonto, den
|
|
Token-Scope und eine etwaige Teich-Beschränkung.
|
|
|
|
## Lesen
|
|
|
|
```sh
|
|
# Die Teiche, die dieses Token erreicht
|
|
curl -H "$AUTH" https://wiki.example.com/api/public/v1/ponds
|
|
|
|
# Seiten eines Teichs: Slug, Titel, Parent (Seitenbaum-Slug), Labels, Zeitstempel
|
|
curl -H "$AUTH" https://wiki.example.com/api/public/v1/ponds/team/pages
|
|
|
|
# Nur Seiten, die seit einem ISO-8601-Zeitpunkt erstellt/geändert wurden (#148)
|
|
curl -H "$AUTH" "https://wiki.example.com/api/public/v1/ponds/team/pages?updatedSince=2026-07-01T00:00:00Z"
|
|
|
|
# Eine Seite — Markdown-Quelle UND gerendertes, bereinigtes HTML
|
|
curl -H "$AUTH" https://wiki.example.com/api/public/v1/ponds/team/pages/meeting-notes
|
|
|
|
# Volltextsuche (optional ?pond=<slug>&label=<labelId>)
|
|
curl -H "$AUTH" "https://wiki.example.com/api/public/v1/search?q=seerose"
|
|
|
|
# Der ganze Teich als Markdown-ZIP
|
|
curl -H "$AUTH" -o team.zip \
|
|
https://wiki.example.com/api/public/v1/ponds/team/export/markdown
|
|
```
|
|
|
|
Such-Snippets markieren Treffer mit `**…**`; Ergebnisse tragen Teich-
|
|
und Seiten-Slugs für Folgeaufrufe.
|
|
|
|
## Schreiben (braucht den `write`-Scope)
|
|
|
|
```sh
|
|
# Eine Seite aus Markdown anlegen (optional "parent": ein Seiten-Slug ordnet sie unter)
|
|
curl -H "$AUTH" -H 'Content-Type: application/json' \
|
|
-d '{"title": "Meeting notes", "markdown": "# Agenda\n\n- Enten\n"}' \
|
|
https://wiki.example.com/api/public/v1/ponds/team/pages
|
|
|
|
# Umbenennen, den Inhalt ERSETZEN und/oder im Seitenbaum verschieben
|
|
# ("parent": <slug> ordnet die Seite unter, "parent": null holt sie auf die oberste Ebene)
|
|
curl -X PATCH -H "$AUTH" -H 'Content-Type: application/json' \
|
|
-d '{"markdown": "Neuer Inhalt."}' \
|
|
https://wiki.example.com/api/public/v1/ponds/team/pages/meeting-notes
|
|
|
|
# Eine Seite in den Papierkorb verschieben
|
|
curl -X DELETE -H "$AUTH" \
|
|
https://wiki.example.com/api/public/v1/ponds/team/pages/meeting-notes
|
|
```
|
|
|
|
Ein Inhalts-`PATCH` **ersetzt** die ganze Seite. Er wird durch das
|
|
lebendige kollaborative Dokument angewandt: Wer die Seite in diesem
|
|
Moment bearbeitet, sieht die Änderung erscheinen, nichts spaltet sich
|
|
ab, und der vorherige Stand bleibt als wiederherstellbarer
|
|
Schnappschuss im Versionsverlauf (das Update selbst erscheint als
|
|
Version namens „API update").
|
|
|
|
## Labels
|
|
|
|
```sh
|
|
GET /ponds/{pond}/labels # der Label-Baum
|
|
POST /ponds/{pond}/labels # {name, color?, parentId?}
|
|
PATCH /ponds/{pond}/labels/{labelId} # umbenennen/umfärben/verschieben in einem Aufruf
|
|
DELETE /ponds/{pond}/labels/{labelId}
|
|
PUT /ponds/{pond}/pages/{page}/labels/{labelId} # zuweisen
|
|
DELETE /ponds/{pond}/pages/{page}/labels/{labelId} # entfernen
|
|
```
|
|
|
|
Die Verwaltung des Label-Baums braucht Teich-Admin-Rechte (wie in der
|
|
App).
|
|
|
|
## Kommentare
|
|
|
|
```sh
|
|
GET /ponds/{pond}/pages/{page}/comments?filter=all|open|resolved
|
|
POST /ponds/{pond}/pages/{page}/comments # {body, parentId?} — Markdown
|
|
POST /ponds/{pond}/pages/{page}/comments/{id}/resolve
|
|
DELETE /ponds/{pond}/pages/{page}/comments/{id}/resolve # wieder öffnen
|
|
```
|
|
|
|
Die Kommentar-Richtlinie des Teichs gilt exakt wie in der App.
|
|
|
|
## Fehler, Limits, Semantik
|
|
|
|
- Fehler tragen den einheitlichen Body `{ "code": "...", "message":
|
|
"...", "details": {...} }`. Der `code` ist stabil und maschinell
|
|
prüfbar.
|
|
- **404 vs. 403**: Was du nicht _lesen_ darfst, antwortet 404 (die
|
|
Existenz bleibt verborgen — auch Teiche ohne API-Freigabe); ein
|
|
Schreibzugriff auf etwas, das du lesen, aber nicht ändern darfst,
|
|
antwortet 403. Ein Token ohne `write`-Scope bekommt auf jeder
|
|
Schreibroute `403 scope_required`.
|
|
- **Rate-Limit** pro Token; `429`-Antworten tragen einen
|
|
`Retry-After`-Header.
|
|
- Nirgendwo sind Cookies im Spiel — es gibt keine CSRF-Angriffsfläche,
|
|
und Browser-Sitzungen können die öffentliche API nicht aufrufen.
|
|
|
|
## (Noch) außerhalb des Umfangs
|
|
|
|
Anhang-Upload, Versions-Endpoints und Webhooks sind bewusst nicht Teil
|
|
von v1.
|
|
|
|
_Die Betreiber-Sicht auf dasselbe Feature (Schalter,
|
|
Sicherheitshinweise):
|
|
[`docs/self-hosting/public-api.md`](../../self-hosting/public-api.md)
|
|
(englisch)._
|