Skip to content
Navigation

Health endpoints

Point your orchestrator's health checks here. Both endpoints are unauthenticated (no API key required) and safe to poll frequently.

Liveness

GET /api/health/live

Confirms the process is up and serving HTTP. Does no I/O, so a slow database can never make it fail.

curl https://your-domain/api/health/live
{ "status": "ok" }

Always returns 200 if the process can respond at all. Use this for a container orchestrator's restart-on-failure check.

GET /api/health (no suffix) is a legacy alias of /api/health/live, kept for existing consumers. Use /api/health/live in new configuration.

Readiness

GET /api/health/ready

Confirms the instance can actually serve traffic: the database answers, migrations are up to date, and (on worker and all roles) the background job worker is running.

curl https://your-domain/api/health/ready
{
  "status": "ok",
  "role": "all",
  "checks": {
    "db": { "ok": true },
    "migrations": { "ok": true },
    "workers": {
      "ok": true,
      "expected": true,
      "running": true,
      "loops": 1,
      "inFlight": 0,
      "schemaMissing": 0,
      "refused": 0
    }
  }
}

Returns 200 when every check passes, 503 with the same shape otherwise. Each failed check carries a short error code, one of "failed", "timeout", or "behind" (migrations not yet caught up), never raw error detail. Each check has a 3-second budget, so a hung dependency reports timeout instead of hanging the probe. role reports the replying process's QUACKBACK_ROLE (all, web, or worker). On a web replica, workers.expected is false and the check passes, since no workers run there.

Use /api/health/ready for your load balancer's traffic-admission check and Kubernetes' readinessProbe. Use /api/health/live for livenessProbe. Readiness can legitimately flip to 503 during a deploy or migration without meaning the process should be restarted.

Next steps