Skip to main content

Monitor the platform

A monitoring probe built for cron, CI gates, and alerting scripts. It layers the health endpoints (no credentials, no lockout risk) with one authenticated GET /topology call as the key-validity probe, and reports through exit codes:

Exit codeMeaningSuggested action
0Platform healthy, key validNothing.
1Reachable, but a subsystem is degradedPage on sustained failures.
2Platform unreachablePage; check network egress first.
3API key rejected (401)Alert the integration owner; do not auto-retry (lockout risk).

The whole run is 5 requests, well inside the per-IP budget of 30/minute at a one-minute cadence. If several monitors share an egress IP, stagger them. Set CONSTELLATION_API_BASE and CONSTELLATION_API_TOKEN first (common setup).

const BASE = process.env.CONSTELLATION_API_BASE ?? 'https://api.constellation.space'
const TOKEN = process.env.CONSTELLATION_API_TOKEN
if (!TOKEN) {
console.error('CONSTELLATION_API_TOKEN is not set')
process.exit(3)
}

type Health = { status?: string; checks?: Record<string, { ok?: boolean; detail?: string }> }

function isHealthy(body: Health): boolean {
if (body.status !== 'ok') return false
return !Object.values(body.checks ?? {}).some((c) => c.ok === false)
}

async function probe(path: string, headers?: Record<string, string>) {
try {
const res = await fetch(`${BASE}${path}`, { headers, signal: AbortSignal.timeout(8000) })
return { status: res.status, json: (await res.json().catch(() => null)) as Health | null }
} catch {
return { status: 0, json: null }
}
}

// 1. Reachability: /health must answer 200 with a healthy body.
const health = await probe('/health')
if (health.status !== 200 || !health.json || !isHealthy(health.json)) {
console.error(`platform unreachable or unhealthy at ${BASE} (status ${health.status})`)
process.exit(2)
}

// 2. Subsystems: 503 means degraded.
let degraded = false
for (const sub of ['telemetry', 'topology', 'predictions']) {
const res = await probe(`/health/${sub}`)
const ok = res.status === 200 && res.json != null && isHealthy(res.json)
console.log(`${sub}: ${ok ? 'healthy' : `DEGRADED (status ${res.status})`}`)
if (!ok) degraded = true
}

// 3. Key validity: authed topology read with a small window.
const auth = await probe('/topology?freshness_seconds=900', { 'x-api-key': TOKEN })
if (auth.status === 401) {
console.error('API key rejected (401)')
process.exit(3)
}
if (auth.status !== 200) {
console.error(`authenticated probe failed (status ${auth.status})`)
degraded = true
} else {
const tenant = (auth.json as { tenant_key?: string } | null)?.tenant_key ?? 'unknown'
console.log(`auth: ok (tenant ${tenant})`)
}

process.exit(degraded ? 1 : 0)

Expected output on a healthy platform:

telemetry: healthy
topology: healthy
predictions: healthy
auth: ok (tenant acme-sat)

Run the unauthenticated stages as often as every minute; run the authenticated stage at a lower cadence, since it spends tenant rate budget and a misconfigured key feeding stage 3 in a tight loop would trip the auth lockout. For a richer, human-oriented diagnostic of the same flow, see the connection smoke test.