Loading documentation

Access required

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

Sign out
Skip to main content

Model Service Health

Status: stable Category: model_services Added: 2026-06-24 Last reviewed: 2026-06-24

Summary​

Reports the health of every model the engine offers. A single authenticated call returns one status per model -- ok, unreachable, or unconfigured -- so a status page or monitor can show the engine's model fleet at a glance. The engine checks each model on your behalf; you pass no model name, body, or list.

Endpoint​

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

Purpose​

The engine offers a catalog of models it can run as part of its analytics. Those models are not directly reachable by callers -- only the engine can reach them. This endpoint is the supported way to see whether they are healthy: the engine reads its own model catalog, checks each entry, and returns the collected result.

It is the model-fleet counterpart to the API health check. Use the API health check to answer "is the engine itself up?"; use this endpoint to answer "are the engine's models available?".

Authentication​

Send a valid API key in the apikey header. A missing or unknown key returns 401 Unauthenticated before the request reaches this endpoint. See authentication.

Request​

Headers​

HeaderRequiredDescription
apikeyYesConsumer API key.

Path / query parameters​

None. The model list is server-side knowledge; you do not select which models to check.

Body​

None. Any body on a GET request is ignored.

Response​

Success — 200 OK​

Returned whenever the engine can read its model catalog, regardless of whether individual models are healthy. Per-model problems are reported inside the list, not as a non-200 status.

{
"services": [
{ "name": "model_a", "status": "ok", "latency_ms": 38 },
{ "name": "model_b", "status": "unreachable", "latency_ms": 4002 },
{ "name": "model_c", "status": "unconfigured", "latency_ms": null }
],
"checked_at": "2026-06-24T17:32:10.812Z"
}

The model names above are illustrative. The list reflects whatever models the engine currently publishes, in catalog order; treat the set as dynamic rather than hard-coding it.

Response fields​

FieldTypeAlways presentDescription
servicesarrayYesOne entry per model in the engine's catalog. Empty array if the catalog lists no models.
services[].namestringYesThe model's identifier, stable across calls.
services[].statusstringYesOne of "ok", "unreachable", or "unconfigured" (see below).
services[].latency_msinteger | nullYesRound-trip time of the health check in milliseconds, or null when no response was measured (unconfigured, or a check that never completed).
checked_atstring (ISO 8601 UTC)YesServer timestamp when the checks were run.

Status values​

ValueMeaning
okThe model responded healthy within the check window.
unreachableThe model is configured for traffic but did not report healthy -- it timed out or returned an error. Treat as a model-side problem.
unconfiguredThe model is listed in the engine's catalog but is not currently wired for traffic. This is not an error -- the model simply is not available yet.

Status codes​

CodeMeaningWhen
200OKThe catalog was read and per-model results returned. Individual models may still be unreachable or unconfigured.
401UnauthenticatedMissing or invalid API key.
402PaymentRequiredAccount or key credit balance exhausted. See credits.
404NotFoundWrong path or method. GET /api/model_services/health is the only supported form.
429RateLimitedPer-consumer rate limit exceeded. See Retry-After.
503ServiceUnavailableThe engine could not read its model catalog. The standard error envelope is returned, not the health body.
5xx (other)VariesUnexpected failure. request_id identifies the call in server logs.

Error envelope​

Non-200 responses (other than the gateway 401) use the standard error envelope:

{
"timestamp": "2026-06-24T17:32:10.812Z",
"error": "ServiceUnavailable",
"message": "Model catalog is temporarily unavailable",
"request_id": "8f2c3b1d-5e4a-4a9c-9b1e-2a7f1d3e4c5b"
}

See errors for the full code list and envelope extras.

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 reuse it.

1. Canonical request and response​

Send:

GET /api/model_services/health HTTP/1.1
Host: engine.tripod-health.com
apikey: $ENGINE_API_KEY

Receive (200 OK):

{
"services": [
{ "name": "model_a", "status": "ok", "latency_ms": 38 },
{ "name": "model_b", "status": "unreachable", "latency_ms": 4002 },
{ "name": "model_c", "status": "unconfigured", "latency_ms": null }
],
"checked_at": "2026-06-24T17:32:10.812Z"
}

2. Calling the endpoint in your language​

curl​

