API Reference
HTTP endpoints and WebSocket protocol
Authentication
All API endpoints (except health check and shared views) require authentication. Browsers use the session cookie obtained by logging in:
POST /api/auth/login
Content-Type: application/json
{ "password": "your-password" }Development automation
When the Server is started from the repository with bun run dev:server, the
launcher binds the API to loopback and creates an ephemeral 256-bit development
credential. Agents and local scripts should use the request wrapper; they do not
need to handle or print the credential:
bun run dev:server:request -- GET /api/topologies
bun run dev:server:request -- POST /api/topologies/example/rebuild
bun run dev:server:request -- PATCH /api/topologies/example/discovery-policy \
--json '{"nodes":[]}'The wrapper uses the standard Authorization: Bearer scheme. This path is
available only when NODE_ENV=development, requires the API to be bound to
127.0.0.1 or ::1, accepts only normalized /api/* paths, and refuses to
send the generated credential to any remote HTTP or HTTPS origin. Production
continues to accept session authentication only. The credential is stored in a
gitignored owner-only file while the API is running and is removed on shutdown.
Starting apps/server/api directly with bun run dev does not create this
credential; use the server-level command above when automating API access.
Machine-readable contract
GET /api/openapi.json returns the OpenAPI 3.1 contract. It requires the same
administrator session or development Bearer credential as management endpoints:
bun run dev:server:request -- GET /api/openapi.jsonRequest and response schemas are the source of truth for migrated routes, and request schemas also perform runtime validation. Migration is incremental: the document currently covers health, system information, the admin runtime status, data source CRUD, and topology CRUD; the manually documented endpoints below remain available while their contracts move to the generated document.
For repository development, bun run openapi:generate writes the deterministic
apps/server/api/openapi.json snapshot and the web client's generated TypeScript
definitions. The web data source and topology CRUD clients consume those definitions with
openapi-fetch. CI checks artifact drift and requires every management route to
exist either in OpenAPI or in the explicit legacy migration ledger.
Shared views (public, token-scoped)
The only endpoints reachable without a session are the share routes below
(plus /api/health). A share token grants read-only access to a single
topology — or, for a dashboard, to just the topology/data-source ids that
dashboard's widgets reference. Responses are projected to a public shape:
internal fields (the resource's own share token, data-source ids, host
mappings, port aliases, timestamps) are never returned.
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/share/topologies/:token | Shared topology context (nodes/edges/metrics) |
| GET | /api/share/topologies/:token/graph | Shared topology as a NetworkGraph |
| GET | /api/share/topologies/:token/render | Shared topology render output |
| GET | /api/share/dashboards/:token | Shared dashboard shell (layout) |
| GET | /api/share/dashboards/:token/topologies/:id | Topology metadata for a widget in this dashboard |
| GET | /api/share/dashboards/:token/topologies/:id/graph | NetworkGraph for a widget in this dashboard |
| GET | /api/share/dashboards/:token/topologies/:id/context | Context for a device-status widget |
| GET | /api/share/dashboards/:token/datasources/:id/alerts | Alerts for an alert widget |
A dashboard-scoped request whose :id is not referenced by the dashboard's
layout returns 404, so the token cannot enumerate unrelated resources. The
management endpoints below (/api/topologies/:id, /api/dashboards/:id,
/api/datasources/:id/alerts, …) always require authentication.
HTTP Endpoints
Data Sources
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/datasources | List all data sources |
| POST | /api/datasources | Create data source |
| GET | /api/datasources/:id | Get data source details |
| PUT | /api/datasources/:id | Update data source |
| DELETE | /api/datasources/:id | Delete data source |
| POST | /api/datasources/:id/test | Test connection |
| GET | /api/datasources/:id/hosts | List monitored hosts |
| GET | /api/datasources/:id/hosts/:hostId/items | Host metrics items |
| GET | /api/datasources/:id/alerts | Get alerts |
Topologies
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/topologies | List all topologies |
| POST | /api/topologies | Create topology |
| GET | /api/topologies/:id | Get topology details |
| PUT | /api/topologies/:id | Update topology |
| DELETE | /api/topologies/:id | Delete topology |
| GET | /api/topologies/:id/render | Get rendered layout data |
| GET | /api/topologies/:id/sources | List linked data sources |
| POST | /api/topologies/:id/sources | Link a data source |
Dashboards
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/dashboards | List all dashboards |
| POST | /api/dashboards | Create dashboard |
| GET | /api/dashboards/:id | Get dashboard details |
| PUT | /api/dashboards/:id | Update dashboard |
| DELETE | /api/dashboards/:id | Delete dashboard |
Plugins
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/plugins | List all plugins |
| POST | /api/plugins | Add plugin (URL/path/upload) |
| DELETE | /api/plugins/:id | Remove plugin |
Webhooks
Webhook endpoints do not use session authentication. Each request must instead
carry the webhook secret configured on the source, supplied via the
X-Webhook-Secret header (preferred) or a ?secret= query parameter. The
secret is compared in constant time; a missing secret returns 401, an unknown
target returns 404, and a wrong secret returns 401.
The general form is POST /api/webhooks/:type/:id, where :id is the id of
the source (shown in its settings, not the secret itself). type=topology
re-fetches a webhook-mode topology source's graph; any other type is dispatched
to the matching data-source plugin — currently only grafana handles webhooks.
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/webhooks/topology/:id | Topology source webhook (:id = topology source id) — re-syncs the source, e.g. from NetBox |
| POST | /api/webhooks/grafana/:id | Grafana alert webhook (:id = data source id) |
| GET | /api/webhooks/health | Webhook health check |
Other
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/health | Health check (no auth required) |
| GET | /api/system | Build and update information |
| GET | /api/admin/status | Redacted runtime, scheduler, plugin, and subscriber status |
| GET | /api/openapi.json | OpenAPI 3.1 contract for migrated endpoints |
| GET | /api/auth/status | Check authentication state |
| POST | /api/auth/setup | Initial password setup |
| POST | /api/auth/logout | Logout |
WebSocket
Connect to ws://<host>/ws for real-time metrics streaming.
Client Messages
// Subscribe to topology updates
{ "type": "subscribe", "topology": "<topology-id>" }
// Filter specific nodes/links
{ "type": "filter", "nodes": ["router1"], "links": ["link-0"] }Server Messages
{
"type": "metrics",
"data": {
"nodes": {
"router1": { "status": "up" }
},
"links": {
"link-0": {
"status": "up",
"utilization": { "in": 45.2, "out": 12.8 }
}
},
"timestamp": 1705849200000
}
}