---
title: "Health"
description: "2 operations under /v1/health (GET): parameters, status codes, refusal bodies, and the same request in curl, HTTP, Python and TypeScript."
---

Base URL: `https://api.codespar.dev`

Every operation below requires a Bearer token. See [Authentication](/docs/concepts/authentication).

### GET `/v1/health`

<Endpoint method="GET" path="/v1/health" base="https://api.codespar.dev" />

Read graded dependency health, as this credential's tenant sees it

Dependency checks and the schema version, graded into one `status`. The checks run in parallel behind a three-second budget each; one that throws or times out is reported in its own failed shape with `message` carrying the reason, and the response still carries the others. So the operation is expected back in under four seconds however badly the database is behaving.

EVERY CHECK SAYS WHAT IT MEASURED AND WHAT THAT MEANS HERE. Its own `status` keeps its vocabulary; beside it, `state` separates a real failure from pending configuration, from no activity, and from a feature not in use, with `required`, a `reason` code and, where something has to be set up, an `action`. A new account with no integration, no provider call and no FX quote reads `healthy`, with `connections` pending configuration.

GRADE ON `status`, AND READ THE RULE BEFORE WRITING THE ALERT. Only `state: failure` grades. `down` means `db` or `vault` fails. `degraded` means any other check fails, which today is one of: the tool catalog is not loaded (`tool_catalog`), a USD/BRL quote the router needs is missing, stale or unreadable (`fx_rates`; no deployment needs one until the router normalizes cost across currencies, and until then the quote is `not_in_use` whatever its age), a live Celcoin connection lacks a webhook subscription (`celcoin_webhook_subscriptions`), or a Pix Automático worker with work to do is stale, failing or never ran (`recurrence_holds`, `recurrence_scheduler`, including a hold past its time), or a BolePix paid twice has had its refund owed for longer than 3 days (`bolepix_refunds`). Everything else grades `healthy`. `attention` lists the failing checks and the ones pending configuration by name.

`metrics` IS READ, NEVER GRADED. `metrics.recurrence_instruction_alarms` counts the Pix Automático instruction alarms still open on a cycle still ahead, per kind and reason, for the calling org: a cycle not announced, an instruction refused, held back by a ceiling, or queued and expired. Each alarm already reached its tenant as an event in the recurrence's project; this is the standing number, and it never moves `status`.

NON-NOMINAL MEASUREMENTS THAT DO NOT MOVE THE GRADE, and an alert that wants them has to read the field rather than the grade: `embeddings.status` `low` or `empty` (discovery answers from its keyword fallback), `connections.status` `partial` or `none`, `telemetry.status` `idle` or `stale` (no provider call is no activity, not a fault), and `fx_rates.status` `stale` or `missing` while no quote is needed. None of them stops a call from being served.

ONLY HALF OF ONE CHECK IS PER TENANT. `connections.connected` counts connections in the calling credential's own org and project. `connections.total_servers` counts every active provider in the catalog and is the same number for every reader, so the ratio between them is not a tenant completion percentage.

THIS READ WRITES, and the write is observable. Each call stores a snapshot of its own result against the calling org, and when the grade differs from the previous snapshot's it publishes `system.health.degraded` or `system.health.recovered` into the calling project, carrying a field-by-field diff of what moved. Anything subscribed to those event types in that project fires. Polling this endpoint therefore has side effects, and two monitors polling the same org write into one shared snapshot history — a transition either of them causes is seen once, by whoever's call crossed it. Where the 30-day history is switched on, each call also counts one observation in `GET /v1/health/history` for the calling org, so a monitor polling this endpoint moves that history too.

THE HANDLER ANSWERS 200 FOR EVERY STATE IT GRADES, `down` included: a dead dependency is reported in the body and never mapped onto an HTTP status. That is why the map below has one entry. It is not a promise that nothing else can come back. Three things produce a non-200 here and none of them is a grade: a credential that does not authenticate, a credential whose grants do not cover this read — both refused before the handler runs, and neither described in the map below, because the answer to them is the same on every operation the same door guards — and a refusal of the snapshot write above, which is a defect on our side rather than a dependency being down. Alert on `status`. A non-200 is a bug report, and which of the three it is decides who should be reading it.

