Sign Up

System

GET
/config

Unauthenticated bootstrap for every client that must discover the deployment before it can log in: the dashboard (OIDC parameters, PostHog, forced feature flags) and the daytona CLI (oidc.cli_client_id, the SSH gateway, api_url). Documented so those clients decode it through the generated contract types (PLAN-CLI.md D19); the body is assembled once from the environment at process start and never changes.

Response Body

Runtime configuration of this deployment

application/json
  1. response

The /config response body.

analytics_url?|

Public base URL of the rlp-analytics spending service (PLAN-ANALYTICS-SERVICE.md), set by the operator and trimmed of a trailing slash. null when unset — or when the value is not an http(s)://host[:port][/path] base (see analytics_base_url) — the dashboard then shows no spending analytics. The URL itself is published (unlike the billing service's) because the browser calls rlp-analytics directly, with its own bearer; the dashboard passes it through safeUrl like toolbox_url.

api_url?|

Public base URL of this API when the deployment advertises one.

billing_enabled*boolean

Whether the member-facing billing surface is wired (PLAN-BILLING-WALLET.md). A boolean rather than the URL because the browser never talks to rlp-billing directly (D1) — it only needs to know whether to render Billing.

build_sha*string

Full commit SHA this API was built from; unknown when unstamped.

build_time*string

RFC 3339 UTC instant the build ran, for example 2026-10-02T14:03:11Z; unknown when unstamped.

docs_url?|

Public documentation site URL for this deployment.

featureFlags?null|
oidc?null|
posthog?null|
ssh_gateway?null|
toolbox_url?|

Toolbox proxy base URL the browser should use. A deployment-specific browser override wins over the general proxy URL when both are set.

version*string

Platform version this API was built as (PLAN-BUILD-IDENTITY.md): the latest published release, for example 2.0.0-alpha.1; 0.0.0-dev for an unstamped build. The same value GET /health reports.

curl -X GET 'https://example.com/config'
{  "analytics_url": "string",  "api_url": "string",  "billing_enabled": true,  "build_sha": "string",  "build_time": "string",  "docs_url": "string",  "featureFlags": null,  "oidc": null,  "posthog": null,  "ssh_gateway": null,  "toolbox_url": "string",  "version": "string"}
GET
/health

Response Body

API, database, and schema are up

application/json
  1. response

GET /health liveness body. Beside the probe result it carries the build identity of the answering process (PLAN-BUILD-IDENTITY.md): the same three values GET /config publishes, so a stack's version can be read from the unauthenticated probe alone.

build_sha*string

Full commit SHA this binary was built from; unknown when unstamped.

build_time*string

RFC 3339 UTC instant the build ran; unknown when unstamped.

status*string
version*string

Platform version this binary was built as (the latest published release); 0.0.0-dev for an unstamped build.

curl -X GET 'https://example.com/health'
{  "build_sha": "string",  "build_time": "string",  "status": "string",  "version": "string"}
GET
/health/deep

Response Body

JetStream answered the probe (status may still be warn on retention-drift alarms)

application/json
  1. response

GET /health/deep readiness body: JetStream probe result plus the wedge/shed observability counters (PLAN-NATS-HYGIENE, PLAN-OVERLOAD-SHEDDING, PLAN-SELF-CORDON-DEADLOCK, PLAN-JETSTREAM-CRITICAL-ONLY).

consecutive_publish_timeouts*integer
Formatint64
Range0 <= value
consecutive_slow_publishes*integer
Formatint64
Range0 <= value
create_stuck_pending_failures*integer

Total creates the create-expiry reaper (events::maintenance) has ever deleted before they reached running. Historical field name kept so the health surface stays stable; a nonzero rate means creates are timing out before becoming live right now.

Formatint64
Range0 <= value
db*string

