Loading documentation

Access required

Your account doesn't have access to the documentation. Contact your administrator.

Sign out
Skip to main content

API Health Check

Status: stable Category: infrastructure Added: 2026-04-20 Last 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

FieldValue
MethodGET
Path/api/health/check
Full URLhttps://engine.tripod-health.com/api/health/check
AuthenticationAPI key (required)
Request bodynone
Response bodyapplication/json
IdempotentYes
Rate-limitedYes

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

HeaderRequiredDescription
apikeyYesConsumer API key.
X-Request-IDNoOptional 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

FieldTypeAlways presentDescription
statusstringYes"ok" if every component is healthy; "degraded" if at least one is down.
nodestringYesComponent-status flag. Always "ok" when you receive this body — a response implies this component is answering.
pythonstringYesComponent-status flag. When "down", scoring and composite endpoints will fail until it clears.
dbstringYesDatastore 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.idstring | nullYesConsumer identifier derived from your API key. Useful for confirming you are calling as the consumer you expect.
consumer.usernamestring | nullYesHuman-readable consumer name.
request_idstringYesCorrelation ID for this request. Quote this in support tickets.
timestampstring (ISO 8601 UTC)YesServer 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

CodeMeaningWhen
200OKAll checked components are healthy.
401UnauthenticatedMissing or invalid API key.
404NotFoundWrong path or method. GET /api/health/check is the only supported form.
429RateLimitedPer-consumer rate limit exceeded. See Retry-After.
503 (health body)DegradedA component is down. Body shape matches the success example with status: "degraded".
503 (error envelope)ServiceUnavailableDatastore probe failed. Body is the standard error envelope.
5xx (other)VariesUnexpected 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 200 from 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 consumer block 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 from 503-datastore by status code alone. Parse the body: the degraded response has status: "degraded" and the component fields (node, python, db); the datastore-probe failure returns the standard error envelope with error: "ServiceUnavailable".

Debugging

  1. Capture the request_id. It is in the response body (success, degraded, or error envelope) and in the X-Request-ID response header. Every support ticket about this endpoint starts with it.
  2. 401 — your API key was rejected. Confirm the apikey header is being sent (curl's -H order matters when piping through proxies) and the key has not been rotated.
  3. 429 RateLimited — respect the Retry-After header and slow your monitor cadence.
  4. 503 with status: "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 the request_id in a ticket.
  5. 503 with error: "ServiceUnavailable" — the datastore probe failed. This usually clears on its own within seconds. Persistent failures indicate an incident; quote the request_id.
  6. 200 but 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; error and field on a 400 ValidationError usually pinpoint the input problem.

Rate limits

Treat this endpoint like any other authenticated call when choosing monitor cadence. See rate-limits.md.

  • 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

DateChange
2026-04-20Initial publication.