Skip to main content

Governance Dashboard

The governance dashboard endpoints turn the raw audit chain into something a security team can actually look at. You get totals, violations broken down by policy and agent, a time-series of activity, and per-agent violation history — all served from a single SQL query against the audit log.

Tier: All endpoints on this page require the governance_dashboard feature. Available on Starter+. Free-tier tenants receive a 403.


GET /v1/control/dashboard

Aggregated governance stats for a configurable time window.

Query parameters

ParameterTypeDefaultDescription
windowstring7dTime window. One of 24h, 7d, 30d.
bucketstringautoTime-series bucket size. hour or day. Defaults to hour for 24h window, day for 7d and 30d.

Response shape

FieldTypeDescription
windowstringEchoes the requested window.
bucketstringEchoes the bucket (resolved if auto).
backendstringpostgres or file. See Postgres vs file mode below.
totalsobjectAggregate counts. See below.
violations_by_policyobject[]One entry per policy that fired in the window, with severity breakdown.
violations_by_agentobject[]One entry per agent that hit a violation.
time_seriesobject[]One entry per bucket.

totals fields

FieldTypeDescription
evaluationsnumberTotal actions evaluated against policies.
executednumberActions that ran (allowed or post-approval).
pending_reviewnumberActions currently held in the approval queue.
approvednumberActions approved by a human reviewer.
deniednumberActions denied by a human reviewer.

violations_by_policy[] fields

FieldTypeDescription
policystringPolicy name.
countnumberTotal times the policy fired in the window.
severity_breakdownobjectMap of severity → count (e.g., {"critical": 3, "high": 12}).

violations_by_agent[] fields

FieldTypeDescription
agent_idstringThe agent that hit the violation.
countnumberTotal violations for this agent in the window.

time_series[] fields

FieldTypeDescription
bucketstringISO 8601 timestamp at the start of the bucket.
executednumberActions executed in this bucket.
pending_reviewnumberActions that entered pending in this bucket.
approvednumberApprovals recorded in this bucket.
deniednumberDenials recorded in this bucket.

Examples

from novyx import Novyx

nx = Novyx(api_key="nram_your_key")

dash = nx.governance_dashboard(window="7d")

print(dash["totals"])
# {'evaluations': 1248, 'executed': 1109, 'pending_review': 87, 'approved': 134, 'denied': 18}

for p in dash["violations_by_policy"]:
print(f"{p['policy']}: {p['count']} ({p['severity_breakdown']})")

Sample response

{
"window": "7d",
"bucket": "day",
"backend": "postgres",
"totals": {
"evaluations": 1248,
"executed": 1109,
"pending_review": 87,
"approved": 134,
"denied": 18
},
"violations_by_policy": [
{
"policy": "pii_protection",
"count": 47,
"severity_breakdown": {"critical": 3, "high": 38, "medium": 6}
},
{
"policy": "FinancialSafetyPolicy",
"count": 12,
"severity_breakdown": {"high": 12}
}
],
"violations_by_agent": [
{"agent_id": "support-bot", "count": 41},
{"agent_id": "billing-bot", "count": 18}
],
"time_series": [
{
"bucket": "2026-04-04T00:00:00Z",
"executed": 142,
"pending_review": 11,
"approved": 18,
"denied": 2
},
{
"bucket": "2026-04-05T00:00:00Z",
"executed": 168,
"pending_review": 14,
"approved": 22,
"denied": 3
}
]
}

Errors

StatusCodeCause
403novyx_ram.v1.tier.feature_requiredTenant tier does not include governance_dashboard (Free tier).

Postgres vs file mode

The dashboard reads from the same audit chain as the rest of Novyx. Tenants on the standard cloud deployment use the Postgres backend (backend: "postgres") and get full aggregate stats.

Tenants in file mode (local SQLite or filesystem audit log) receive an empty-but-valid response: the same shape, with all counts at zero and backend: "file". This lets dashboard clients render the same UI regardless of backend without special-casing — a "no data yet" state instead of a 500 or a missing field.

If you're integrating the dashboard into your own tooling, check backend to know whether the zeros are "no activity" or "the file backend doesn't aggregate."


GET /v1/control/agents/{agent_id}/violations

Per-agent violation history. Returns audit entries containing non-empty violation payloads, ordered most recent first.

Path parameters

ParameterTypeDescription
agent_idstringThe agent identifier.

Query parameters

ParameterTypeDefaultDescription
limitnumber50Max entries to return.
sincestringISO 8601 timestamp lower bound.
untilstringISO 8601 timestamp upper bound.

Both timestamp params accept full ISO 8601 with timezone (e.g. 2026-04-01T00:00:00Z). Invalid input returns 400 novyx_ram.v1.control.invalid_violations_param with the offending field name in the message.

Response shape

FieldTypeDescription
agent_idstringThe agent.
totalnumberNumber of entries returned.
backendstringpostgres or file.
violationsobject[]Violation entries. Each entry has action_id, action, timestamp, event, triggered_policy, severity, reason, risk_score, violation_count.

Examples

v = nx.agent_violations("billing-bot", limit=20)
print(f"{v['total']} violations for {v['agent_id']}")
for entry in v["violations"]:
print(f" {entry['timestamp']}: {entry['triggered_policy']} ({entry['severity']}) — {entry['reason']}")

Sample response

{
"agent_id": "billing-bot",
"total": 3,
"backend": "postgres",
"violations": [
{
"action_id": "act_xyz789",
"action": "http.transfer_funds",
"timestamp": "2026-04-10T13:42:00Z",
"event": "action_blocked",
"triggered_policy": "FinancialSafetyPolicy",
"severity": "critical",
"reason": "Unauthorized financial operation",
"risk_score": 0.92,
"violation_count": 1
}
]
}

Errors

StatusCodeCause
400novyx_ram.v1.control.invalid_violations_paramsince or until is not a valid ISO 8601 timestamp. The error message names the offending field.
403novyx_ram.v1.tier.feature_requiredTenant tier does not include governance_dashboard (Free tier).

See also