Health
Liveness and dependency-check endpoint for uptime monitors, CI, and load balancers.
Health
A liveness/health probe used by BetterStack, CI, and load balancers.
Base URL: https://theroyalglow.in · Auth: Public. Unlike every other
endpoint, GET /api/health does not use the { success, data } envelope —
it returns its own documented HealthStatus contract and its own status codes.
The response always sends Cache-Control: no-store and an X-Health-Status
header. The admin app exposes an identical probe at
admin.theroyalglow.in/api/health; this page documents the customer probe on
theroyalglow.in.
GET /api/health
Runs three independent dependency checks (database, Redis, R2) in parallel and reports an overall status. The handler is fully guarded — each check is wrapped so the endpoint never throws.
Minimum role: Public
GET /api/healthThis endpoint takes no parameters.
Response shape
{
"status": "healthy",
"timestamp": "2026-06-02T09:20:00.000Z",
"version": "a1b2c3d",
"uptime": 12345.67,
"checks": {
"database": { "status": "pass", "latencyMs": 12 },
"redis": { "status": "skip", "latencyMs": 0, "message": "Redis not configured" },
"r2": { "status": "skip", "latencyMs": 0, "message": "R2 not configured" }
}
}Response fields
Prop
Type
Each component check is { status: "pass" | "fail" | "skip", latencyMs: number, message?: string }.
Overall status rules
The database is the only hard dependency. A skip never degrades the
overall status.
| Condition | Overall status | HTTP code |
|---|---|---|
database.status === "fail" | unhealthy | 503 |
Database passes, but redis or r2 is fail | degraded | 200 |
Database passes; Redis/R2 pass or skip | healthy | 200 |
So a no-keys local/dev environment (Redis and R2 unconfigured → skip) reports
healthy with a 200. Only a failing database produces a 503.
Status examples
Redis and R2 unconfigured (skip); database passes → 200.
{
"status": "healthy",
"timestamp": "2026-06-02T09:20:00.000Z",
"version": "a1b2c3d",
"uptime": 12345.67,
"checks": {
"database": { "status": "pass", "latencyMs": 12 },
"redis": { "status": "skip", "latencyMs": 0, "message": "Redis not configured" },
"r2": { "status": "skip", "latencyMs": 0, "message": "R2 not configured" }
}
}Redis configured but unreachable; database still passes → 200.
{
"status": "degraded",
"timestamp": "2026-06-02T09:20:00.000Z",
"version": "a1b2c3d",
"uptime": 12345.67,
"checks": {
"database": { "status": "pass", "latencyMs": 12 },
"redis": { "status": "fail", "latencyMs": 51, "message": "Redis unreachable" },
"r2": { "status": "skip", "latencyMs": 0, "message": "R2 not configured" }
}
}Database down → 503.
{
"status": "unhealthy",
"timestamp": "2026-06-02T09:20:00.000Z",
"version": "a1b2c3d",
"uptime": 12345.67,
"checks": {
"database": { "status": "fail", "latencyMs": 2003, "message": "DB unreachable" },
"redis": { "status": "skip", "latencyMs": 0, "message": "Redis not configured" },
"r2": { "status": "skip", "latencyMs": 0, "message": "R2 not configured" }
}
}Headers
Prop
Type
Was this page helpful?