Skip to main content

Health

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

6 min read
View MarkdownEdit on GitHub

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

Every operation below requires a Bearer token. See Authentication.

GET /v1/health

GEThttps://api.codespar.dev/v1/health

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

StatusBodyDescription
200objectOK

Response 200

FieldTypeRequiredDescription
attentionobjectyes—
checksobjectyes—
metricsobjectyes—
observed_atstring (date-time)yesWhen this call built the response. It is also the snapshot key, so two calls landing in the same instant store one row.
schema_versionobjectyes—
status"healthy" | "degraded" | "down"yesdown 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.
Example request
curl -X GET https://api.codespar.dev/v1/health \
  -H "Authorization: Bearer $CODESPAR_API_KEY"
GET /v1/health HTTP/1.1
Host: api.codespar.dev
Authorization: Bearer $CODESPAR_API_KEY
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()
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();
const result = await cs.api.get("/v1/health");
Example response 200
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"
}

GET /v1/health/history

GEThttps://api.codespar.dev/v1/health/history

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

NameTypeRequiredDescription
daysintegerno—

Responses

StatusBodyDescription
200objectOK
400objectdays is not an integer from 1 to 30.

Response 200

FieldTypeRequiredDescription
checksobjectyesPer 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.
daysintegeryes—
first_sampled_daystring,nullyesThe 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.
fromstringyesFirst Sao Paulo day of the window, YYYY-MM-DD.
overallarray of objectyesThe response's grade per day: a sample is ok when status was healthy. Days with no observation are absent.
tostringyesToday in Sao Paulo, YYYY-MM-DD.
Example request
curl -X GET https://api.codespar.dev/v1/health/history \
  -H "Authorization: Bearer $CODESPAR_API_KEY"
GET /v1/health/history HTTP/1.1
Host: api.codespar.dev
Authorization: Bearer $CODESPAR_API_KEY
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()
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();
const result = await cs.api.get("/v1/health/history");
Example response 200
application/json
{
  "days": 0,
  "from": "string",
  "to": "string",
  "first_sampled_day": "string",
  "checks": {},
  "overall": [
    {
      "day": "string",
      "ok_share": 0,
      "samples": 0,
      "uptime": 0
    }
  ]
}
Health | CodeSpar