Worked health samples
The liveness probes report one thing: whether the API process is up and answering requests. They do not probe the database or any upstream dependency — useGET /health/email below when monitoring an individual
channel instead of the origin’s alive signal.
The 200 body carries three fields:
status— the string"ok". Assert on this exact value; anything else (or a non-2xx status) means the probe is failing.timestamp— the ISO-8601 wall time on the API at response time.version— the git SHA of the running build. Poll this after a deploy to confirm every pod rolled out before you shift traffic.
X-API-Key header — send it if your template cannot omit headers, it is
ignored either way.
The two versioned aliases (/api/health and /api/v1/health) expand the
same data into a per-subsystem register — a top-level status plus one
components row each for the API, database, cache, voice gateway, worker,
and storage — so status pages can attribute a degraded interval to the
failing piece. The worked responses in the two operation sections below
show that shape; section 6 shows the degraded variant.
1. Liveness probe
200
2. The three aliases
GET /health, GET /api/health, and GET /api/v1/health all run the
same liveness handler and return the same body. Point your checker at
whichever path it already polls — listing all three on one load balancer
adds nothing. Kubernetes liveness, external uptime monitors, and most
health-check configurations each conventionally guess a different one,
which is why all three exist.
3. Reading the probe in a load balancer or CI
Assert onstatus === "ok"; the timestamp and version fields are
context, not gates:
status is not "ok") tells the load
balancer to pull the pod out of rotation. A version that does not
match the SHA your deploy pipeline just shipped tells CI a stale pod is
still serving, so the rollout has not finished — keep checking until it
converges before draining the old pool.
4. Errors
The unversioned probes never validate credentials, so the failure modes are transport-level rather than API-level:- 5xx / connection refused — the process is not answering; the load balancer’s retry policy applies.
- 429 — rate limited — shared-rate monitors probe too frequently; raise the interval.
5. Email-channel liveness
GET /health/email is a separate probe for the email channel’s outbound
path, so a tenant email outage does not read as an API-wide outage. Use
the generic /health above for the origin and /health/email only when
you track email as its own component; the public status
page wiki documents one health-check URL per
component. The API request logs
console covers the deeper tenant-side
monitoring path when a probe flaps but the endpoint keeps returning
"ok".
200
status reading "degraded" and a detail string describing the
underlying failure — the status page records that interval as downtime
instead of the 100%-uptime reading the bare /health probe would give
during a real email outage.
6. The degraded variant of the origin probes
When a subsystem fails its probe,GET /api/health and
GET /api/v1/health return the same components register with that
component reading "red" and the top-level status flipped to
"degraded":
200
status is the rollup (every component
green ⇒ "ok"; any red ⇒ "degraded"), while each component row names
the failing piece and, once degraded, carries degraded_since plus a
short detail. A yellow component alone keeps the top-level status at
"ok" and only flags the row. The HTTP code stays 200 in both cases —
gate your status page on the body, not on the status code.