Key points
- All five are public by design: they have to work when authentication does not.
/livezreports the process;/healthzreports readiness and stays unready while the database is unreachable./versionis the compatibility contract — released CLIs read it to refuse incompatible mutating requests./metricsis public unlessMETRICS_REQUIRE_AUTH=true.- None of them writes anything, and
/favicon.icoexists specifically to keep browser probes out of the audit log.
Operations
GET/healthzPublic
Readiness. Stays unready while setup preflight is retrying an unreachable database.
Notes
Use this for readiness gates. A cold start answers 503 until PostgreSQL is reachable, then flips to 200 without a restart.
Responses
The API is ready to serve requests.
{"status":"ok"}Preflight mode only: the platform is up but not ready. The body is the full preflight response, so the blocking check is visible without a second call.
{"ready":false,"can_login":false,"mode":"setup","checks":[{"id":"database","label":"Database","status":"error","message":"database is not reachable yet","required":true}]}Side effects
- None. The probe reads state and never writes.
Proven by
services/nopsai/auth_middleware_test.goservices/nopsai/health_handler.goservices/nopsai/setup_preflight.go
GET/livezPublic
Liveness. Answers as soon as the process is up, independent of database state.
Notes
Never gate a restart on this returning 200 with a broken database — that is what /healthz is for.
Responses
The process is alive.
{"status":"alive"}Side effects
- None.
Proven by
services/nopsai/auth_middleware_test.goservices/nopsai/health_handler.go
GET/versionPublic
Build identity: product and API versions, supported CLI and runner ranges, capabilities, and the release manifest digest.
Notes
Released CLIs read this to reject incompatible mutating requests before sending them.
Responses
Public build information. Deliberately carries no deployment configuration and no credentials.
{
"productVersion": "0.22",
"commit": "e387a81d",
"buildDate": "2026-08-19T10:04:11Z",
"apiVersion": "v1",
"cliCompatibility": ">=0.20",
"runnerCompatibility": ">=0.20",
"runnerProtocolVersion": 1,
"capabilities": [],
"releaseManifestDigest": ""
}Side effects
- None.
Proven by
services/nopsai/version_handler_test.goservices/nopsai/version_handler.gopkg/buildinfo/buildinfo.go
GET/metricsPublic
Prometheus metrics, including identity-provider capability and authorization grant ownership series.
Notes
Set METRICS_REQUIRE_AUTH=true to require a bearer token. Leave it public only where the scrape path is already private.
Responses
Prometheus text exposition format.
# HELP nopsai_build_info Build identity of the running platform.
# TYPE nopsai_build_info gauge
nopsai_build_info{version="0.22"} 1Only when METRICS_REQUIRE_AUTH=true and the request carries no valid bearer token.
Side effects
- None.
Proven by
services/nopsai/routes.go
GET/favicon.icoPublic
Empty cacheable browser probe so missing-favicon requests do not create bearer token errors in audit logs.
Responses
Empty body. It exists to keep browser probes out of the authentication path.
Side effects
- None. It deliberately produces no audit record.
Proven by
services/nopsai/auth_middleware_test.goservices/nopsai/routes.go
Examples
curl -s "$NOPSAI_URL/livez"
curl -s -o /dev/null -w "healthz: %{http_code}\n" "$NOPSAI_URL/healthz"
curl -s "$NOPSAI_URL/version" | jq '{productVersion, apiVersion, runnerProtocolVersion}'
curl -s "$NOPSAI_URL/metrics" | head -5How it works
Gate restarts on /livez and traffic on /healthz. Inverting the two produces a restart loop during a slow database start, because readiness is exactly the thing that is temporarily false.
During setup-preflight mode /healthz answers 503 with the full preflight document rather than a bare status, so the blocking check is visible without a second call.
Implementation evidence
services/nopsai/health_handler.goReadiness and liveness responses.
services/nopsai/version_handler.goPublic build identity payload.

