Seven audience-targeted documents (English first, German translation to follow), linked from the README and a new docs/manual/ index: - docs/features.md — public-facing feature overview: what Dorfteich can do and why that matters - docs/manual/user-guide.md — everyday use: editor, wikilinks, labels, search, comments, watches/digests, import/export, settings - docs/manual/pond-admin-guide.md — pond configuration: members/roles, access rules incl. label scoping and public pages, labels, comment policy, plugins, API/MCP opt-ins, files, export - docs/manual/site-admin-guide.md — instance administration: wizard, settings, quotas, uploads, API/MCP switches, legal pages, plugins, users, and the system panel (jobs/backups/audit/storage) - docs/manual/api-guide.md — example-driven public-API walkthrough (tokens, reading, writing through the collab-safe path, labels, comments, error semantics) - docs/manual/mcp-guide.md — connecting AI assistants: switches, token scopes, Claude Code one-liner, mcp-remote bridge, tool table, audit and safety properties - docs/developer/extending.md — plugin development (sandbox contract, SDK, block plugins, bundled apps/fullscreen, shipping) and core contributions (stack, dev environment, gates, house rules) README: documentation index, repository-layout rows for docs/manual and docs/developer, and the stale "architecture phase" status brought up to reality. All relative links verified. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EwZ4jR4KFAPvpjWevfUGX1
4.6 KiB
API guide
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:
- A site admin enables the instance switch (Admin → Settings → Public API).
- 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:
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
# 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)
# 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
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
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": {...} }. Thecodeis 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
writescope gets403 scope_requiredon every write route. - Rate limit per token;
429responses carry aRetry-Afterheader. - 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.