MountainSwitch

Developers

Health

Overview

GET

/v1/health

Health

Health is the adapter-status source of truth. Use it to inspect adapter freshness, live aggregation eligibility, and infrastructure health without inferring those states from data endpoints.

Parameters

Path and query parameters are documented together so the request surface stays easy to scan.

This endpoint does not accept path or query parameters.

Example request

Use the same endpoint across all three snippets. The tabs switch only the client syntax.

cURL

curl -sS "https://api-staging.mountainswitch.co/v1/health" \
  -H "Accept: application/json"

Example response

The example response shows the documented JSON envelope with endpoint data in data and request metadata in _meta.

200 OK application/json
{
  "data": {
    "overall": "degraded",
    "adapters": [
      {
        "adapter_id": "ca-chain-controls",
        "jurisdiction": "US-CA",
        "feed_type": "chain-controls",
        "status": "healthy",
        "live_aggregation_eligible": true,
        "last_successful_fetch": "2026-03-19T12:47:00Z",
        "last_attempted_fetch": "2026-03-19T12:47:00Z",
        "consecutive_failures": 0,
        "last_error": null,
        "record_count": 45,
        "average_latency_ms": 340
      },
      {
        "adapter_id": "ca-lane-closures",
        "jurisdiction": "US-CA",
        "feed_type": "lane-closures",
        "status": "stale",
        "live_aggregation_eligible": false,
        "last_successful_fetch": "2026-03-19T12:35:00Z",
        "last_attempted_fetch": "2026-03-19T12:47:00Z",
        "consecutive_failures": 2,
        "last_error": "HTTP 503 from upstream",
        "record_count": 120,
        "average_latency_ms": 890
      }
    ]
  },
  "_meta": {
    "request_id": "req_health_docs",
    "response_generated_at": "2026-03-19T19:47:30Z"
  }
}

Response fields

This reference stays flat on purpose so the documented fields remain easy to scan.

data.overall
"healthy" | "degraded" | "stale" | "down"
Worst status across all adapters in the response.
data.adapters
Array<object>
Registered adapters ordered by adapter_id ascending.
data.adapters[].adapter_id
string
Registered adapter identifier.
data.adapters[].jurisdiction
string
Canonical jurisdiction code owned by the adapter.
data.adapters[].feed_type
string
Registered feed type for the adapter, such as chain-controls or lane-closures.
data.adapters[].status
"healthy" | "degraded" | "stale" | "down"
Request-time effective freshness status after monotonic worsening.
data.adapters[].live_aggregation_eligible
boolean
Authoritative request-time live-aggregation eligibility bit used by list and summary endpoints.
data.adapters[].last_successful_fetch
string | null
Timestamp of the last successful fetch, or null before the first success.
data.adapters[].last_attempted_fetch
string | null
Timestamp of the last attempted fetch, or null before the first attempt.
data.adapters[].consecutive_failures
number
Current consecutive failure count for the adapter.
data.adapters[].last_error
string | null
Last error string for the adapter when one exists.
data.adapters[].record_count
number
Record count reported by the adapter health snapshot.
data.adapters[].average_latency_ms
number | null
Average fetch latency in milliseconds when available.
_meta.request_id
string
Request identifier for debugging and support workflows.
_meta.response_generated_at
string
ISO timestamp describing when the API assembled the response.

Errors

These rows keep the repo-wide rate-limit and infrastructure behavior visible without inventing endpoint-specific transport semantics.

Status Code When it happens
429 RATE_LIMIT_EXCEEDED The caller exceeded the shared API rate limit.
503 SERVICE_UNAVAILABLE D1 or another critical dependency is unavailable.

Notes

These notes capture the contract edges that matter most for consumers of the endpoint.

Health omits coverage and pagination fields

Health is the source of truth for adapter status, so its _meta includes only request_id and response_generated_at. It omits _meta.sources, _meta.query_coverage, and _meta.pagination entirely.

