---
title: "GET /api/v1/self-health"
method: GET
path: "/api/v1/self-health"
tags: ["health"]
---

# GET /api/v1/self-health

`GET /api/v1/self-health`

## Request

- Base URL: `https://api.metagraph.sh`
- URL: `https://api.metagraph.sh/api/v1/self-health`
- Auth: none required

metagraphed's OWN uptime: a verdict scoped strictly to our own components (api / site / publish) plus each one's trailing-90-day daily uptime ratios and latest probe state, served from the self_health_daily lakehouse rollup at /api/v1/self-health (no static file). Days with no probe rows are ABSENT, never zero-filled -- a gap means we weren't measuring, not that we were down. Never mixes in third-party subnet-surface health, which is what /api/v1/health covers. The per-component current_ok/http_status/latency_ms/checked_at/note fields are NULL for now, and null here means UNMEASURED, not down: the per-check ticks were written by the indexer box's self-health poller, the box is decommissioned, and only the daily rollup survived it. Synthesizing a current reading from the last frozen tick would state a probe we did not take.

## Response `200`

Canonical artifact wrapped in the Metagraphed API envelope.

- object
  - `data` object, required: metagraphed's own uptime verdict (#8422). Mirrors GET /api/v1/self-health.
    - `components` SelfHealthComponent[], required
      - `checked_at` string, nullable, required
      - `component` string, required
      - `current_ok` boolean, nullable, required: Null when the component has never been probed -- NOT false.
      - `days` SelfHealthDay[], required: Trailing-90d daily ratios, oldest first; gaps are absent, never zero-filled.
        - `checks` integer, required
        - `day` string, required
        - `ok_count` integer, required
        - `uptime_ratio` number, required: ok_count / checks, 0..1.
      - `http_status` integer, nullable, required
      - `latency_ms` integer, required: A duration in milliseconds. Published as Float in GraphQL: a span past 24.8 days exceeds the 32-bit range of GraphQL's Int.
      - `note` string, nullable, required: Qualifies a false current_ok with why, for non-HTTP failure modes. Null when there's nothing to add.
      - `uptime_90d` number, nullable, required: Mean uptime across the days we actually have. Null when there are none.
    - `lanes` SelfHealthLane[], required
      - `age_ms` integer, required: A duration in milliseconds. Published as Float in GraphQL: a span past 24.8 days exceeds the 32-bit range of GraphQL's Int.
      - `checked_at` string, nullable, required
      - `detail` string, nullable, required
      - `lane` string, required
      - `verdict` 'ok' | 'stale' | 'unknown', required
    - `measured_component_count` integer, required: Components with data. Zero means the poller hasn't written anything yet.
    - `observed_at` string, nullable, required
    - `schema_version` integer, required
    - `stale_lane_count` integer, required
    - `verdict` 'operational' | 'degraded' | 'outage', required: operational | degraded | outage.
  - `meta` ResponseMeta, required
    - `artifact_path` string
    - `cache` 'short' | 'standard' | 'static'
    - `catalog_paging` object
      - `reason` 'catalog_changed' | 'catalog_budget_exceeded' | 'catalog_unavailable', required
    - `contract_version` string, required
    - `generated_at` string, nullable: Deterministic build content marker (epoch by default); not a wall clock. Use published_at for human-facing freshness.
    - `observed_through` string, date-time, nullable: How far the tier that answered this request has observed at all. A payload reporting no activity at or before this time is a measured absence; one whose subject is newer is outside coverage, not empty. Null when the horizon is unreadable.
    - `pagination` PaginationMeta
      - `collection` string, required
      - `cursor` integer, required
      - `limit` integer, required
      - `next_cursor` integer, nullable, required
      - `order` 'asc' | 'desc'
      - `returned` integer, required
      - `snapshot` string: Present only for page_snapshot paging. Echo as page_snapshot on subsequent pages; a changed collection or query requires a restart.
      - `sort` string, nullable
      - `total` integer, required
    - `published_at` string, date-time, nullable: Real publish time from the KV latest pointer, distinct from generated_at. Null before the first publish or when the control KV is unbound.
    - `source` string
    - `stale_contract` object: Present ONLY when the served artifact was built under an older contract than the live one (serve-time drift, #1001) — the body may predate a schema change. Mirrored on the x-metagraph-stale-contract response header for monitoring.
      - `built_under` string, required: Contract version the served artifact was built under.
      - `live` string, required: Current (live) contract version the Worker is running.
  - `ok` true, required
  - `schema_version` 1, required

## Other responses

- `304`: ETag matched and the cached response is still valid.
- `400`: Query parameters were malformed or unsupported.
- `404`: Artifact or API route was not found.
- `405`: HTTP method is not supported.
- `500`: Unexpected backend error.

---

[API](https://skmtc.dev/metagraph/apis/metagraphed-api.md) · [All operations](https://skmtc.dev/metagraph/apis/metagraphed-api/llms.txt) · [OpenAPI document](https://skmtc.dev/metagraph/apis/metagraphed-api/revisions/e29036024bb1?raw)