curl -sS "https://engine.tripod-health.com/api/model_services/health" \
-H "apikey: $ENGINE_API_KEY"

Python (requests)​

# Uses the call() helper from quickstart.md.
fleet = call("GET", "/api/model_services/health")
unhealthy = [s["name"] for s in fleet["services"] if s["status"] == "unreachable"]
if unhealthy:
print("unreachable models:", ", ".join(unhealthy))
else:
print("all configured models healthy")

Node.js (native fetch)​

// Uses the call() helper from quickstart.md.
const fleet = await call("GET", "/api/model_services/health");
const unreachable = fleet.services.filter((s) => s.status === "unreachable");
if (unreachable.length > 0) {
console.warn("unreachable models:", unreachable.map((s) => s.name).join(", "));
}

TypeScript​

// Uses the typed call<T>() helper from quickstart.md.
interface ModelStatus {
name: string;
status: "ok" | "unreachable" | "unconfigured";
latency_ms: number | null;
}
interface FleetHealth {
services: ModelStatus[];
checked_at: string;
}

const fleet = await call<FleetHealth>("GET", "/api/model_services/health");
const degraded = fleet.services.some((s) => s.status === "unreachable");
if (degraded) {
throw new Error("one or more models are unreachable");
}

PowerShell​

# Uses the Invoke-Engine helper from quickstart.md.
$fleet = Invoke-Engine -Method Get -Path "/api/model_services/health"
$down = $fleet.services | Where-Object { $_.status -eq "unreachable" }
if ($down) {
Write-Warning "unreachable models: $(($down | ForEach-Object { $_.name }) -join ', ')"
}

3. Error scenarios​

Missing API key​

curl -sS "https://engine.tripod-health.com/api/model_services/health"

Receive (401):

{
"message": "No API key found in request",
"request_id": "cd27261422d41501f632143b590d7001"
}

401 bodies carry only message and request_id, not the full error envelope. Branch on the status code, not the message string. See authentication.md.

Catalog unavailable​

If the engine cannot read its model catalog, it returns the standard error envelope instead of the health body:

{
"timestamp": "2026-06-24T17:32:10.812Z",
"error": "ServiceUnavailable",
"message": "Model catalog is temporarily unavailable",
"request_id": "8f2c3b1d-5e4a-4a9c-9b1e-2a7f1d3e4c5b"
}

Distinguish this from a healthy response with degraded models: a 200 always carries the services array; a 503 carries error. Only the 503 includes request_id.

Intended use​

  • Status pages. Surface per-model status on an operational dashboard. Each entry maps directly to a row.
  • Fleet monitoring. Alert when a model that is normally ok flips to unreachable.
  • Pre-flight checks. Before a batch that relies on a specific model, confirm that model reports ok.

Mistaken use​

  • Do not use this to check whether the engine itself is up. It reports model availability, not API-path health. Use the API health check for that.
  • Do not treat unconfigured as an outage. It means the model is not wired for traffic yet, not that it failed. Only unreachable indicates a problem with a model that is supposed to be serving.
  • Do not expect a top-level health field. There is no overall rollup; derive fleet health by inspecting each entry's status.
  • Do not select a model with query parameters. The engine always checks its full catalog; there is no per-model variant of this call.
  • Do not poll 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.

Debugging​

  1. Capture the request_id from the error envelope. A 200 body has none, nor does a response with no body from the engine; capture the X-Request-ID response header (the gateway's trace ID) for those. Every support ticket starts here.
  2. 401 — your API key was rejected. Confirm the apikey header is present and the key has not been rotated.
  3. 402 PaymentRequired — the account or key is out of credits. See credits.
  4. 429 RateLimited — respect the Retry-After header and slow your cadence.
  5. A model shows unreachable — the model is configured but not answering. This is a model-side condition; retry after a short backoff. If it persists, quote the request_id and the model name in a ticket.
  6. A model shows unconfigured — expected for models not yet wired for traffic. No action needed.
  7. 503 ServiceUnavailable — the engine could not read its model catalog. Usually transient; retry with backoff and quote the request_id if it persists.

Rate limits​

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

Change history​

DateChange
2026-06-24Initial publication.
2026-10-14The engine assigns every request ID; an X-Request-ID request header is not used. The X-Request-ID response header is the gateway's trace ID for the request and does not match request_id; quote request_id to support.