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.
X-Request-IDNoOptional client-generated correlation ID, up to 128 characters. If omitted, one is generated and returned in the X-Request-ID response header.

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
X-Request-ID: docs-model-health-canonical

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. Both include 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. It is in the error envelope and in the X-Request-ID response header. 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.