API Health Check
Status:
stableCategory:infrastructureAdded:2026-04-20Last reviewed:2026-04-21
Summary
Authenticated end-to-end health check. A 200 response proves the
full request path works: the API key was accepted and every component
the API depends on is responsive. This is the endpoint to call from
integration tests, CI smoke checks, and uptime monitors.
Endpoint
| Field | Value |
|---|---|
| Method | GET |
| Path | /api/health/check |
| Full URL | https://engine.tripod-health.com/api/health/check |
| Authentication | API key (required) |
| Request body | none |
| Response body | application/json |
| Idempotent | Yes |
| Rate-limited | Yes |
Purpose
A single call that answers the question integrators and on-call engineers actually care about: "if I made a real request right now, would it succeed?" It validates authentication, routing, and the health of every component the public API depends on. Any component being unhealthy changes either the status code or a field in the response body, so a monitor can alert on both.
Authentication
Send a valid API key in the apikey header. A missing or unknown
key returns 401 Unauthenticated before the request reaches this
endpoint.
Request
Headers
| Header | Required | Description |
|---|---|---|
apikey | Yes | Consumer API key. |
X-Request-ID | No | Optional client-generated correlation ID, up to 128 characters. If omitted, one is generated and returned in both the response body and the X-Request-ID response header. |
Path / query parameters
None.
Body
None. Any body on a GET request is ignored.
Response
Success — 200 OK
Returned when every checked subsystem is healthy.
{
"status": "ok",
"node": "ok",
"python": "ok",
"db": "ok",
"consumer": {
"id": "12345678-90ab-cdef-1234-567890abcdef",
"username": "example-consumer"
},
"request_id": "25eae3df-8442-426b-9163-482439835861",
"timestamp": "2026-04-20T17:32:10.812Z"
}
The example above mirrors a real production response. consumer.id and consumer.username reflect the API key the request was made with -- you will see your own consumer identity here, not the placeholder shown.
Degraded — 503 Service Unavailable
Returned when the API is reachable and authenticated but one of its
components is unhealthy. The body is the same shape as the success
response, with status set to "degraded" and the unhealthy
component reporting "down".
{
"status": "degraded",
"node": "ok",
"python": "down",
"db": "ok",
"consumer": {
"id": "12345678-90ab-cdef-1234-567890abcdef",
"username": "example-consumer"
},
"request_id": "8f2c3b1d-5e4a-4a9c-9b1e-2a7f1d3e4c5b",
"timestamp": "2026-04-20T17:32:10.812Z"
}
A "degraded" response means domain endpoints that depend on the
unhealthy component will fail; it is the honest "do not send real
traffic yet" signal. Monitors should treat 503 here identically to
5xx on business endpoints.
Response fields
| Field | Type | Always present | Description |
|---|---|---|---|
status | string | Yes | "ok" if every component is healthy; "degraded" if at least one is down. |
node | string | Yes | Component-status flag. Always "ok" when you receive this body — a response implies this component is answering. |
python | string | Yes | Component-status flag. When "down", scoring and composite endpoints will fail until it clears. |
db | string | Yes | Datastore reachability flag. Always "ok" when this body is returned — a failed datastore probe returns a 503 ServiceUnavailable error envelope instead of this body (see below). |
consumer.id | string | null | Yes | Consumer identifier derived from your API key. Useful for confirming you are calling as the consumer you expect. |
consumer.username | string | null | Yes | Human-readable consumer name. |
request_id | string | Yes | Correlation ID for this request. Quote this in support tickets. |
timestamp | string (ISO 8601 UTC) | Yes | Server timestamp when the response was emitted. |
The node, python, and db field names are historical
wire-protocol labels for the components the probe checks — treat them
as opaque component identifiers rather than as hints about the
underlying stack. Branch on the values ("ok" / "down") and on
status; do not rename or reinterpret the field names.
Datastore-probe failure — 503 ServiceUnavailable
If the datastore probe itself fails, the endpoint returns the standard error envelope instead of the health body above. This is the same shape as every other error response in the API:
{
"timestamp": "2026-04-20T17:32:10.812Z",
"error": "ServiceUnavailable",
"message": "Datastore probe failed",
"request_id": "8f2c3b1d-5e4a-4a9c-9b1e-2a7f1d3e4c5b"
}
This distinction matters for automation: parse the response body and
branch on status (for the degraded body) or on error (for the
error envelope). Both carry request_id; both can arrive as 503.
Status codes
| Code | Meaning | When |
|---|---|---|
200 | OK | All checked components are healthy. |
401 | Unauthenticated | Missing or invalid API key. |
404 | NotFound | Wrong path or method. GET /api/health/check is the only supported form. |
429 | RateLimited | Per-consumer rate limit exceeded. See Retry-After. |
503 (health body) | Degraded | A component is down. Body shape matches the success example with status: "degraded". |
503 (error envelope) | ServiceUnavailable | Datastore probe failed. Body is the standard error envelope. |
5xx (other) | Varies | Unexpected failure. request_id identifies the call in server logs. |
Examples
The language-specific invocations below assume the call() helper (or
its equivalent) from quickstart.md. Copy that
scaffolding once; the per-endpoint calls here are one-liners that reuse
it.
1. Canonical request and response
Send:
GET /api/health/check HTTP/1.1
Host: engine.tripod-health.com
apikey: $ENGINE_API_KEY
X-Request-ID: docs-health-check-canonical
Receive (200 OK):
{
"status": "ok",
"node": "ok",
"python": "ok",
"db": "ok",
"consumer": {
"id": "12345678-90ab-cdef-1234-567890abcdef",
"username": "example-consumer"
},
"request_id": "docs-health-check-canonical",
"timestamp": "2026-04-21T22:55:25.182Z"
}
2. Calling the endpoint in your language
curl
curl -sS "https://engine.tripod-health.com/api/health/check" \
-H "apikey: $ENGINE_API_KEY"
Python (requests)
# Uses the call() helper from quickstart.md.
health = call("GET", "/api/health/check")
if health["status"] == "ok":
print("engine healthy")
else:
print(f"degraded: python={health['python']} db={health['db']}")
Node.js (native fetch)
// Uses the call() helper from quickstart.md.
const health = await call("GET", "/api/health/check");
if (health.status === "ok") {
console.info("engine healthy", health.request_id);
} else {
console.warn(`degraded: python=${health.python} db=${health.db}`);
}
TypeScript
// Uses the typed call<T>() helper from quickstart.md.
interface HealthResponse {
status: "ok" | "degraded";
node: "ok" | "down";
python: "ok" | "down";
db: "ok" | "down";
consumer: { id: string | null; username: string | null };
request_id: string;
timestamp: string;
}
const health = await call<HealthResponse>("GET", "/api/health/check");
if (health.status !== "ok") {
throw new Error(`engine degraded: python=${health.python} db=${health.db}`);
}
Go
// Uses the call() helper from quickstart.md.
health, err := call("GET", "/api/health/check", nil, 3)
if err != nil {
panic(err)
}
if health["status"] != "ok" {
fmt.Printf("degraded: python=%v db=%v\n", health["python"], health["db"])
}
Java
// Uses the call() helper from quickstart.md.
String health = call("GET", "/api/health/check", null, 3);
String status = extract(health, "status");
if (!"ok".equals(status)) {
System.err.println("engine degraded: " + health);
}
C# (.NET HttpClient)
// Uses the Call() helper from quickstart.md.
var health = await Call(HttpMethod.Get, "/api/health/check");
var status = health.GetProperty("status").GetString();
if (status != "ok")
{
var python = health.GetProperty("python").GetString();
var db = health.GetProperty("db").GetString();
Console.Error.WriteLine($"degraded: python={python} db={db}");
}
PowerShell
# Uses the Invoke-Engine helper from quickstart.md.
$health = Invoke-Engine -Method Get -Path "/api/health/check"
if ($health.status -ne "ok") {
Write-Warning "degraded: python=$($health.python) db=$($health.db)"
}
3. Error scenarios
Missing API key
Send:
curl -sS "https://engine.tripod-health.com/api/health/check"
Receive (401):
{
"message": "No API key found in request",
"request_id": "cd27261422d41501f632143b590d7001"
}
Invalid API key
Send:
curl -sS "https://engine.tripod-health.com/api/health/check" \
-H "apikey: bogus-key-xyz"
Receive (401):
{
"message": "Unauthorized",
"request_id": "0b9d7059ece9ec36347c2210e1f48844"
}
401 bodies use a simpler shape than the standard error envelope —
they carry only message and request_id, without error or
timestamp. Clients should branch on the 401 status code, not on a
specific message string. See
authentication.md.
Degraded component
When a component is down, the endpoint returns 503 with a body
matching the success shape but with status: "degraded" and the
unhealthy component reporting "down":
{
"status": "degraded",
"node": "ok",
"python": "down",
"db": "ok",
"consumer": {
"id": "12345678-90ab-cdef-1234-567890abcdef",
"username": "example-consumer"
},
"request_id": "8f2c3b1d-5e4a-4a9c-9b1e-2a7f1d3e4c5b",
"timestamp": "2026-04-21T22:55:25.182Z"
}
Datastore-probe failure
If the datastore probe itself fails, the endpoint returns the standard error envelope instead of the health body above:
{
"timestamp": "2026-04-21T22:55:25.182Z",
"error": "ServiceUnavailable",
"message": "Datastore probe failed",
"request_id": "8f2c3b1d-5e4a-4a9c-9b1e-2a7f1d3e4c5b"
}
Parse the response body and branch on status (for the degraded body)
or on error (for the error envelope). Both carry request_id; both
can arrive as 503.
Intended use
- End-to-end smoke tests. CI pipelines that deploy a dependent service
can block on a
200from this endpoint before promoting a release. - External uptime monitoring. Point a synthetic monitor here with your
API key; alert on anything other than
200. - Incident triage. On-call engineers call this first to confirm the API path is up before digging into business endpoints.
- Per-consumer identity verification. The
consumerblock echoes the identity resolved from your API key — useful when verifying a new key is provisioned against the expected consumer.
Mistaken use
- Do not use
/health(without the/api/prefix) for external health checks. That path is an internal container liveness probe, documented separately, and is not reachable via the public API hostname. - Do not treat
status: "ok"as a guarantee for a specific domain endpoint. It proves the subsystems are reachable; it does not validate any particular scoring algorithm, catalog entry, or input shape. - Do not poll this endpoint at sub-second frequency. It counts against your rate limit like any other authenticated call. Standard uptime-monitor cadence (30–60 seconds) is the expected pattern.
- Do not distinguish
503-degraded from503-datastore by status code alone. Parse the body: the degraded response hasstatus: "degraded"and the component fields (node,python,db); the datastore-probe failure returns the standard error envelope witherror: "ServiceUnavailable".
Debugging
- Capture the
request_id. It is in the response body (success, degraded, or error envelope) and in theX-Request-IDresponse header. Every support ticket about this endpoint starts with it. 401— your API key was rejected. Confirm theapikeyheader is being sent (curl's-Horder matters when piping through proxies) and the key has not been rotated.429 RateLimited— respect theRetry-Afterheader and slow your monitor cadence.503withstatus: "degraded"and a component"down"— a downstream component is unhealthy. Scoring and composite endpoints will fail until it clears. Retry after a short backoff; if it persists, quote therequest_idin a ticket.503witherror: "ServiceUnavailable"— the datastore probe failed. This usually clears on its own within seconds. Persistent failures indicate an incident; quote therequest_id.200but your domain call still fails — this endpoint only verifies component reachability, not the correctness of any specific payload. Check the envelope on the domain call itself;errorandfieldon a400 ValidationErrorusually pinpoint the input problem.
Rate limits
Treat this endpoint like any other authenticated call when choosing monitor cadence. See rate-limits.md.
Related endpoints
GET /health— internal container liveness probe. Not for external use.GET /api/version/get— Trinity build, catalog, and deploy metadata. Useful alongside a health check when verifying a specific deploy.
Change history
| Date | Change |
|---|---|
| 2026-04-20 | Initial publication. |