Skip to content

HTTP API

Mikhail Deynekin edited this page Nov 13, 2026 · 1 revision

HTTP API

Three surfaces: the public JSON API (no key), the admin JSON API (session + CSRF), and the machine update API (API key). All JSON responses use {ok: …} and never leak PHP notices.

Public JSON

Endpoint Returns
GET ?api=search&q=…&limit=50 {ok, query, took_ms, total, filters, results[]}
GET ?api=suggest&q=… {ok, results[]} — titles and headings
GET ?api=toc&file=… headings of a document (file optional → home document)
GET ?api=config public configuration for the UI
POST ?api=render legacy session + CSRF clipboard render
POST ?api=save save with hash check
POST ?api=upload multipart image upload (reader-side, DISABLE_UPLOAD applies)

Machine render API

POST ?api=render with X-Api-Key: $API_KEY (or ?api_key=) is stateless and needs no session, which is what makes it useful for CI and embeddings:

curl -fsS -H "X-Api-Key: $API_KEY" -H 'Content-Type: application/json' \
  -d '{"content":"# t\n\n- a\n","format":"auto"}' \
  'https://docs.example.com/index.php?api=render'
Field Values
format auto (default), markdown, html, text
output {ok: true, data: {format, html, bytes, elapsed_ms, renderer}}

html is a fragment: Markdown → standalone renderer in embed mode; html input → the sanitiser; text → wrapped in <div class="md-text">. Statuses: 401 bad_key, 422 empty_content, 422 bad_format, 413 too_large (above 256 KiB).

Admin JSON

Session cookie plus X-CSRF-Token. Actions include file.read|write|create|rename|move|delete| createFromTemplate, folder.create|delete, upload.md|upload.image, preview, trash.list|restore, index.rebuild|stats, backup.create|list|restore|delete|download, revision.list|read|restore, backlinks.rebuild, tags.rebuild, export.static, update.check|status|apply, settings.set, settings.regenerate-key, logs.tail, health.run, links.check.

Status codes: 401 unauthorized, 403 CSRF or flag, 404, 409 conflict, 413 too large, 400 bad request.

Machine update API

updater.php at the project root — reached through the shipped public/updater.php bridge on a docroot-public install, so the same URL works in both layouts.

GET  updater.php?api_key=<key>&action=status&format=json
GET  updater.php?api_key=<key>&action=conflicts&format=json
POST updater.php?api_key=<key>&action=install&format=json[&dry_run=1]
Action Meaning
status local state per tracked file (present / modified / missing), no network
conflicts files that differ from the shipped manifest, no network
install POST only. dry_run=1 downloads the release archive, verifies every entry inside it and reports what would be replaced — writing nothing

The key is the credential: ALLOW_UPDATE is not required for the API. A bad or missing key is 403; install without POST is 405. The envelope matches the v2 contract {ok, action, version, steps, files, conflicts, errors}.

Feeds

sitemap.xml and rss.xml when SITEMAP_ENABLED / RSS_ENABLED are on. Downloads: ?file=…&download=1.

Clone this wiki locally