All checks were successful
CD / Build and push images (push) Successful in 1m9s
CD / Deploy to Test (push) Successful in 10s
CD / Smoke tests against Test (push) Successful in 1m10s
CD / Promote to Int (push) Successful in 11s
CI / Lint, typecheck, test (push) Successful in 4m7s
CI / Build container images (push) Has been skipped
CI / Auth e2e pack (push) Successful in 5m34s
CI / Import/export fidelity gate (push) Successful in 47s
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
132 lines
4.6 KiB
Markdown
132 lines
4.6 KiB
Markdown
# 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:
|
|
|
|
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)._
|