Health & status
Endpoints for load balancers, uptime monitors and dashboards. None of them needs a token except the metrics endpoint. A human-readable status page with 90 days of history is at /health. All health endpoints allow cross-origin requests.
| Use it for | Endpoint |
|---|---|
| Container / process liveness | GET /healthz |
| Load-balancer readiness, uptime monitors | GET /readyz |
| Dashboards, detailed checks | GET /status |
| Availability history | GET /health/history |
Liveness
GET /healthz
No authentication
200 ok whenever the process is running. It doesn't check dependencies, so a database
outage doesn't make an orchestrator restart healthy containers.
curl "https://fw.unitcircle.ca/healthz"
http GET "https://fw.unitcircle.ca/healthz"
import requests
r = requests.get(
"https://fw.unitcircle.ca/healthz",
)
print(r.status_code, r.text)
ok
Readiness
GET /readyz
No authentication
Checks the database and the object store (with short timeouts). 503 if either fails —
point external uptime monitors here.
curl "https://fw.unitcircle.ca/readyz"
http GET "https://fw.unitcircle.ca/readyz"
import requests
r = requests.get(
"https://fw.unitcircle.ca/readyz",
)
print(r.status_code, r.json())
{
"checks": {
"db": {"ok": true, "latency_ms": 1},
"storage": {"ok": true, "latency_ms": 7}
},
"ready": true
}{
"checks": {
"db": {"ok": false, "latency_ms": 1001, "detail": "database unreachable"},
"storage": {"ok": true, "latency_ms": 6}
},
"ready": false
}
Retrieve service status
GET /status
No authentication
Overall status (ok, degraded or down), version, uptime, connection and request
counters, database pool statistics, and the latest result of each check: database,
object storage, email relay, and backup freshness. degraded means the service works but
a check such as backups needs attention; down (HTTP 503) means the database is
unreachable.
curl "https://fw.unitcircle.ca/status"
http GET "https://fw.unitcircle.ca/status"
import requests
r = requests.get(
"https://fw.unitcircle.ca/status",
)
print(r.status_code, r.json())
{
"active_connections": 1,
"checks": {
"backup": {"age_hours": 6, "backend": "tarsnap", "last_success": "2026-09-25T18:23:18.83603Z", "ok": true},
"db": {"latency_ms": 1, "ok": true},
"mail": {"backend": "smtp", "checked_at": "2026-09-26T00:58:38.77972Z", "ok": true},
"storage": {"latency_ms": 5, "ok": true}
},
"db_pool": {"acquire_wait_ms_total": 10, "idle": 1, "max": 10, "size": 1},
"git_sha": "6238f4b",
"requests_in_flight": 1,
"requests_total": 75,
"started_at": "2026-09-26T00:58:38Z",
"status": "ok",
"time": "2026-09-26T01:04:31Z",
"uptime_seconds": 352,
"version": "1.0.0"
}
Retrieve health history
GET /health/history
No authentication
Daily availability per component (api, db, storage, smtp, backup), from checks
the service runs every minute, plus overall uptime per component for the period. Today's
figures are live.
Query parameters
daysinteger1–400, default 90.
curl "https://fw.unitcircle.ca/health/history?days=2"
http GET "https://fw.unitcircle.ca/health/history?days=2"
import requests
r = requests.get(
"https://fw.unitcircle.ca/health/history",
params={
"days": "2"
},
)
print(r.status_code, r.json())
{
"days": 2,
"uptime_pct": {"api": 100, "backup": 100, "db": 100, "mail": 100, "storage": 100},
"daily": [
{"day": "2026-09-25", "component": "api", "samples": 339, "ok_samples": 339, "uptime_pct": 100, "p50_ms": 4, "p95_ms": 6, "incidents": 0},
{"day": "2026-09-25", "component": "db", "samples": 339, "ok_samples": 339, "uptime_pct": 100, "p50_ms": 1, "p95_ms": 2, "incidents": 0},
{"day": "2026-09-25", "component": "mail", "samples": 33, "ok_samples": 33, "uptime_pct": 100, "p50_ms": 9, "p95_ms": 55, "incidents": 0},
{"…": "one entry per component per day"}
]
}
Retrieve metrics
GET /metrics
Admin token
Prometheus text format: request counts and durations per route, uploads, downloads,
update checks, rate-limit rejections, database pool and backup age. Requires the
operator's metrics token (Authorization: Bearer <METRICS_TOKEN>) or an administrator
token.
curl "https://fw.unitcircle.ca/metrics" \ -H "Authorization: Bearer YOUR_ADMIN_TOKEN"
http -A bearer -a YOUR_ADMIN_TOKEN GET "https://fw.unitcircle.ca/metrics"
import requests
r = requests.get(
"https://fw.unitcircle.ca/metrics",
headers={"Authorization": "Bearer YOUR_ADMIN_TOKEN"},
)
print(r.status_code, r.text)
# TYPE http_requests_total counter
http_requests_total{route="/devices",method="GET",status="200"} 1
http_requests_total{route="/firmware/{domain}/{hw}/{hwver}/{fw}/{fwver}",method="GET",status="200"} 24
# TYPE http_request_duration_seconds summary
http_request_duration_seconds_sum{route="/devices",method="GET"} 0.004210
http_request_duration_seconds_count{route="/devices",method="GET"} 1
update_checks_total 24
uclogserver_uptime_seconds 352.4
backup_last_success_timestamp 1.790360598e+09{"type":"about:blank","title":"Unauthorized","status":401,"detail":"metrics require METRICS_TOKEN or an admin","instance":"/metrics","request_id":"…"}
Retrieve signing keys
GET /.well-known/jwks.json
No authentication
The public keys that sign API tokens, as a JSON Web Key Set (Ed25519, EdDSA). Use them
to check a token offline; the server still decides whether a token is revoked.
curl "https://fw.unitcircle.ca/.well-known/jwks.json"
http GET "https://fw.unitcircle.ca/.well-known/jwks.json"
import requests
r = requests.get(
"https://fw.unitcircle.ca/.well-known/jwks.json",
)
print(r.status_code, r.json())
{
"keys": [
{"alg": "EdDSA", "crv": "Ed25519", "kid": "2026-09-01-a1B2", "kty": "OKP", "use": "sig", "x": "njhynTM5__vh7w8s7KYd-_P_1iqFbr46TrvrdgUlfiM"}
]
}
Retrieve the OpenAPI description
GET /openapi.json
No authentication
A machine-readable OpenAPI 3.1 description of every endpoint on these pages, for code generators and API clients.
curl "https://fw.unitcircle.ca/openapi.json"
http GET "https://fw.unitcircle.ca/openapi.json"
import requests
r = requests.get(
"https://fw.unitcircle.ca/openapi.json",
)
print(r.status_code, r.json())
{
"openapi": "3.1.0",
"info": {"title": "uclogserver API", "version": "1.0.0", "…": "…"},
"paths": {"…": "…"}
}