grithdocs

Health and tier

Liveness, plan tier, licence refresh state and the narrow config read/write the dashboard uses.

MethodPathAuth
GET/api/healthOpen
GET/api/tierOpen
GET/api/license/statusOpen
GET/api/onboarding/statusOpen
GET/api/configDashboard token
PUT/api/configDashboard token, x-grith-csrf

GET /api/health

status is healthy when every subsystem reports ok, degraded if any is degraded, and unhealthy if any errored. The four subsystems are audit, digest, proxy and supervisor.

The body carries status, version, uptime_seconds, a subsystems map of {status, message?, latency_ms?}, instance_id and protocol_version.

Two optional fields matter more than the rest. audit_quarantined and audit_read_only appear only when set, and they are on the unauthenticated payload deliberately: the CLI reads them before starting a supervised session, so a daemon that cannot durably record decisions is caught before a tool is spawned. instance_id is regenerated on every start, which lets a client tell "the daemon that admitted me" from "the daemon that replaced it" - something a PID cannot express.

GET /api/tier

tier, seats, max_sessions, renewal_date, billing_portal_url, refresh, session_limit_rejections and session_limit_rejection_window_days, plus features.

max_sessions is the licence ceiling - 2 on Community, 64 on a paid plan - not the value of supervisor.max_concurrent_sessions. The lower of the two wins at session registration.

features is a flat map of 13 booleans. It is a JSON object, so read it by key - the serialised order is not stable:

features, on Community
{
"proxy": true, "audit": true, "digest": true, "supervisor": true,
"filters": true, "cli": true, "dashboard": true,
"notification_channels": false, "usage_analytics": false,
"cloud_sync": false, "policy_editor": false,
"pagerduty": false, "opsgenie": false
}

The first seven are true on every tier. The next four are what a Pro licence turns on. pagerduty and opsgenie are always false.

GET /api/license/status

The refresh-health view, kept separate from /api/tier so a caller that only needs "is my licence still fresh" does not pull the feature list: tier, seats, renewal_date, billing_portal_url, air_gapped, hours_since_refresh and the same refresh block. This is what grith pro status reads.

GET /api/config

Three fields: config_scope (the two scope names, local and team - not paths), proxy (the effective auto_allow_threshold and auto_deny_threshold), and filters - one entry per filter with id, name, phase and enabled. Both the thresholds and each enabled are the effective values: the running defaults, then team-config.toml, then config.toml on top.

PUT /api/config

Not a general config writer. It accepts four things and nothing else: a scope of local or team, a filters array of {id, enabled}, proxy.auto_allow_threshold and proxy.auto_deny_threshold, and server.auto_open_dashboard.

PUT /api/config
{
"scope": "local",
"proxy": { "auto_allow_threshold": 3.5 },
"filters": [ { "id": "behavioural", "enabled": false } ]
}

An unknown filter id is 400 UNKNOWN_FILTERS. Thresholds outside 0.0-10.0, or an allow threshold at or above the deny threshold, are 400 INVALID_PROXY_THRESHOLD. Success is {status, scope, filters_updated, proxy_updated, server_updated, message}. The write lands in config.toml, or team-config.toml when scope is team; the running proxy keeps its current thresholds until the daemon restarts.

See also

Last updated: 2026-08-24Edit this page on GitHub →