Generated from the specification, not typed out.
This table is built from the same document the API serves, so it cannot promise a route that does not exist. Two endpoints write; the rest read.
| Path | Methods | What it does |
|---|---|---|
| /api/v1/openapi | GET | This document |
| /api/v1/systems | GET · POST | List AI systems |
| /api/v1/systems/{id} | GET | Get one AI system |
| /api/v1/obligations | GET | List obligations |
| /api/v1/obligations/{id} | PATCH | Update an obligation |
| /api/v1/incidents | GET | List incidents |
| /api/v1/evidence | GET | List evidence |
| /api/v1/risk-items | GET | List risk items |
| /api/v1/reports | GET | List generated reports |
| /api/v1/audit-log | GET | Pull the audit log |
10 paths, of which 2 accept a write. A drift test fails the build if the specification and the routes disagree.
One key, and a read-only mode that means it.
Organisation keys begin ak_ and are created in Settings → API keys and webhooks. A key marked READ_ONLY is rejected on a mutating endpoint rather than quietly dropping the write — a silent no-op is how an integration reports success for months without changing anything.
Every call is scoped to the organisation that owns the key. There is no cross-organisation read, and no key can widen its own scope.
Open the OpenAPI 3.1 documentAn assistant can read the register directly.
A stateless JSON-RPC server at POST /api/mcp, using the same keys. It exposes the read tools plus shadow-AI intake, so you do not need a bespoke integration to ask questions about your own estate.
list_systemsregister_systemlist_obligationslist_evidencelist_incidentslist_risk_itemsquery_audit_logFour outbound webhooks, and a resumable audit feed.
system.createdincident.createdobligation.status_changedevidence.verifiedFor a SIEM or a warehouse, the audit-log endpoint takes a since parameter and a cursor, so a poller resumes exactly where it stopped rather than re-reading the day.
About the API.
How do I authenticate?
With an organisation API key that starts with ak_, created in Settings → API keys and webhooks and sent as a bearer token. Keys marked READ_ONLY are rejected on mutating endpoints rather than silently ignoring the write. API access is available on the Manage plan and above.
Is the specification machine-readable?
Yes. GET /api/v1/openapi serves the OpenAPI 3.1 document, and a unit test fails the build if the spec drifts from the routes. That is also why the table on this page is generated from the spec rather than typed out — it cannot describe an endpoint that does not exist.
What can the API change, and what is read-only?
Two endpoints write: creating a system, and patching an obligation. Everything else reads. That asymmetry is deliberate — an integration should be able to pull your register into your own stack without being able to rewrite the record it is reporting on.
Is there an MCP server?
Yes, at POST /api/mcp — stateless JSON-RPC using the same ak_ keys. It exposes the read tools plus shadow-AI intake, so an assistant can answer questions about your register without a bespoke integration.
How do I get told when something changes?
Outbound webhooks cover system.created, incident.created, obligation.status_changed and evidence.verified. For an audit feed, the audit-log endpoint takes a since parameter and a cursor, so a poller can resume exactly where it stopped.
API keys are available on the Manage plan and above. The specification itself is public, so you can see exactly what you would be integrating with before you pay for it.