dorfteich/docs/manual/api-guide.md
Claude Fable 5 baebd79cc8
All checks were successful
CD / Build and push images (push) Successful in 1m10s
CD / Deploy to Test (push) Successful in 10s
CD / Smoke tests against Test (push) Successful in 1m14s
CD / Promote to Int (push) Successful in 11s
CI / Lint, typecheck, test (push) Successful in 4m6s
CI / Build container images (push) Has been skipped
CI / Auth e2e pack (push) Successful in 5m35s
CI / Import/export fidelity gate (push) Successful in 48s
German translations of the seven user-facing docs under docs/de/
Mirrors the English tree (docs/de/{features.md,manual/*,developer/
extending.md}) so relative links between translated guides resolve
within the German set; links into untranslated areas (self-hosting,
architecture, deploy) point at the English files and say so. Every
quoted UI label matches the actual German interface strings. Each
pair of files cross-links the other language; English stays
authoritative when the two diverge.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EwZ4jR4KFAPvpjWevfUGX1
2026-07-12 19:28:50 +02:00

134 lines
4.7 KiB
Markdown

# API guide
_Deutsche Fassung: [docs/de/manual/api-guide.md](../de/manual/api-guide.md)_
How to talk to Dorfteich from scripts and integrations. The public REST
API lives at `/api/public/v1`; its machine-readable description is
served at `/api/public/v1/openapi.json`.
## Switching it on
The API is **off by default**, twice:
1. A **site admin** enables the instance switch (Admin → Settings →
Public API).
2. Each **pond** that should be reachable opts in (pond settings →
"Expose this pond through the public API").
Anything not enabled answers `404` — indistinguishable from an instance
without the feature.
## Personal access tokens
Create tokens under **Settings → API tokens**: a name, a scope
(`read` or `read+write`), an optional expiry date, and optionally a
restriction to selected ponds. The secret (`dt_pat_…`) is shown **once**
— copy it immediately. Tokens are revocable and show their last use.
A token acts **as you**: it can read and write exactly what you can,
narrowed by its scope and pond restriction — never more. Token
management itself always requires the browser session; a leaked token
cannot mint new tokens.
Authenticate with a bearer header:
```sh
curl -H "Authorization: Bearer dt_pat_..." \
https://wiki.example.com/api/public/v1/me
```
`GET /me` is the smoke test — it returns your user, the token scope,
and any pond restriction.
## Reading
```sh
# The ponds this token can reach
curl -H "$AUTH" https://wiki.example.com/api/public/v1/ponds
# Pages of a pond: slug, title, labels, timestamps
curl -H "$AUTH" https://wiki.example.com/api/public/v1/ponds/team/pages
# One page — Markdown source AND rendered, sanitized HTML
curl -H "$AUTH" https://wiki.example.com/api/public/v1/ponds/team/pages/meeting-notes
# Full-text search (optionally ?pond=<slug>&label=<labelId>)
curl -H "$AUTH" "https://wiki.example.com/api/public/v1/search?q=seerose"
# The whole pond as a Markdown ZIP
curl -H "$AUTH" -o team.zip \
https://wiki.example.com/api/public/v1/ponds/team/export/markdown
```
Search snippets mark hits with `**…**`; results carry pond and page
slugs for follow-up calls.
## Writing (requires the `write` scope)
```sh
# Create a page from Markdown
curl -H "$AUTH" -H 'Content-Type: application/json' \
-d '{"title": "Meeting notes", "markdown": "# Agenda\n\n- Ducks\n"}' \
https://wiki.example.com/api/public/v1/ponds/team/pages
# Rename and/or REPLACE the content
curl -X PATCH -H "$AUTH" -H 'Content-Type: application/json' \
-d '{"markdown": "New content."}' \
https://wiki.example.com/api/public/v1/ponds/team/pages/meeting-notes
# Move a page to the trash
curl -X DELETE -H "$AUTH" \
https://wiki.example.com/api/public/v1/ponds/team/pages/meeting-notes
```
A content `PATCH` **replaces** the whole page. It is applied through the
live collaborative document: anyone editing the page at that moment sees
the change appear, nothing forks, and the previous state remains in the
version history as a restorable snapshot (the update itself shows up as
a version named "API update").
## Labels
```sh
GET /ponds/{pond}/labels # the label tree
POST /ponds/{pond}/labels # {name, color?, parentId?}
PATCH /ponds/{pond}/labels/{labelId} # rename/recolor/move in one call
DELETE /ponds/{pond}/labels/{labelId}
PUT /ponds/{pond}/pages/{page}/labels/{labelId} # assign
DELETE /ponds/{pond}/pages/{page}/labels/{labelId} # unassign
```
Label-tree management needs pond-admin rights (like in the app).
## Comments
```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 # reopen
```
The pond's comment policy applies exactly as in the app.
## Errors, limits, semantics
- Errors carry the uniform body `{ "code": "...", "message": "...",
"details": {...} }`. The `code` is stable and machine-checkable.
- **404 vs 403**: what you may not _read_ answers 404 (existence stays
hidden — including ponds without the API opt-in); a write on
something you may read but not change answers 403. A token without
the `write` scope gets `403 scope_required` on every write route.
- **Rate limit** per token; `429` responses carry a `Retry-After`
header.
- No cookies are involved anywhere — there is no CSRF surface, and
browser sessions cannot call the public API.
## Out of scope (for now)
Attachment upload, version endpoints, and webhooks are deliberately not
part of v1.
_Operator's view of the same feature (switches, security notes):
[`docs/self-hosting/public-api.md`](../self-hosting/public-api.md)._