live_aggregation_eligible is authoritative

Clients must not re-derive live aggregation eligibility from status or last_successful_fetch. The API computes live_aggregation_eligible at request time and uses that value directly for list and summary coverage decisions.

Health responses are always no-store

GET /v1/health and GET /v1/health/:adapterId are never written to response KV and must always return Cache-Control: no-store.

Subsection

GET

/v1/health/:adapterId

Health by adapter

Use the single-adapter health endpoint when the caller needs one adapter's effective status, live aggregation eligibility, and bootstrap or missing-health fallback behavior.

Parameters

Path and query parameters are documented together so the request surface stays easy to scan.

adapterId

Path Required

string

Registered adapter identifier such as ca-chain-controls. Unknown identifiers return 404 ADAPTER_NOT_FOUND.

Example request

Use the same endpoint across all three snippets. The tabs switch only the client syntax.

cURL

curl -sS "https://api-staging.mountainswitch.co/v1/health/ca-chain-controls" \
  -H "Accept: application/json"

Example response

The example response shows the documented JSON envelope with endpoint data in data and request metadata in _meta.

200 OK application/json
{
  "data": {
    "adapter_id": "ca-chain-controls",
    "jurisdiction": "US-CA",
    "feed_type": "chain-controls",
    "status": "healthy",
    "live_aggregation_eligible": true,
    "last_successful_fetch": "2026-03-19T12:47:00Z",
    "last_attempted_fetch": "2026-03-19T12:47:00Z",
    "consecutive_failures": 0,
    "last_error": null,
    "record_count": 45,
    "average_latency_ms": 340
  },
  "_meta": {
    "request_id": "req_health_adapter_docs",
    "response_generated_at": "2026-03-19T19:47:30Z"
  }
}

Response fields

This reference stays flat on purpose so the documented fields remain easy to scan.

data.adapter_id
string
Registered adapter identifier for the returned health record.
data.jurisdiction
string
Canonical jurisdiction code owned by the adapter.
data.feed_type
string
Registered feed type for the adapter, such as chain-controls or lane-closures.
data.status
"healthy" | "degraded" | "stale" | "down"
Request-time effective freshness status for the adapter.
data.live_aggregation_eligible
boolean
Authoritative request-time live-aggregation eligibility bit for the adapter.
data.last_successful_fetch
string | null
Timestamp of the last successful fetch, or null before the first success.
data.last_attempted_fetch
string | null
Timestamp of the last attempted fetch, or null before the first attempt.
data.consecutive_failures
number
Current consecutive failure count for the adapter.
data.last_error
string | null
Last error string for the adapter when one exists.
data.record_count
number
Record count reported by the adapter health snapshot.
data.average_latency_ms
number | null
Average fetch latency in milliseconds when available.
_meta.request_id
string
Request identifier for debugging and support workflows.
_meta.response_generated_at
string
ISO timestamp describing when the API assembled the response.

Errors

These rows keep the repo-wide rate-limit and infrastructure behavior visible without inventing endpoint-specific transport semantics.

Status Code When it happens
404 ADAPTER_NOT_FOUND The requested adapterId is not present in the registered adapter registry.
429 RATE_LIMIT_EXCEEDED The caller exceeded the shared API rate limit.
503 SERVICE_UNAVAILABLE D1 or another critical dependency is unavailable.

Notes

These notes capture the contract edges that matter most for consumers of the endpoint.

Single-adapter health uses the same fallback rules

If health:{adapterId} is missing, the API distinguishes true bootstrap from post-boot missing health using lastCompletedCycle:{adapterId}. The response is synthesized but not written back to KV.

The single-adapter shape matches one list entry

GET /v1/health/:adapterId returns the same public AdapterHealthApiSchema used inside GET /v1/health data.adapters[].

Single-adapter health is also no-store

GET /v1/health/:adapterId is not part of the query_coverage cache matrix and must always return Cache-Control: no-store.