ok | unhealthy (migration ledger missing or empty) — the same DB/migration probe /health runs, now also covered here (found by review, 2026-08-25: previously absent). Draining is reported only in the outer status field, never here — this field reflects the DB probe alone, so it stays ok even while draining if the DB itself is fine (cubic review, 2026-08-27: the field never actually emits a "degraded" value). Probed concurrently with nats (PLAN-HEALTH-LIVENESS.md) — neither should wait on the other, and a wedged one must not delay reporting the other's real state.

jobs_consumer_ack_pending*integer

Fleet-wide JetStream consumer health, summed across every consumer on the JOBS stream (2026-08-27): distinguishes "queue is deep because load is high" from "queue is deep because runners have stopped acking" — no other signal here made that distinction before.

Formatint64
Range0 <= value
jobs_consumer_pending*integer
Formatint64
Range0 <= value
jobs_consumer_redelivered*integer
Formatint64
Range0 <= value
jobs_consumer_waiting*integer
Formatint64
Range0 <= value
last_publish_ms*integer
Formatint64
Range0 <= value
max_queued_creates*integer
Formatint64
Range0 <= value
nats*string

ok when JetStream answered the bounded $JS.API.INFO probe.

otel*string

OTel pipeline state.

publish_timeouts*integer
Formatint64
Range0 <= value
queued_creates*integer
Formatint64
Range0 <= value
reaper_herd_guard_trips*integer

Reaper ticks (cumulative, this process) on which the herd guard refused to mark runners lost because EVERY online runner was stale at once — an observer/transport outage signature, not fleet death (issue #1205). Nonzero and climbing means the api can hear NATS but no runner heartbeat is arriving: check the bus, the runners' NATS connectivity, and the runner herd-guard threshold configuration.

Formatint64
Range0 <= value
reaper_lost_mark_gate*string

Whether the reaper is currently allowed to mark runners lost from last_seen_at staleness (issue #1205): unbound (the heartbeat lane is not consuming — nothing refreshes last_seen_at), settling (it (re)bound less than one stale window ago; lost-marking is suppressed until the runners have heartbeated through the new subscription) or armed. A process that stays unbound/settling for minutes has a wedged or flapping runner-event lane.

redis*string

Rate-limit Redis state (PLAN-AUTH-RATE-LIMITS.md §2.6): ok | degraded (PING failed/timed out — brute-force protection is silently off, fail-open) | unconfigured (rate-limit storage disabled on this deployment). Never flips the overall status — the limiter fails open by design.

retention_alarms*array<string>

Managed streams whose retention config drifted from desired. Non-empty is the alarm that was missing during both retention-drift incidents.

self_cordoned_runners*integer
Formatint64
shedding*boolean
slow_publishes*integer
Formatint64
Range0 <= value
status*string

draining (publish-watchdog trip) | unhealthy (DB/migration-ledger probe failed) | degraded (NATS probe failed) | warn (retention alarms present) | ok — checked in that priority order, draining and unhealthy first since those matter most for a deploy decision.

trace_id?|

Present only on a 503 (draining / bad DB / degraded NATS), same as every ApiError body — this endpoint's success/error bodies share one documented shape (DeepHealth) that ApiError's generic {"error": "..."} envelope can't carry without dropping the rest of these fields (api/AGENTS.md's ApiError section documents this as the one narrow exception), so the trace ID is attached here directly via the same helper error::envelope uses rather than through ApiError.

curl -X GET 'https://example.com/health/deep'
{  "consecutive_publish_timeouts": 0,  "consecutive_slow_publishes": 0,  "create_stuck_pending_failures": 0,  "db": "string",  "jobs_consumer_ack_pending": 0,  "jobs_consumer_pending": 0,  "jobs_consumer_redelivered": 0,  "jobs_consumer_waiting": 0,  "last_publish_ms": 0,  "max_queued_creates": 0,  "nats": "string",  "otel": "string",  "publish_timeouts": 0,  "queued_creates": 0,  "reaper_herd_guard_trips": 0,  "reaper_lost_mark_gate": "string",  "redis": "string",  "retention_alarms": [    "string"  ],  "self_cordoned_runners": 0,  "shedding": true,  "slow_publishes": 0,  "status": "string",  "trace_id": "string"}