How to Design a Safe API Health Endpoint
A safe health endpoint is cheap, honest, and hard to abuse. It should tell external monitors whether critical dependencies are reachable without becoming an open proxy into your internals.
A health endpoint exists so an external monitor can ask a narrow question: are the dependencies we care about reachable enough to serve customers? It should be cheap to call, honest in failure, and boring under load. It should not become a debug console or an open proxy.
Public, Cheap, Honest, Boring
- Public when possible. Prefer unauthenticated reachability for the basic liveness signal. Put privileged detail behind auth or omit it.
- Cheap. Constant-time checks. No full report generation. No unbounded fan-out.
- Honest. If the database is required for requests to succeed, a DB failure should fail the health check.
- Boring. Stable JSON keys. No timestamps required for success. No unique ids that break assertions.
Suggested response shape
{
"status": "ok",
"checks": {
"database": "up",
"queue": "up"
}
}{
"status": "error",
"checks": {
"database": "down",
"queue": "up"
}
}Return a non-success HTTP status when status is not ok, so monitors that only read status codes still work. Pair with JSON assertions when soft failures can return 200. See API monitoring.
Dependency rules
- Include dependencies whose failure makes customer requests fail.
- Exclude third parties you cannot fix and that are not on the critical path for this service.
- Cap check time. A hung dependency should time out the health call, not hang forever.
- Do not follow user-controlled URLs inside the health handler.
Liveness versus readiness
Some teams split "process is up" from "ready to take traffic." External uptime monitors usually want readiness for customer paths. If you only expose liveness, you may stay green while traffic should be draining. Name the endpoint so operators know which one they are hitting.
What to assert from the monitor
- HTTP status in the success set you documented
statusfield equalsokwhen you use that shape- Optional: critical dependency fields equal
up
Avoid asserting wall-clock fields. Related: How to Monitor an API Without Creating Alert Noise.
Load and abuse
Health endpoints get polled. Keep them cache-friendly only if caching cannot hide dependency failure. Rate-limit abusive clients if needed, but do not rate-limit your monitor into false downtime. Document expected poll intervals for operators.
Ship checklist
- Path documented for on-call
- Success and failure examples recorded
- Monitor test passes before activation
- No secrets in response bodies
- Timeouts defined for each dependency check
After the endpoint ships, configure the monitor with confirmation settings from How to Monitor an API Without Creating Alert Noise. A perfect health handler still pages too often if the monitor treats every blip as downtime.
Revisit the dependency list when architecture changes. Yesterday’s optional cache can become today’s hard requirement after a launch. Health checks that lie about readiness teach everyone to ignore them.
Plain-text version · APIs and Webhooks
Was this useful?