NovaFabric REST API Reference
Status: works today (v0.98.0). Generated from the live nova serve FastAPI route table (src/novafabric/serve/app.py).
The nova serve dashboard server exposes 207 REST endpoints. All require a valid auth token except the unauthenticated probes GET /api/health, GET /livez, and GET /readyz. The multi-tenant nova server API is specified separately in api/openapi.yaml.
Generated by design/scripts/gen_api_reference.py — re-run it after route changes rather than editing endpoints by hand.
TV-5 3D topology routes (experimental). When the server is started with nova serve --tv5,
an additional router is mounted at /api/tv5/ (src/novafabric/serve/topology/router_tv5.py):
GET /api/tv5/live (Arrow delta stream), GET /api/tv5/windows,
GET /api/tv5/snapshot/{window_id}, and a WS /api/tv5/ws websocket. These are conditional
and eval-gated, so they are not in the generated table above.
Since v0.97.0 they are authenticated — the HTTP routes are token-gated like every other
/api/* route, and the WebSocket enforces the localhost Host guard (close code 4403)
and the token (close code 4401) before accepting the connection — on the WebSocket
the token must arrive as a ?token= query parameter, since browsers cannot set headers on
a WS connect. Previously this router was mounted with no auth at all; a custom TV-5 client
that connected without a token must now supply one.
| Method |
Path |
Summary |
GET |
/ |
serve no dashboard |
GET |
/api/adapters |
List registered Nova framework adapters with availability flags. |
GET |
/api/docs |
swagger ui html |
GET |
/api/doctor |
Run diagnostic checks on the NovaFabric installation (nova doctor). |
GET |
/api/health |
health |
GET |
/api/openapi.json |
openapi |
GET |
/api/stats |
Aggregate counts for the HomeTab. |
POST |
/api/validate-spec |
Validate an asset YAML spec without registering — mirrors nova validate <spec>. |
GET |
/docs/oauth2-redirect |
swagger ui redirect |
Runs & capsules (33)
| Method |
Path |
Summary |
POST |
/api/capsule-migrate |
Migrate a v0.1.x capsule directory to v1.0.0 format (ADR-0034 §6). |
POST |
/api/otlp/v1/traces |
Ingest OTLP OTel GenAI spans into a run capsule (NF-034, experimental). |
GET |
/api/runs |
list runs |
GET |
/api/runs/cost-summary |
Return per-run token and cost totals from ClickHouse. |
GET |
/api/runs/search |
Cursor-based run listing. True keyset paging: the cursor seeks the index directly — O(page), no cursor-to-offset conversion (ADR-0199 B2). |
GET |
/api/runs/stream |
Server-Sent Events stream of new run summaries. |
GET |
/api/runs/suggest-register |
Return asset registration suggestions derived from recent capsules. |
DELETE |
/api/runs/{run_id} |
Delete a capsule directory, subject to legal holds and retention policy. |
GET |
/api/runs/{run_id} |
get run |
GET |
/api/runs/{run_id}/children |
Return parent capsule metadata + list of child capsule summaries. |
GET |
/api/runs/{run_id}/diagnose |
Attribute a failed run to its most likely responsible step. |
GET |
/api/runs/{run_id}/energy |
Energy-Anchored Action Receipts + conservation for a run (ADR-0093). |
POST |
/api/runs/{run_id}/export-system-card |
Generate and SEAL an auto-generated system/audit card. |
GET |
/api/runs/{run_id}/file/{filepath:path} |
get run file |
GET |
/api/runs/{run_id}/forensics-timeline |
Reconstruct a deterministic forensics timeline from a run's sealed capsule (ADR-0155 D1; see note below). |
GET |
/api/runs/{run_id}/ledger |
Adversary-anchored ledger verification status (ADR-0094). |
POST |
/api/runs/{run_id}/redact |
redact endpoint |
GET |
/api/runs/{run_id}/redaction-proof |
get redaction proof endpoint |
GET |
/api/runs/{run_id}/redaction-xray |
Field-protection overlay for one capsule (ADR-0174). |
POST |
/api/runs/{run_id}/replay/dry-run |
dry run replay endpoint |
POST |
/api/runs/{run_id}/replay/exact |
exact replay endpoint |
POST |
/api/runs/{run_id}/replay/forensic |
forensic replay endpoint |
POST |
/api/runs/{run_id}/replay/semantic |
semantic replay endpoint |
GET |
/api/runs/{run_id}/run-lineage |
List spool lineage edges for a distributed run — nova run lineage. |
GET |
/api/runs/{run_id}/safety-case |
Compile an evidence-grounded safety case for a run (ADR-0095). |
GET |
/api/runs/{run_id}/scan-secrets |
Report secret/PII findings from the redaction log — nova scan-secrets. |
POST |
/api/runs/{run_id}/scores |
Append one externally-computed score to the run's scores.jsonl. |
GET |
/api/runs/{run_id}/tool-permission-events |
Return ToolPermissionEvent records for a capsule. |
GET |
/api/runs/{run_id}/tree |
Show the parent/child capsule tree — nova run show --with-children. |
GET |
/api/runs/{run_id}/trust-radar |
Trust guarantees for one capsule (ADR-0173). |
POST |
/api/runs/{run_id}/validate |
Validate a capsule's schema and required files. |
POST |
/api/runs/{run_id}/validate-distributed |
Validate a distributed parent capsule + its workers (nova run validate-distributed). |
POST |
/api/runs/{run_id}/verify |
Verify DSSE signature + RFC 3161 timestamp + Merkle log inclusion (nova verify). |
Content search on GET /api/runs/search — scope parameter (experimental, ADR-0204)
GET /api/runs/search accepts an additive scope=meta|content|all query
parameter (default meta):
scope=meta (or omitted) — the existing behavior, unchanged: q matches
run_id and command metadata only.
scope=content — experimental: full-text search (SQLite FTS5) over the
redacted capsule text indexed at ingest (ADR-0204). Requires a non-empty
q (else 400). Each item carries a matches array of
{stream, ref, line_no, snippet} plus matches_truncated (max 8 matches
per run); the response adds snippet_markers (["«", "»"]). Results are
relevance-ranked (bm25); next_cursor is always null for content scopes
in v0. User query input is quoted before it reaches the MATCH grammar —
FTS5 operators (OR, NEAR, -, :) match literally.
scope=all — experimental: content hits first (with matches), then
metadata hits in the existing newest-first order, deduplicated by run_id.
If the host SQLite lacks FTS5, content scopes return a 501 error envelope
({"error": {"code": "fts5_unavailable", …}}); scope=meta is unaffected.
Postgres (nova server) parity is planned — no target version.
GET /api/runs/{run_id}/forensics-timeline (ADR-0155 D1)
Reconstructs a deterministic forensics timeline from a run's own sealed
capsule via the pure forensics/timeline.py::merge_timeline core — the same
merge nova forensics timeline uses. Honest scope: it only reconstructs
what the capsule already carries (run start/finish, model-call and
tool-call events with a usable timestamp); a documented follow-on "incident →
session → lineage collector" does not exist yet, so lineage coverage is
always reported as a gap, never fabricated. Each source is capped
(MAX_EVENTS_PER_SOURCE); anything beyond the cap is a gap, not a silent drop.
Assets & registry (19)
| Method |
Path |
Summary |
GET |
/api/assets |
list assets endpoint |
POST |
/api/assets |
register asset endpoint |
POST |
/api/assets/register-from-yaml |
Register an asset from a YAML spec string (used by suggest-register panel). |
GET |
/api/assets/{asset_id} |
Asset detail with its recent eval history (bounded: eval_limit default 50, max 500; adds eval_results_total/eval_results_truncated). |
GET |
/api/assets/{asset_id}/approvals |
Return approval records for an asset (by UUID). |
POST |
/api/assets/{asset_id}/approve |
approve asset endpoint |
POST |
/api/assets/{asset_id}/eval |
Eval by UUID — resolves name+version from the registry then delegates. |
GET |
/api/assets/{asset_id}/eval-history |
eval history endpoint |
POST |
/api/assets/{asset_id}/promote |
Promote by UUID — resolves name+version from the registry then delegates. |
GET |
/api/assets/{name}/diff |
asset spec diff endpoint |
POST |
/api/assets/{name}/rollback |
rollback asset endpoint |
DELETE |
/api/assets/{name}/{version} |
Hard-delete an asset from the registry (nova unregister). |
GET |
/api/assets/{name}/{version} |
get asset endpoint |
POST |
/api/assets/{name}/{version}/eval |
eval asset endpoint |
POST |
/api/assets/{name}/{version}/promote |
promote asset endpoint |
GET |
/api/diff |
diff runs |
POST |
/api/eval/compare |
Compare two EvalResult JSON objects for regression — mirrors nova eval compare. |
POST |
/api/eval/run |
Run a standard eval suite against a capsule — nova eval run. |
GET |
/api/eval/suites |
List registered eval suite adapters — nova eval list. |
Lineage (8)
| Method |
Path |
Summary |
GET |
/api/lineage/blast-radius/{ref:path} |
lineage blast radius |
GET |
/api/lineage/edges |
Return lineage edges (newest-first). Powers the dashboard's full-DAG view. Keyset cursor/next_cursor over (created_at, edge_id), plus true total and truncated (ADR-0199 B2). |
POST |
/api/lineage/export-prov |
Export W3C PROV-JSON lineage document for a capsule. |
POST |
/api/lineage/import |
Import capsule lineage events into the store — mirrors nova lineage import. |
GET |
/api/lineage/provenance/{ref:path} |
lineage provenance |
GET |
/api/lineage/replay-chain/{run_id} |
lineage replay chain |
GET |
/api/lineage/time-travel/{ref:path} |
lineage time travel |
GET |
/api/lineage/{run_id}/emit-openlineage |
Return OpenLineage events for a capsule as JSON (nova lineage emit-openlineage). |
Evidence & audit (8)
| Method |
Path |
Summary |
GET |
/api/audit |
list audit |
GET |
/api/evidence |
list evidence endpoint |
GET |
/api/evidence/completeness/{run_id} |
Compute the completeness assertion for a capsule. |
GET |
/api/evidence/{bundle_id} |
get evidence detail endpoint |
GET |
/api/evidence/{bundle_id}/download |
download evidence endpoint |
POST |
/api/evidence/{bundle_id}/verify |
Verify the cryptographic integrity of an evidence bundle. |
POST |
/api/evidence/{run_id} |
export evidence endpoint |
POST |
/api/evidence/{run_id}/bind |
Build criterion-evidence bindings for a capsule against a profile. |
Compliance & governance (27)
| Method |
Path |
Summary |
POST |
/api/aibom/generate |
Generate CycloneDX AI-BOM(s) for one or all capsules — nova aibom generate. |
GET |
/api/aibom/status |
Show CRA SBOM compliance status — nova aibom status. |
GET |
/api/compliance/annex-iv |
Build and return an EU AI Act Annex IV document as JSON-LD. |
POST |
/api/compliance/audit/bundle |
Export a compliance evidence bundle as base64-encoded ZIP (nova audit bundle). |
GET |
/api/compliance/audit/coverage |
Per-control coverage analysis for the local capsule store (nova audit coverage). |
GET |
/api/compliance/audit/map |
List evidence checkers for a compliance profile. |
POST |
/api/compliance/audit/report |
Run compliance audit against a capsule and return a coverage report. |
POST |
/api/compliance/audit/verify |
Validate the structure of an audit report JSON-LD (nova audit verify). |
POST |
/api/compliance/erasure/request |
Experimental — works today (ADR-0210). Execute a GDPR Art.17 erasure request through the real DEK crypto-shred machinery (DEKStore.erase_subject, same code path as nova pii erase). Safe-mutations gated: body must carry confirmed: true (400 otherwise, nothing mutated). Persists the request PENDING in $NOVAFABRIC_HOME/erasure.db, executes synchronously, returns the terminal state (COMPLETED/DEFERRED/FAILED) with a receipt + receipt_sha256. NOVA_CAP003_ENABLED=false → 409. |
GET |
/api/compliance/erasure/status |
Experimental — works today (ADR-0210). List persisted GDPR erasure requests from erasure.db, newest first (?subject_id= exact filter, ?limit=, default 200). Rows are hash-only at top level (subject_sha256); receipts appear verbatim. Empty queue returns requests: [] honestly. |
POST |
/api/compliance/euaiact/export |
Export EU AI Act Art.12 structured log records (ADR-0076). |
GET |
/api/compliance/euaiact/status |
Return EU AI Act Art.12 compliance configuration (ADR-0076). |
POST |
/api/compliance/examiner/{format} |
Export a capsule in examiner format (bagit / pccp / iso42001). |
POST |
/api/compliance/export/aibom |
Export CycloneDX 1.7 AI-SBOM (ML-BOM) — nova export-aibom. |
POST |
/api/compliance/export/c2pa |
Export C2PA v2.3 manifest for a capsule (ADR-0074 / EU AI Act Art.50). |
POST |
/api/compliance/export/hipaa-proof |
Export HIPAA Safe Harbor de-identification proof — nova export-hipaa-proof. |
GET |
/api/compliance/export/kinds |
The registry catalog the dynamic panel renders (ADR-0200 §2). |
POST |
/api/compliance/export/nist-rmf |
Export NIST AI RMF 1.0 quantitative risk report — nova export-nist-rmf. |
POST |
/api/compliance/export/rocrate |
Export a capsule as W3C RO-Crate v1.1 ZIP (base64-encoded). |
POST |
/api/compliance/export/ropa |
Export GDPR Art.30 Records of Processing Activities (RoPA) — nova export-ropa. |
POST |
/api/compliance/export/{kind} |
Run one registry exporter — the same builder its CLI command calls. |
GET |
/api/compliance/nis2 |
Build and return a NIS2 incident report as JSON. |
POST |
/api/compliance/pii/erase |
Destroy a data subject's DEK (GDPR Art.17 crypto-shredding) — nova pii erase. |
GET |
/api/compliance/subject-proof |
Return GDPR Art. 17 redaction proof for a data subject. |
GET |
/api/governance/classify |
Classify an AI system risk tier inferred from a Run Capsule. |
POST |
/api/governance/classify-manual |
Classify a manually described AI system — nova classify run. |
GET |
/api/governance/vocabularies |
List vocabulary versions — nova classify list-vocabularies. |
Generic compliance-export registry (works today, ADR-0200 §2)
GET /api/compliance/export/kinds returns the export-kind catalog (id, label,
required/optional fields) that the dashboard's dynamic export panel renders;
POST /api/compliance/export/{kind} runs the matching CLI-only exporter's own
builder function given a JSON body instead of CLI flags, and every call is
audit-logged with its cli_equivalent. This complements — and does not
replace — the bespoke literal routes above (/api/compliance/export/aibom,
c2pa, hipaa-proof, nist-rmf, rocrate, ropa), which stay in place;
the generic {kind} route is registered last so it never shadows them
(Starlette matches in registration order).
Policy & approval (8)
| Method |
Path |
Summary |
GET |
/api/policy/capture-level |
Return current capture level + tier descriptions (DB-CAP-1, cap-004). |
POST |
/api/policy/capture-level |
Validate a capture-level value and return restart instructions (DB-CAP-1). |
POST |
/api/policy/check |
Evaluate a policy check interactively. |
GET |
/api/policy/explain |
Look up a past policy decision from the audit log (nova policy explain). Bounded O(page) tail read, newest-first; limit (default 100, max 1000) + byte-offset cursor; adds next_cursor/truncated (ADR-0199 B2). |
GET |
/api/policy/list |
List Rego bundle files and signed promotion policies — nova policy list. |
GET |
/api/policy/recent-decisions |
Return recent decision IDs from the audit log for autocomplete. Bounded O(page) tail read; byte-offset cursor; adds next_cursor/truncated (ADR-0199 B2). |
POST |
/api/policy/sign |
Sign and store a new promotion policy — nova policy sign. |
POST |
/api/policy/test |
Run the Rego test suite for the policy bundle (nova policy test). |
Sealing & trust (10)
| Method |
Path |
Summary |
GET |
/api/seal/log/verify |
Verify internal consistency of the local Merkle log (ADR-0041). |
GET |
/api/seal/policy |
Return the latest promotion policy predicate. |
POST |
/api/seal/ratchet/init |
Provision epoch-0 ratchet state for a node. |
POST |
/api/seal/ratchet/rotate |
Advance to the next signing epoch; erase the previous chain key. |
GET |
/api/seal/ratchet/status |
Show a node's current signing epoch and registry history. |
POST |
/api/seal/sigstore/sign |
Sign a capsule artifact using Sigstore keyless signing (ADR-0071). |
POST |
/api/seal/sigstore/verify |
Verify a stored Sigstore bundle for a capsule (ADR-0071). |
POST |
/api/seal/{capsule_id}/bypass |
Create a time-limited SoD bypass, DSSE-signed and permanently logged (ADR-0059). |
GET |
/api/seal/{capsule_id}/proposals |
List all proposals for a capsule with their approval status. |
POST |
/api/seal/{capsule_id}/verify |
Run the five-check SoD verifier for a capsule's promote bundles. |
Knowledge graph (18)
| Method |
Path |
Summary |
GET |
/api/kg/agents/{agent_id}/edges |
Return models, tools, and MCP servers called by an agent (DB-KG-1). |
GET |
/api/kg/aliases |
List all alias-table entries, optionally filtered by canonical entity id. |
POST |
/api/kg/aliases |
Register (upsert) an alias into the Tier-2 alias table. |
POST |
/api/kg/attack-path |
Shortest attack path between two entities — mirrors nova kg attack-path (UC2). |
POST |
/api/kg/blast-radius |
Impact/blast-radius of an entity — mirrors nova kg blast-radius (UC3). |
POST |
/api/kg/detect |
Unsupervised SPKG anomaly scan of a capsule — mirrors nova kg detect (ADR-0111). |
GET |
/api/kg/entity-queue |
Return pending ReviewItems from the Tier-3 human review queue (bounded: limit default 200, max 1000; adds true total + truncated). |
GET |
/api/kg/entity-queue/stats |
Return pending/approved/rejected counts for the entity review queue. |
POST |
/api/kg/entity-queue/{item_id}/approve |
Approve a review item. Body: {canonical: str, resolved_by: str}. |
POST |
/api/kg/entity-queue/{item_id}/reject |
Reject a review item. Body: {resolved_by: str}. |
POST |
/api/kg/ingest |
Ingest a capsule directory into the KG — mirrors nova kg ingest. |
POST |
/api/kg/ingest-all |
Bulk-ingest all capsule directories into the KG. |
POST |
/api/kg/init |
Initialise the KG schema (idempotent) — mirrors nova kg init. |
GET |
/api/kg/status |
Return Capsule KG store health + entity counts (DB-KG-1, ADR-0067). |
GET |
/api/kg/topology |
Return all KG nodes and edges for multi-layer topology visualization. |
GET |
/v1/kg/audit |
KG health audit: node/edge counts, zero-call-count edges. |
GET |
/v1/kg/query |
Query models and tools for an agent. Mirrors nova kg query. |
GET |
/v1/kg/status |
KG store health check (Tier 2+ aware). Alias of /api/kg/status. |
Assurance & MCP (3)
| Method |
Path |
Summary |
GET |
/api/assure/{run_id} |
Run OWASP Top 10 for LLM evidence checks against a capsule. |
POST |
/api/mcp/risk-report |
Generate a structured OWASP LLM risk report for an MCP manifest. |
POST |
/api/mcp/scan |
Scan an MCP server manifest for OWASP LLM supply-chain risks. |
Storage & infrastructure (7)
| Method |
Path |
Summary |
POST |
/api/db/upgrade |
Run alembic upgrade to the specified revision (default: head). |
GET |
/api/infra/backups |
List backup archives in NOVA_BACKUP_DIR (manifest-claimed, not hash-verified — that's nova backup verify); {detected: false} when unconfigured (ADR-0201 P7). |
GET |
/api/infra/collector |
Return collector health. Returns {detected: false} if not running. |
GET |
/api/storage/inspect/{run_id} |
Show dual-object split for a run (DB-STG-1, cap-003). |
GET |
/api/storage/manifest-chain |
Return the last N entries in the manifest chain. |
GET |
/api/storage/stats |
Return object capsule store statistics. |
GET |
/api/storage/validate |
Validate S3 backend supports Object Lock COMPLIANCE (DB-STG-1, cap-009). |
Cost & metrics (7)
| Method |
Path |
Summary |
POST |
/api/cost/attribute |
Compute productive-vs-wasted spend attribution over a request document — same core as nova cost attribute (ADR-0146 D3). |
POST |
/api/cost/fairness |
Compute per-agent spend share + Gini fairness report — same core as nova cost fairness (ADR-0146 D5). |
GET |
/api/cost/pricing |
Return the per-1k-token price table from CostInterceptor (DB-COST-1). |
GET |
/api/cost/report |
Return aggregated LLM cost (DB-COST-1 / cap-002). |
POST |
/api/cost/usage-breakdown |
Compute token usage-type composition — same core as nova cost usage-breakdown (ADR-0132). |
GET |
/metrics |
metrics endpoint |
GET |
/metrics/stream |
SSE metrics stream (FR-21: Last-Event-ID reconnect support). |
The three /api/cost/* POST routes above are pure, deterministic, read-only
wraps of the same cost cores their nova cost CLI counterparts call (no
capsule I/O, no writes, not audit-logged — computing a bounded aggregate over
caller-supplied numbers isn't a mutating or boundary-crossing action).
Reports (17)
| Method |
Path |
Summary |
GET |
/api/report |
Generate an asset inventory report — mirrors nova report. |
GET |
/api/reports/alert-digest |
Registry-driven data route (R4) — {columns, rows, count} JSON or CSV. |
GET |
/api/reports/api-key-inventory |
Registry-driven data route (R4) — {columns, rows, count} JSON or CSV. |
GET |
/api/reports/capsule-compare |
report capsule compare |
GET |
/api/reports/catalog |
Return the report registry (identity, filters, chart specs) — the single source of truth the dashboard ReportsTab reads for preview charts (ADR-0200/0201). |
GET |
/api/reports/compliance-posture |
Registry-driven data route (R4) — {columns, rows, count} JSON or CSV. |
GET |
/api/reports/cost-burn |
report cost burn |
GET |
/api/reports/dashboard-audit |
Registry-driven data route (R4) — {columns, rows, count} JSON or CSV. |
GET |
/api/reports/eval-regression |
report eval regression |
GET |
/api/reports/evidence-inventory |
report evidence inventory |
GET |
/api/reports/executive-summary |
report executive summary |
GET |
/api/reports/policy-audit |
report policy audit |
GET |
/api/reports/release-comparison |
report release comparison |
GET |
/api/reports/run-history |
report run history |
GET |
/api/reports/seal-verification |
report seal verification |
GET |
/api/reports/throughput |
report throughput |
GET |
/api/reports/{report_id}/export?format=html|pdf |
Export a self-contained report artifact with an inline-SVG chart where the registry declares one (ADR-0201: server-side chart rendering). HTML needs nothing; PDF lazily imports the optional WeasyPrint extra and degrades to 501 + install hint when absent (pip install 'novafabric[compliance]'). |
Legal holds (3)
| Method |
Path |
Summary |
GET |
/api/holds |
list holds |
POST |
/api/holds |
create hold |
POST |
/api/holds/{hold_id}/release |
release hold |
Schema (1)
| Method |
Path |
Summary |
GET |
/api/schema/list |
List the CapsuleEventType values + meta (DB-SCH-1, cap-001 / ADR-0066; |
Topology (live) (5)
| Method |
Path |
Summary |
POST |
/api/topology/seed |
Seed the live topology store from capsules already on disk. |
GET |
/api/topology/snapshot |
Return current topology counts for the SPA status bar. |
GET |
/topology/cluster-edges |
Return inter-cluster edge aggregates for drawing edges between super-nodes. |
GET |
/topology/cluster-list |
Return clusters as plain JSON rows (largest first) for the Table/Treemap views. |
GET |
/topology/clusters |
Return Arrow IPC cluster layer (ADS v1 cluster_layer schema). |
Admin (11)
| Method |
Path |
Summary |
GET |
/api/admin/api-keys |
Read-only, secret-free API-key projection (ADR-0193). Bounded: limit (default 500, max 2000) pushed into SQL; total is a true COUNT(*); adds truncated (ADR-0199 B2). |
POST |
/api/admin/flush-jwks-cache |
Flush the JWKS cache, forcing a re-fetch from the OIDC provider. |
GET |
/api/admin/new-run-id |
Generate a fresh ULID for use as NOVAFABRIC_GLOBAL_RUN_ID (cap-007 FR-27). |
POST |
/api/admin/rebuild-metadata-db |
Disaster-recovery rebuild of the metadata DB from the chain log. |
POST |
/api/admin/reindex-runs |
Confirm-gated ({"confirmed": true}, else 400), idempotent INSERT-OR-REPLACE rebuild of the runs_cache index from the capsule filesystem — never deletes a capsule or a row with a still-existing capsule (ADR-0201 P8). Optional {"prune": true} (default false) also drops rows whose capsule directory is gone; response gains pruned. |
GET |
/api/admin/roles |
List role assignments (local mode). |
POST |
/api/admin/roles |
Assign a role to a subject (idempotent). Local-mode admin shortcut. |
DELETE |
/api/admin/roles/{subject}/{role} |
Revoke a role from a subject. 404 if not found, 409 if lockout would occur. |
GET |
/api/admin/tokens |
List issued local tokens (stored in ~/.novafabric/tokens.jsonl), newest-first. Bounded: limit (default 200, max 2000) + byte-offset cursor; adds next_cursor/truncated (ADR-0199 B2). |
POST |
/api/admin/tokens |
Issue a new local session token. |
DELETE |
/api/admin/tokens/{fingerprint} |
Revoke a token by fingerprint. |
alerts (1)
| Method |
Path |
Summary |
GET |
/api/alerts/recent |
recent alerts |
analytics (1)
| Method |
Path |
Summary |
GET |
/api/analytics/summary |
analytics summary |
incidents (5)
| Method |
Path |
Summary |
GET |
/api/incidents |
List the newest incidents with their nearest Art. 73 deadline. |
POST |
/api/incidents |
Open a new incident (forward-only lifecycle; never deleted). |
GET |
/api/incidents/{incident_id} |
Get one incident with computed Art. 73 deadlines. |
GET |
/api/incidents/{incident_id}/export |
Export an incident as an OECD-AIM or NIS2 structured report. |
POST |
/api/incidents/{incident_id}/transition |
Advance an incident's lifecycle (open → reported → closed). |
ingest-capsule (1)
| Method |
Path |
Summary |
POST |
/api/ingest-capsule |
Index capsule(s) into the runs metadata store — nova ingest-capsule. |
lineage-store (1)
| Method |
Path |
Summary |
GET |
/api/lineage-store/profile |
Generate a lineage-store deployment profile — nova lineage-store profile. |
livez (1)
| Method |
Path |
Summary |
GET |
/livez |
livez |
ops (1)
| Method |
Path |
Summary |
GET |
/api/ops/daemon-status |
Report whether the warm capture daemon socket is alive (read-only). |
query (1)
| Method |
Path |
Summary |
POST |
/api/query |
Execute a Capsule Query DSL document ({q, engine?}) — the same JSON/YAML query object nova query --query-file accepts, not a free-text/SQL string (ADR-0129, no new grammar). Read-only, capped at 5000 rows regardless of the plan's own limit; a 422 on any parse/allow-list failure, a 500 only on a malformed on-disk capsule index. |
readyz (1)
| Method |
Path |
Summary |
GET |
/readyz |
readyz |
Deprecation register (ADR-0188)
Maturity: mechanism works today (experimental); the register is empty and the CI
drift gate is future design. Policy and machinery:
ADR-0188.
Scope. The lifecycle policy applies to the multi-user nova server API only
(api/openapi.yaml, /v0 and later). The nova serve dashboard API documented in the
tables above remains experimental/unversioned — no lifecycle promises — until the
planned ADR-0183 consolidation.
Breaking-change definition (normative). Breaking: removing or renaming a path,
query parameter, or response field; narrowing a type or enum; tightening auth or
required scopes on an existing endpoint; changing error-envelope semantics (codes,
envelope shape). Non-breaking: adding optional fields, endpoints, enum values
documented as open, or response headers. If it is not on the breaking list, it may
ship in any release; if it is, the lifecycle below is mandatory.
Lifecycle. A deprecation is announced in CHANGELOG.md, the release notes, and
this register, all at once. From the deprecating release onward the endpoint emits
three headers on every response (implemented in
src/novafabric/server/deprecation.py):
| Header |
Format |
Meaning |
Deprecation: |
@<unix-timestamp> or true (RFC 9745) |
The endpoint is deprecated (and since when, if known). |
Sunset: |
HTTP-date (RFC 8594) |
Earliest date the endpoint may be removed. |
Link: |
<url>; rel="deprecation" |
Points at this register's entry for the endpoint. |
Minimum window. A deprecated endpoint stays working for at least two minor
releases. Removal lands only in a minor version bump pre-1.0 and only in a
major bump post-1.0. No silent removals, ever. Every register row names the
deprecating release, an earliest-removal release at least two minors later, and a
replacement (or an explicit "none"); each row must match a deprecated: true
operation in api/openapi.yaml (drift gate: future CI).
Register
No endpoints are currently deprecated.
| Endpoint |
Deprecated in |
Earliest removal |
Sunset date |
Replacement |
| — |
— |
— |
— |
— |
Interactive API docs
When the server is running, the same route table is browsable interactively:
- Swagger UI:
http://127.0.0.1:4321/api/docs?token=<token>
- OpenAPI JSON:
http://127.0.0.1:4321/api/openapi.json
Summary & next steps
- This document covers the local, experimental
nova serve --experimental HTTP surface —
a read-first (Layer A) dashboard over capsules on your own machine. The separate
multi-tenant nova server API is specified in api/openapi.yaml.
api/openapi.yaml is a hand-curated spec, not a generated one — but is now essentially
complete. As of this pass it documents 75 operations, matching all 75 always-mounted
nova server routes (the resource routers under /v0 plus the /scim/v2/* surface;
previously-noted gaps — /v0/orgs, /v0/workspaces, /v0/service-accounts,
/v0/admin/roles, /v0/runs/suggest-register, /v0/seal/*, /v0/auth/saml/*, SCIM — are
all present now). The one real remaining gap: the RFC 8628 device-authorization-grant demo
trio (POST /v0/auth/device/code, POST /v0/auth/token, POST /v0/auth/approve,
src/novafabric/server/routes/auth.py) is absent from the spec. That's arguably correct
scoping rather than drift — those three are unauthenticated demo scaffolding mounted only
when an operator opts in (config.demo_device_grant, default False; the HS256 tokens
they issue are never honored by the real verifier) — but flagging it here rather than
silently dropping it from this note.
- Requests to
/api/* require the session token, in either of two forms (v0.97.0):
a ?token=<token> query parameter, or an Authorization: Bearer <token> header —
when the header carries a Bearer credential it is authoritative and the query
parameter is ignored (an absent or non-Bearer header falls back to ?token=).
The query form is kept for the SPA and for printed/bookmarked URLs; prefer the header
for scripts and curl, so the secret stays out of shell history, proxy logs, and
Referer. The unauthenticated probes GET /api/health, GET /livez, and GET /readyz
are open (/metrics requires the token). The server binds to 127.0.0.1 and rejects
non-localhost Host headers.
- The endpoint tables are generated — after any route change, re-run
uv run python design/scripts/gen_api_reference.py so this file stays truthful.
- A route existing in the table is not by itself a claim that everything behind it is
fully shipped — several endpoints are explicitly marked experimental inline above
(e.g. the ADR-0204 content-search
scope parameter, the ADR-0210 GDPR erasure pair,
the OTLP ingest endpoint); anything not so marked is works today, per this repo's
docs-honesty convention (works today / experimental / planned / future design).
Where to go next:
- CLI reference (
docs/cli-reference.md) — the canonical, offline interface; every
dashboard view maps to a nova command.
- Developer guide (
docs/developer-guide.md) — adding asset types, CLI commands, and
report formats.
nova serve --help — the authoritative, always-current list of server flags.