Health and Status
GET /v1/health (liveness with database connectivity), GET /ready (readiness), and GET /v1/status (the platform status feed with per-component health).
GET /v1/health
Liveness with database connectivity, the API version, and the last sync timestamp. Rate-limited on its own bucket so a monitor never competes with data traffic.
curl https://api.philidor.io/v1/health{
"data": {
"status": "ok",
"version": "1.2.0",
"vaultCount": 1095,
"lastSync": "2026-09-12T07:54:42.846Z",
"timestamp": "2026-09-12T08:26:17.398Z",
"lastScoreRun": {
"completedAt": "2026-09-12T07:52:20.125Z",
"failSafeMode": "normal"
},
"assetRegistryCoverage": {
"totalExposures": 548,
"withAssetVersion": 497,
"coveragePercent": 90.69
},
"assetIdentityCoverage": {
"identityBasis": "chain_and_address",
"totalIdentities": 581,
"withApprovedVersion": 530,
"coveragePercent": 91.22,
"byChain": [
{
"chainId": 1,
"totalIdentities": 262,
"withApprovedVersion": 261,
"coveragePercent": 99.62
}
]
},
"assetRegistryQueueBacklog": 39,
"evidenceSigner": { "...": "..." }
}
}version matches the info.version of /v1/openapi.json. lastScoreRun.failSafeMode is normal unless the platform has entered a fail-safe mode, in which case risk endpoints answer 503 with X-Philidor-FailSafe-Mode and Retry-After.
Under a database fault this endpoint answers 503 (never a 500), with Retry-After.
GET /ready
Readiness for load balancers and deploy tooling: 200 only when the database answers a query within one second. Redis is reported but is not a readiness dependency.
curl https://api.philidor.io/ready{ "status": "ready", "db": "ok", "redis": "closed" }redis is the state of the API's Redis circuit breaker: closed means Redis is answering, open means the API is serving with its bounded in-process fallbacks.
GET /v1/status
The platform status feed behind philidor.io/status. No key needed; cached for 60 seconds; its own rate bucket (60 requests per minute per IP) that keeps answering while Redis is down.
curl https://api.philidor.io/v1/status{
"data": {
"status": "operational",
"rollup": "operational",
"last_checked_at": "2026-09-12T08:18:02.000Z",
"uptime": { "24h": 100, "30d": 99.85 },
"components": [
{
"name": "api",
"status": "operational",
"detail": "loopback heartbeat up (162 ms)",
"checked_at": "2026-09-12T08:18:02.000Z"
},
{
"name": "reachability",
"status": "operational",
"detail": "off-box probe up (23 ms)",
"checked_at": "2026-09-12T08:18:40.000Z"
},
{
"name": "errors",
"status": "operational",
"detail": "0 of 1634 responses were 5xx in the last 15 min",
"checked_at": "2026-09-12T08:19:01.000Z"
},
{
"name": "events_stream",
"status": "operational",
"detail": "0 open streams; 0 queue overflows since start",
"checked_at": "2026-09-12T08:19:01.000Z"
},
{
"name": "webhooks",
"status": "operational",
"detail": "0/0 deliveries succeeded in the last hour; 0 in the dead-letter queue",
"checked_at": "2026-09-12T08:19:01.000Z"
},
{
"name": "data_freshness",
"status": "operational",
"detail": "newest vault sync 10 min ago",
"checked_at": "2026-09-12T07:54:42.846Z"
}
],
"signals": { "error_rate_15m": 0, "requests_15m": 1634, "external_down_samples": 0 }
}
}| Field | Meaning |
|---|---|
status | Platform health: the worst of the api, reachability and errors components. operational, degraded or down. |
rollup | The worst status across every component, including the delivery surfaces (event stream, webhooks) and data freshness. |
components[] | One row per component with a human-readable detail and the time of the observation. api is the loopback heartbeat, reachability the off-box probe (down after three consecutive failed samples), errors the 5xx rate over 15 minutes (degraded above 0.5% with at least 200 requests), events_stream a subscriber queue overflow within 15 minutes, webhooks a delivery success rate under 80% over at least 10 attempts in the last hour or any dead-lettered delivery, data_freshness a newest vault sync older than 90 minutes. |
signals | The raw inputs behind the rows. |
uptime | Rolling uptime percentages from the same interval math as the SLA reports; a window is omitted until it has enough history. |
status never 500s: if a component's read fails, that row reads degraded with a reason and the other rows are unaffected. Every field is additive — new component rows may appear; existing names and statuses keep their meaning.