**Responses**

| Status | Body | Description |
|---|---|---|
| `200` | object | OK |

**Response `200`**

| Field | Type | Required | Description |
|---|---|---|---|
| `attention` | object | yes | — |
| `checks` | object | yes | — |
| `metrics` | object | yes | — |
| `observed_at` | `string (date-time)` | yes | When this call built the response. It is also the snapshot key, so two calls landing in the same instant store one row. |
| `schema_version` | object | yes | — |
| `status` | `"healthy"` \| `"degraded"` \| `"down"` | yes | `down` iff the database or the vault fails. `degraded` iff any other check has `state: failure`. `healthy` otherwise, including every pending configuration, no activity and feature not in use. |

<Split min={380}>
<SplitPane label="Example request">

<Tabs items={["curl","HTTP","Python","TypeScript","SDK"]}>
<Tab value="curl">

```bash
curl -X GET https://api.codespar.dev/v1/health \
  -H "Authorization: Bearer $CODESPAR_API_KEY"
```

</Tab>
<Tab value="HTTP">

```http
GET /v1/health HTTP/1.1
Host: api.codespar.dev
Authorization: Bearer $CODESPAR_API_KEY
```

</Tab>
<Tab value="Python">

```python
import os
import requests

res = requests.get(
    "https://api.codespar.dev/v1/health",
    headers={"Authorization": f"Bearer {os.environ['CODESPAR_API_KEY']}"},
)
res.raise_for_status()
data = res.json()
```

</Tab>
<Tab value="TypeScript">

```ts
const res = await fetch("https://api.codespar.dev/v1/health", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
  },
});

const data = await res.json();
```

</Tab>
<Tab value="SDK">

```ts
const result = await cs.api.get("/v1/health");
```

</Tab>
</Tabs>

</SplitPane>
<SplitPane label="Example response 200">

```json title="application/json"
{
  "status": "healthy",
  "attention": {
    "failures": [
      "string"
    ],
    "pending_configuration": [
      "string"
    ]
  },
  "checks": {
    "db": {
      "ok": true,
      "message": "string",
      "latency_ms": 0,
      "state": "healthy",
      "required": true,
      "reason": "string",
      "action": {
        "code": "connect_integration",
        "owner": "account"
      }
    },
    "vault": {
      "ok": true,
      "message": "string",
      "state": "healthy",
      "required": true,
      "reason": "string",
      "action": {
        "code": "connect_integration",
        "owner": "account"
      }
    },
    "tool_catalog": {
      "tools": 0,
      "message": "string",
      "state": "healthy",
      "required": true,
      "reason": "string",
      "action": {
        "code": "connect_integration",
        "owner": "account"
      }
    },
    "embeddings": {
      "populated": 0,
      "total": 0,
      "percent": 0,
      "status": "ok",
      "message": "string",
      "state": "healthy",
      "required": true,
      "reason": "string",
      "action": {
        "code": "connect_integration",
        "owner": "account"
      }
    },
    "fx_rates": {
      "last_fetched_at": "2026-01-15T12:00:00.000Z",
      "hours_old": 0,
      "status": "usable",
      "message": "string",
      "state": "healthy",
      "required": true,
      "reason": "string",
      "action": {
        "code": "connect_integration",
        "owner": "account"
      }
    },
    "telemetry": {
      "last_hour_attempts": 0,
      "last_24h_attempts": 0,
      "status": "active",
      "message": "string",
      "state": "healthy",
      "required": true,
      "reason": "string",
      "action": {
        "code": "connect_integration",
        "owner": "account"
      }
    },
    "connections": {
      "connected": 0,
      "total_servers": 0,
      "status": "wired",
      "message": "string",
      "state": "healthy",
      "required": true,
      "reason": "string",
      "action": {
        "code": "connect_integration",
        "owner": "account"
      }
    }
  },
  "metrics": {
    "recurrence_instruction_alarms": {
      "status": "ok",
      "open": 0,
      "kinds": {},
      "message": "string"
    }
  },
  "schema_version": {
    "latest": "string",
    "applied_at": "2026-01-15T12:00:00.000Z"
  },
  "observed_at": "2026-01-15T12:00:00.000Z"
}
```

