API & dashboard¶
AgentWatch exposes its incidents through a documented HTTP API, and ships a React (Vite + TypeScript + Tailwind) dashboard that consumes that API. The dashboard never touches the database directly — everything goes through the same API an external consumer would use.
Running the API¶
agentwatch serve --host 127.0.0.1 --port 8000
FastAPI serves interactive OpenAPI docs at /docs and the raw schema at
/openapi.json.
Endpoints¶
| Method & path | Purpose |
|---|---|
GET /health |
Liveness check |
GET /incidents |
List incidents; filters: source, incident_type, abstained, min_severity; pagination: limit (1–500), offset |
GET /incidents/{id} |
Incident detail: body, all classifications, and reviews |
POST /incidents/{id}/review |
Record a human review of the latest classification |
GET /stats |
Totals, per-type counts, and abstention rate |
GET /exports/incidents.csv |
Export incidents (with latest classification) as CSV |
Listing incidents¶
curl "http://localhost:8000/incidents?incident_type=deception&limit=20"
Response is a page:
{
"items": [
{
"id": 12,
"source": "hackernews",
"url": "https://news.ycombinator.com/item?id=...",
"title": "...",
"published_at": "...",
"ingested_at": "...",
"classification": {
"incident_type": "deception",
"relevance": "relevant",
"severity": 3,
"confidence": 0.7,
"abstained": false,
"model_name": "baseline",
"prompt_version": "v1"
}
}
],
"total": 1,
"limit": 20,
"offset": 0
}
Recording a review¶
curl -X POST "http://localhost:8000/incidents/12/review" \
-H "Content-Type: application/json" \
-d '{"reviewer": "alice", "decision": "accept", "notes": "clear first-party report"}'
decision is one of accept, override, or false_positive. The review is attached
to the incident's most recent classification, preserving the machine label alongside
the human judgement.
Authentication¶
Read endpoints are public. If AGENTWATCH_API_KEY is set, write endpoints
(POST .../review) and the CSV export require a matching X-API-Key header:
curl -X POST ".../review" -H "X-API-Key: $AGENTWATCH_API_KEY" -H "Content-Type: application/json" -d '...'
When the variable is unset, authentication is disabled — so a reviewer can run the whole thing locally with zero configuration, while a production deployment can lock writes down by setting the key.
The dashboard¶
The dashboard is a React single-page app (Vite + TypeScript + Tailwind, Recharts)
in frontend/, deployed as a static site and served locally by Caddy in the compose
stack. To run just the frontend against a local API:
agentwatch serve # API on :8000, in one terminal
cd frontend && npm install
VITE_API_URL=http://localhost:8000 npm run dev # web on :5173, in another
Three pages:
- Overview — headline metrics (incidents, classified, abstention rate) and an incidents-by-type chart.
- Incident Explorer — a filterable table of incidents and their latest classification.
- Review Queue — open an incident, read its evidence and classification, and submit an accept / override / false-positive decision.
Because the dashboard talks only to the API, the same API backs both human review and any external/automated consumer.