HatchedDocs
Reference

Health & version probes

Bare-path liveness, readiness, and build-fingerprint endpoints for Kubernetes, Fly.io, and uptime monitoring.

Hatched exposes three top-level probe paths intended for ops tooling. They serve the same purpose as the prefixed /api/v1/health/* endpoints — but they are separate handlers, not the same backend, and they skip the API prefix so K8s/Fly probes work out of the box without remapping paths. The human-readable multi-component report lives at GET /api/v1/health.

EndpointPurposeStatus code
GET /healthzLiveness — "the process is up"always 200
GET /readyzReadiness — DB + Redis reachable200 ready, 503 not ready
GET /versionBuild fingerprintalways 200

The detailed multi-component breakdown (queues, image provider, latency per dependency) still lives at GET /api/v1/health for dashboards or on-call debugging.

GET /healthz

curl https://api.hatched.live/healthz
# {"ok":true,"uptime":4623}

Returns immediately. Uptime is in seconds since process start. Use this as your Kubernetes livenessProbe — restart the container only if the process is genuinely wedged.

GET /readyz

curl -i https://api.hatched.live/readyz
# HTTP/1.1 200 OK
# {"ready":true,"db":true,"redis":true}

Returns 503 with {"ready": false, ...} if Postgres or Redis is unreachable. Use as the Kubernetes readinessProbe so the pod is removed from the load balancer until both deps are green.

GET /version

curl https://api.hatched.live/version
# {
#   "version": "1.42.0",
#   "git_sha": "a1b2c3d4",
#   "built_at": "2026-05-25T09:14:30Z",
#   "node_version": "v20.11.0"
# }

Useful as a deployment fingerprint:

  • Diff git_sha between expected and actual to confirm a rollout succeeded across all instances.
  • Compare the SDK consumer's client.auth.whoami() plan against the API's version when reproducing a bug — "I'm on 1.42.0 with plan growth" is a lot easier to triage than "I think it broke yesterday."

The three env vars API_VERSION, GIT_SHA, and BUILT_AT are injected at build time by the deployment pipeline. Either may be "unknown" on local dev or in test environments where the build step is skipped.

Why two paths per probe

/api/v1/health/live (prefixed) and /healthz (bare) are separate handlers serving the same purpose — not the same handler. SDK calls and human dashboards use the prefixed form; ops tooling uses the bare form. Removing one of them would break either the SDK contract or the standard probe playbook — both are kept stable.

Their response shapes and readiness semantics also differ, so do not treat them as interchangeable:

  • Liveness: bare /healthz returns {"ok":true,"uptime":...}, while prefixed /api/v1/health/live returns {"alive":true,"uptime":...}.
  • Readiness: bare /readyz checks only DB + Redis, while prefixed /api/v1/health/ready additionally checks the queue and image provider (returning {"ready":...,"checks":{...}}). The prefixed endpoint can therefore report 503 while bare /readyz still reports 200.