HTTP API
The route reference for nodum serve — the JSON API under /api plus the
/healthz liveness probe, exactly as nodum.http_api builds them.
This page is generated from the live route table — the api_routes list
inside nodum.http_api.create_app — and is committed so the docs site ships
it without a build step. Never edit it by hand; when the route table changes
(a route added, renamed, re-verbed, or removed), regenerate and commit:
uv run python scripts/gen-http-api-docs.py
tests/test_docs.py runs that exact command and fails if the committed page
is not what the generator produces, so the route table and this page cannot
drift apart silently.
Auth model
The session gate is one rule: every /api route requires a valid session —
reads included — with exactly these exemptions:
POST /api/login — open: the route that makes the session (name +
password, argon2id; sets the HttpOnly; SameSite=Strict session cookie,
and a failed-login lockout throttles brute force).
GET /api/download/{token} and PUT /api/uploads/{token} — token:
the single-use, minutes-long capability URL is the authorisation, minted
by nodum.urls against a principal that already passed the session gate.
No other route carries its own credential.
/healthz and the static UI at / are open, but neither is part of the
/api surface. Everything else is session-gated: the session middleware
verifies the cookie into the request scope, and every handler binds its
principal from there — no request field, header, or query parameter can set
an identity. The Host check, the same-origin proof for state-changing
requests, and the content-type rule apply to every route independently of
this gate.
The method column lists the methods the route table configured; Starlette
answers HEAD for any route configured GET.
The tables below list 69 routes, grouped by family.
Session
| Method |
Path |
Handler |
Auth |
Notes |
| POST |
/api/login |
login |
open — makes the session |
Password login — the one /api route outside the session gate. |
| POST |
/api/logout |
logout |
session |
Log out: drop the server-side session row and clear the cookie. |
Catalog & schema
| Method |
Path |
Handler |
Auth |
Notes |
| GET |
/api/types |
get_types |
session |
The live type catalog (node types and edge types). |
| GET |
/api/schema/{type} |
get_schema |
session |
One node or edge type's catalog entry, including its JSON schema. |
Nodes
| Method |
Path |
Handler |
Auth |
Notes |
| GET |
/api/nodes |
list_nodes |
session |
List nodes in creation order, optionally filtered. |
| POST |
/api/nodes |
create_node |
session |
Create a node. It lands active: this is the human surface. |
| GET |
/api/nodes/resolve |
resolve_nodes |
session |
Resolve [[wikilink]] titles to node ids — exact, casefolded, batch. |
| GET |
/api/nodes/{id} |
get_node |
session |
One node, or its active-edge neighborhood when depth is given. |
| PATCH |
/api/nodes/{id} |
update_node |
session |
Update the named fields of a node, and only those. |
| GET |
/api/nodes/{id}/children |
list_children |
session |
A node's children in position order (the document tree). |
| GET |
/api/nodes/{id}/history |
node_history |
session |
A node's version snapshots, chronological. |
| POST |
/api/nodes/{id}/archive |
archive_node |
session |
Retire a node (active → archived) — the service's human tier. |
Edges
| Method |
Path |
Handler |
Auth |
Notes |
| GET |
/api/edges |
list_edges |
session |
List edges, optionally filtered by incident node, type, state, or validity window. |
| POST |
/api/edges |
create_edge |
session |
Create a typed, directed edge between two nodes. |
| POST |
/api/edges/{id}/archive |
archive_edge |
session |
Retire an edge (active → archived) — the service's human tier. |
Search & ask
| Method |
Path |
Handler |
Auth |
Notes |
| GET |
/api/search |
search |
session |
Hybrid search (BM25 + vector, RRF-fused) with optional graph expansion. |
| POST |
/api/ask |
ask |
session |
Answer a question from the graph, with citations, or say it could not. |
| POST |
/api/summarize |
summarize |
session |
Summarise a node and its neighbourhood. Reads only (design E1). |
| GET |
/api/links/suggest |
suggest_links |
session |
Title-prefix candidates for the editor's [[ autocomplete. |
Graph
| Method |
Path |
Handler |
Auth |
Notes |
| GET |
/api/graph/subgraph |
get_subgraph |
session |
A bounded, filtered neighborhood — node and edge caps both applied while walking. |
| GET |
/api/graph/path |
get_path |
session |
The shortest active-edge path between two nodes. |
Review
| Method |
Path |
Handler |
Auth |
Notes |
| GET |
/api/review/queue |
review_queue |
session |
Pending proposals with reviewer context, oldest first. |
| POST |
/api/review/accept |
review_accept |
session |
Accept proposals by id, or every proposal matching a filter. |
| POST |
/api/review/reject |
review_reject |
session |
Reject proposals by id, or by filter. The reason is mandatory. |
Diff & events
| Method |
Path |
Handler |
Auth |
Notes |
| GET |
/api/diff |
diff_versions |
session |
Unified diff between two versions of one node. |
| GET |
/api/events |
list_events |
session |
The append-only event log, newest first. |
Assets
| Method |
Path |
Handler |
Auth |
Notes |
| GET |
/api/assets |
list_assets |
session |
Registered assets, metadata only — the bytes stay in the database. |
| POST |
/api/assets |
upload_asset |
session |
Register an uploaded file as a content-addressed asset. |
| GET |
/api/assets/{id} |
get_asset |
session |
One asset's metadata, by hash or by asset-reference node id. |
| GET |
/api/assets/{id}/rendition/{profile} |
get_rendition |
session |
The WebP bytes of an image rendition — generated lazily, cached in the DB. |
| POST |
/api/assets/{id}/download-url |
mint_asset_download_url |
session |
Mint a single-use, short-lived URL for one asset's original bytes. |
Ingestion
| Method |
Path |
Handler |
Auth |
Notes |
| POST |
/api/ingest |
ingest_source |
session |
Ingest one local file or one URL: register, extract, describe, propose. |
| POST |
/api/uploads |
request_upload_url |
session |
Mint a single-use URL to PUT one file to — or answer with a dedup hit. |
Capability URLs
| Method |
Path |
Handler |
Auth |
Notes |
| GET |
/api/download/{token} |
download_original |
token — the URL is the credential |
Spend a download token and stream that asset's original bytes. |
| PUT |
/api/uploads/{token} |
upload_original |
token — the URL is the credential |
Spend an upload token and store the raw request body as an asset. |
History & undo
| Method |
Path |
Handler |
Auth |
Notes |
| POST |
/api/undo |
undo |
session |
Reverse one event (default: the latest reversible one) — human tier. |
| GET |
/api/export/node/{id} |
export_node |
session |
Download a node — and optionally its neighborhood — as a JSON file. |
Consolidation cycles
| Method |
Path |
Handler |
Auth |
Notes |
| GET |
/api/cycles |
list_cycles |
session |
The consolidation journal, newest first. |
| POST |
/api/cycles |
run_cycle |
session |
Run a consolidation cycle now and answer with its journal entry. |
| GET |
/api/cycles/{id} |
get_cycle |
session |
One journal entry: the row, its metrics, and the events it wrote. |
| POST |
/api/cycles/{id}/abandon |
abandon_cycle |
session |
Close an interrupted cycle as failed — the door out of a stuck run. |
| POST |
/api/cycles/{id}/stop |
stop_cycle |
session |
Ask a running cycle to stop, and record who asked (design K1–K3). |
| POST |
/api/cycles/{id}/rollback |
roll_cycle_back |
session |
Take a whole cycle back — all of it, or none of it (design D7). |
Accounts & sessions
| Method |
Path |
Handler |
Auth |
Notes |
| GET |
/api/me |
get_me |
session |
The session's own human account (id, name, credential state). |
| GET |
/api/humans |
list_humans |
session |
Every human account. |
| POST |
/api/humans |
create_human |
session |
Create a human account (passwordless until its password is set). |
| POST |
/api/humans/{id}/password |
set_human_password |
session |
Set or change a human's password; the hash never leaves the service. |
| POST |
/api/humans/{id}/disable |
disable_human |
session |
Disable a human — its sessions die, and its agents' tokens with them. |
| POST |
/api/humans/{id}/enable |
enable_human |
session |
Re-enable a disabled human. |
| GET |
/api/agents |
list_agents |
session |
Every agent account. |
| POST |
/api/agents |
create_agent |
session |
Create an external agent owned by the session's human. |
| POST |
/api/agents/{id}/token-rotate |
rotate_agent_token |
session |
Replace an agent's token; the new one is in this body and nowhere else. |
| POST |
/api/agents/{id}/disable |
disable_agent |
session |
Disable an agent — its token dies immediately on HTTP; a running MCP |
| POST |
/api/agents/{id}/enable |
enable_agent |
session |
Re-enable a disabled agent. |
Grants & spaces
| Method |
Path |
Handler |
Auth |
Notes |
| GET |
/api/grants |
list_grants |
session |
Grant rows, optionally one agent's (?agent=). |
| POST |
/api/grants |
set_grant |
session |
Grant (or re-level) an agent's access to a space. |
| POST |
/api/grants/revoke |
revoke_grant |
session |
Revoke an agent's grant on a space. |
| GET |
/api/spaces |
list_spaces |
session |
Every active space, with its live node count and grant holders. |
| POST |
/api/spaces |
create_space |
session |
Create a space (a node of builtin type space, living in meta). |
| POST |
/api/spaces/{id}/rename |
rename_space |
session |
Rename a space — a space is a node, so this is a node-title update. |
| POST |
/api/spaces/{id}/archive |
archive_space |
session |
Archive a space; its nodes keep their space_id and grants go inert. |
Settings
| Method |
Path |
Handler |
Auth |
Notes |
| GET |
/api/settings |
get_settings |
session |
Every setting: what is in force, where it came from, whether it can be stored. |
| PUT |
/api/settings |
put_settings |
session |
Apply several setting changes atomically: all of them, or none of them. |
| POST |
/api/settings/export |
export_settings |
session |
Stream the effective configuration as a .env download — the named envelope exemption. |
| POST |
/api/settings/adopt-env |
adopt_environment |
session |
Adopt every editable setting the environment pins into settings.env. |
| DELETE |
/api/settings/{name} |
delete_setting |
session |
Remove one setting from settings.env, falling back down the ladder. |
Projectors
| Method |
Path |
Handler |
Auth |
Notes |
| POST |
/api/projectors/{name}/rebuild |
rebuild_projector_route |
session |
Drop one projector's derived state and replay the event log (human-only). |
Agent surface (MCP)
| Method |
Path |
Handler |
Auth |
Notes |
| POST, GET, DELETE |
/mcp |
StreamableHTTPASGIApp |
bearer — an agent token, per request |
The MCP surface for external agents: read and additive tiers only, streamable HTTP. |
Health
| Method |
Path |
Handler |
Auth |
Notes |
| GET |
/healthz |
healthz |
open |
Liveness probe — open even with the session gate on. |