Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.kynesys.xyz/llms.txt

Use this file to discover all available pages before exploring further.

Health and Readiness

A Demos node exposes plain HTTP GET endpoints on its RPC port for operational monitoring. These are unauthenticated, return JSON, and are designed to be polled by load balancers, Kubernetes liveness/readiness probes, and uptime checks. The contract is additive: existing fields are preserved across releases so probes do not break.

GET /health

The primary health endpoint. It aggregates the subsystem registry, the boot tracker, the main-loop heartbeat, and process-level error counters into a single snapshot.

Status semantics

The top-level status field collapses everything into one of four values, with the following precedence (failing wins, then dormant, degraded, ok):
statusMeaningHTTP code
okAll subsystems healthy, main loop alive.200
degradedAt least one non-critical subsystem is failed, but the chain and main loop are alive.200
dormantThe node booted with an empty peer list and intentionally skipped signaling/MCP/TLSNotary/main loop.200
failingThe mempool/DB is unreachable, the chain subsystem failed, or the main loop died (and the node is not dormant).503
Only failing returns HTTP 503. dormant and degraded are intentional states and return 200, so a probe keyed solely on HTTP status will not flap on a node that legitimately has no peers yet.

Headers

  • X-Demos-Dormant: true — added only when status is dormant. Lets an LB route around a node that is up but not yet participating in consensus.

Response fields

FieldTypeNotes
version / version_namestringNode version and codename.
acceptingbooleanTrue when the node is synced and not currently in its sync loop.
mempool_sizenumber | nullPending transaction count. null when Mempool.count() fails (forces status: failing).
uptime_snumberSeconds since process start.
statusstringok | degraded | dormant | failing.
dormantbooleanRaw dormant-mode flag.
bootobjectBoot-step roll-up: complete, steps_total, steps_ready, steps_failed, steps_skipped, current (name of the running step, or null).
subsystemsobjectPer-subsystem snapshot (see below).
portsobjectPer-subsystem { requested, actual, drifted }. drifted is true when the bound port differs from the requested one. Only subsystems with a known port appear.
main_loopobjectheartbeat_age_s (seconds since last tick, or null), iterations_total, exited, exit_reason.
errorsobjectuncaught_total, unhandled_rejection_total, last_uncaught.
Each entry under subsystems is keyed by name (one of chain, rpc, metrics, signaling, mcp, tlsnotary, omni, dtr, l2ps, main_loop) and carries: status (pending | running | ready | failed | skipped | dormant), since (ms timestamp of the last transition or null), port, requestedPort, lastError, enabled, and optional extra.

Sample response

{
  "version": "1.4.2",
  "version_name": "mycelium",
  "accepting": true,
  "mempool_size": 12,
  "uptime_s": 8421,
  "status": "ok",
  "dormant": false,
  "boot": {
    "complete": true,
    "steps_total": 9,
    "steps_ready": 8,
    "steps_failed": 0,
    "steps_skipped": 1,
    "current": null
  },
  "subsystems": {
    "chain": { "status": "ready", "since": 1716800000000, "port": null, "requestedPort": null, "lastError": null, "enabled": true },
    "rpc": { "status": "ready", "since": 1716800000100, "port": 53550, "requestedPort": 53550, "lastError": null, "enabled": true },
    "metrics": { "status": "ready", "since": 1716800000200, "port": 9090, "requestedPort": 9090, "lastError": null, "enabled": true },
    "mcp": { "status": "skipped", "since": 1716800000300, "port": null, "requestedPort": null, "lastError": null, "enabled": false, "extra": { "reason": "MCP disabled" } },
    "main_loop": { "status": "ready", "since": 1716800001000, "port": null, "requestedPort": null, "lastError": null, "enabled": true }
  },
  "ports": {
    "rpc": { "requested": 53550, "actual": 53550, "drifted": false },
    "metrics": { "requested": 9090, "actual": 9090, "drifted": false }
  },
  "main_loop": {
    "heartbeat_age_s": 1,
    "iterations_total": 5821,
    "exited": false,
    "exit_reason": null
  },
  "errors": {
    "uncaught_total": 0,
    "unhandled_rejection_total": 0,
    "last_uncaught": null
  }
}

Probe configuration

A liveness probe should treat any HTTP 503 (i.e. status: failing) as unhealthy. A readiness probe wanting to gate traffic until consensus participation can additionally inspect dormant / the X-Demos-Dormant header or require boot.complete === true.

GET /health/subsystems

A slim sibling for ops dashboards that only need subsystem state. It returns the same subsystems snapshot plus the dormant flag, with a smaller body and no status roll-up:
{
  "dormant": false,
  "subsystems": { "chain": { "status": "ready", "since": 1716800000000 } }
}

GET /info

Returns identity and peering metadata rather than health. Useful for service-discovery and confirming which node answered:
{
  "version": "1.4.2",
  "version_name": "mycelium",
  "identity": "0x<public-key-hex>",
  "connectionString": "http://node.example:53550",
  "peerlist": []
}