Skip to content

Health & Readiness Probes

ChannelWatch exposes four HTTP health endpoints. Three are probe-oriented endpoints under /healthz/*, and one is a broader service summary at /api/health.

ChannelWatch diagnostics screen showing health summary, multi-DVR status, debug bundle download, log tools, and alert tests
Diagnostics And Debug Bundle Diagnostics groups health checks, log review, alert tests, and sanitized debug bundle download in one operator surface. Captured from ChannelWatch v0.9.10 with safe demo data.
EndpointPurposeHealthy status
/api/healthGeneral monitoring summary200 OK
/healthz/liveProcess is alive and responding200 OK
/healthz/readyMonitoring readiness summary for enabled DVRs200 OK
/healthz/startupStartup completion gate200 OK

All four endpoints return JSON payloads. They are auth-exempt in the backend and do not require the shared API key.

GET /api/health returns a JSON summary built from the monitoring-health snapshot:

{
"status": "ok",
"ready": true,
"dvrs": [
{
"id": "dvr_abc12345",
"name": "Living Room",
"monitoring_status": "healthy",
"reason": null
}
]
}

If the aggregate monitoring state is degraded, the same payload shape is returned with status: "degraded" and HTTP 503.

The liveness probe checks whether the web process can respond at all. The current implementation always returns a simple JSON success body while the process is alive:

{
"status": "ok"
}

Use this probe to let Kubernetes restart a wedged process. It does not evaluate DVR connectivity or freshness.

The readiness probe returns a JSON monitoring summary. On success it returns 200 with a payload like:

{
"status": "ready",
"ready": true,
"dvrs": [
{
"id": "dvr_abc12345",
"name": "Living Room",
"monitoring_status": "healthy",
"freshness_status": "fresh",
"connected": true,
"reason": null,
"last_freshness_at": "2026-04-21T07:00:00+00:00",
"freshness_age_seconds": 15.0
}
],
"stale_threshold_seconds": 300,
"tested_version_range": {
"min": "2024.01.01",
"max": "2027.01.01"
}
}

If the aggregate monitoring summary is not ready, the same JSON shape is returned with status: "degraded" and HTTP 503.

The important distinction is that readiness is based on the watchdog-style monitoring summary, not just raw process liveness.

The startup probe reports whether the backend has completed startup initialization:

Healthy:

{
"status": "ready"
}

Not ready yet:

{
"status": "not_ready"
}

The backend returns HTTP 503 until startup completes.

The /api/health and /healthz/ready payloads are both built from the monitoring health summary used by the backend watchdog snapshot. In practice that means readiness reflects the current per-DVR monitoring state, including connection and freshness information surfaced through fields such as:

  • monitoring_status
  • freshness_status
  • connected
  • reason
  • last_freshness_at
  • freshness_age_seconds

This is broader than a single last_event_at check. The backend exposes both event timing and freshness/watchdog summary fields, and the readiness endpoint is the aggregate view.

livenessProbe:
httpGet:
path: /healthz/live
port: 8501
initialDelaySeconds: 0
periodSeconds: 30
timeoutSeconds: 3
failureThreshold: 3
readinessProbe:
httpGet:
path: /healthz/ready
port: 8501
initialDelaySeconds: 0
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
startupProbe:
httpGet:
path: /healthz/startup
port: 8501
initialDelaySeconds: 0
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 30