</SplitPane>
</Split>

<TryIt method="GET" path="/v1/health" />

### GET `/v1/health/history`

<Endpoint method="GET" path="/v1/health/history" base="https://api.codespar.dev" />

Read the per-day share of ok health observations of each check, for the caller's organization

One point per Sao Paulo calendar day for every check of `GET /v1/health` and for its grade (`overall`), over the last `days` days (1 to 30, default 30) ending today. A point is `ok_share`, the share of that day's health observations in which the check was not in `state: failure` (for `overall`, in which `status` was `healthy`), and `samples`, how many observations there were. `uptime` is a deprecated alias of `ok_share` with the same value, served for one release cycle; read `ok_share`. `first_sampled_day` is the earliest day of the window with an observation.

AN OBSERVATION IS A STORED SNAPSHOT: each authenticated `GET /v1/health` call (so `GET /v1/health` writes, it is not read-only, and an open dashboard tab polls it every 30 seconds) and each pass of the server-side health scraper for the org (every 5 minutes). So `ok_share` is a share of observations, not of time: it is not uptime or availability, and a day with a dashboard open weighs its hours unevenly; read `samples` beside it. A day with no observation is ABSENT from the series, never reported as 100% or 0%. Configuration pending, no activity and a feature not in use count as ok, as they do not move the grade.

Organization-wide, like the snapshots it is built from: the two per-tenant checks were measured for the project of each observation. Same credential and grant as `GET /v1/health`.

**Query parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `days` | `integer` | no | — |

**Responses**

| Status | Body | Description |
|---|---|---|
| `200` | object | OK |
| `400` | object | `days` is not an integer from 1 to 30. |

**Response `200`**

| Field | Type | Required | Description |
|---|---|---|---|
| `checks` | object | yes | Per check of the health body (db, vault, tool_catalog, connections, ...), the days with at least one observation, oldest first. A check never observed in the window is absent. A sample is ok unless the check's `state` was `failure`. |
| `days` | `integer` | yes | — |
| `first_sampled_day` | `string,null` | yes | The earliest day of this window with at least one observation, YYYY-MM-DD, or null when the window has none. Observation of this organization started on this day, unless it equals `from`, in which case it may have started before the window. |
| `from` | `string` | yes | First Sao Paulo day of the window, YYYY-MM-DD. |
| `overall` | array of object | yes | The response's grade per day: a sample is ok when `status` was `healthy`. Days with no observation are absent. |
| `to` | `string` | yes | Today in Sao Paulo, YYYY-MM-DD. |

<Split min={380}>
<SplitPane label="Example request">

<Tabs items={["curl","HTTP","Python","TypeScript","SDK"]}>
<Tab value="curl">

```bash
curl -X GET https://api.codespar.dev/v1/health/history \
  -H "Authorization: Bearer $CODESPAR_API_KEY"
```

</Tab>
<Tab value="HTTP">

```http
GET /v1/health/history HTTP/1.1
Host: api.codespar.dev
Authorization: Bearer $CODESPAR_API_KEY
```

</Tab>
<Tab value="Python">

```python
import os
import requests

res = requests.get(
    "https://api.codespar.dev/v1/health/history",
    headers={"Authorization": f"Bearer {os.environ['CODESPAR_API_KEY']}"},
)
res.raise_for_status()
data = res.json()
```

</Tab>
<Tab value="TypeScript">

```ts
const res = await fetch("https://api.codespar.dev/v1/health/history", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
  },
});

const data = await res.json();
```

</Tab>
<Tab value="SDK">

```ts
const result = await cs.api.get("/v1/health/history");
```

</Tab>
</Tabs>

</SplitPane>
<SplitPane label="Example response 200">

```json title="application/json"
{
  "days": 0,
  "from": "string",
  "to": "string",
  "first_sampled_day": "string",
  "checks": {},
  "overall": [
    {
      "day": "string",
      "ok_share": 0,
      "samples": 0,
      "uptime": 0
    }
  ]
}
```

</SplitPane>
</Split>

<TryIt method="GET" path="/v1/health/history" />

