Health API
Monitor system health and configure heartbeat schedules.Health check (web)
The backend service exposes its own health check at
GET /health (without the /api prefix). The web and backend health endpoints are independent — the web endpoint reports on the web application process while the backend endpoint reports on the API service. See backend health check below for details.Response
The
health field reflects overall system status based on internal CPU and memory thresholds:
Degraded and unhealthy responses
When the system is degraded or unhealthy, the endpoint still returns HTTP200 with the health field set to degraded or unhealthy. The status field remains ok.
Error response
An HTTP500 is returned only when an unexpected error occurs while collecting health metrics, not for degraded or unhealthy status:
Platform version
VERSION file.
Response headers
Response
Dashboard health
Response headers
Response
The
status field for each service reflects the result of an HTTP health probe with a 6-second timeout per candidate URL. When all candidates fail, the primary URL is retried once with an 8-second timeout for diagnostic detail:
When a service is
down, the detail field contains a normalized error label rather than the platform’s raw error string. Possible values include timeout (8s), dns error, connection refused, connection reset, socket error, or unreachable.
The Borg-7139 (formerly Tempo Soul) probe attempts the configured
SOUL_SERVICE_URL first at /soul/status, then falls back through /health, /healthz, and /readyz on the same host before trying /soul/status and /health on the canonical borg-0-production-7139.up.railway.app host. This fallback chain ensures that a stale SOUL_SERVICE_URL value does not surface a misleading HTTP 404 while the canonical Borg host is healthy. A host is considered healthy when any candidate returns HTTP 2xx; the response body is parsed for an active, ready, status, or build field to populate the detail. Railway uses a TCP port check on port 4023 instead of an HTTP health check for this service.Backend health check
/api prefix).
The backend API continues to serve non-provisioning endpoints (health, metrics, auth, AI, registration) even when the Railway API is not reachable. Agent provisioning and lifecycle operations are disabled until the Railway API becomes available.
Response
Response when the Railway API is unavailable
When the Railway API is not reachable, the health endpoint still returns HTTP200 but reports degraded capabilities:
provisioning is disabled, any request to a provisioning-dependent endpoint (such as deploying, starting, stopping, or restarting an agent) returns a 500 error. Non-provisioning endpoints continue to operate normally.
The
provider field currently returns render for backward compatibility. Agent containers are now provisioned on Railway. This value may be updated to railway in a future release.Get heartbeat settings
The
source field in the response indicates where the data came from: gateway when read from the gateway’s cron scheduler, or db when read from the database fallback.Query parameters
Response (gateway source)
When the gateway has a heartbeat cron job configured:Response (database fallback)
When no gateway heartbeat job is found andagentId is provided:
enabled and frequency values.
When no agentId is provided and no gateway heartbeat is found:
Errors
Update heartbeat settings
source: "gateway". If the gateway is unavailable or the write fails, the settings are saved to the database as a fallback.
Request body
Response (gateway source)
Response (database fallback)
Errors
Delete heartbeat settings
Request body
Response
Errors
Runtime status classification
All health-related endpoints that report agent status use a shared runtime probe. The probe checks three endpoints on each agent service in parallel:GET /api/status is the authoritative health signal. The Railway wrapper uses /api/status as the primary health check. The legacy /healthz and /readyz endpoints may legitimately return 404 on some deployments and should not be treated as the sole indicator of agent health.- If
/api/statusreturns200:configured: false→ status issetuprunning: trueorstate: "running"→ status isrunning(even if/healthzand/readyzreturn404)running: falseorstate: "stopped"→ status isstopped- Other states → falls back to legacy probe results
- If
/api/statusdoes not return200:/healthzand/readyzboth200→ status ishealthy/healthz200but/readyznot200→ status isstarting- All probes fail → status is
unreachable
Container health checks
Agent services run the official OpenClaw image, which exposes built-in health endpoints on port18789. The backend uses these to determine service readiness during provisioning and ongoing monitoring.
Built-in health endpoints
The OpenClaw image (ghcr.io/openclaw/openclaw:2026.4.27) provides three health endpoints on each agent service:
All endpoints are unauthenticated and bind to the service’s internal port (
18789).
/api/status response
/healthz response
/readyz response
Container health statuses
Health check behavior
- The shared runtime probe checks
/healthz,/readyz, and/api/statusin parallel./api/statusis the authoritative signal. - The health check uses a 5-second timeout for
/healthzand/api/status, and a 4-second timeout for/readyz. - The
waitForHealthyfunction polls service health every 2 seconds, with a default overall timeout of 60 seconds.
Watchdog monitoring
The backend runs a per-agent watchdog that continuously monitors agent health, detects crash loops, and performs automatic recovery. The watchdog operates internally and does not expose dedicated API endpoints. Status information is surfaced through the existing agent status and lifecycle endpoints.Health check cycle
The watchdog probes each agent’s gateway using the shared runtime probe (which checks/api/status, /healthz, and /readyz). Health checks run on a configurable interval (default: every 2 minutes). When the probe reports the agent as unhealthy or unreachable, the watchdog transitions the agent to a degraded state and increases the check frequency to every 5 seconds.
Lifecycle states
The watchdog tracks the following lifecycle states for each agent:Auto-repair
When the watchdog detects an unhealthy agent, it can automatically attempt recovery. Auto-repair is enabled by default and can be disabled by setting theWATCHDOG_AUTO_REPAIR environment variable to false.
The repair sequence is:
- Kill the agent gateway process
- Wait 5 seconds
- Restart the gateway
- Wait 30 seconds (startup grace period)
- Verify health
crash_loop state.
Crash loop detection
The watchdog tracks crash timestamps within a sliding window (default: 5 minutes). When the number of crashes in the window reaches the threshold (default: 3), the agent enters thecrash_loop state. This prevents infinite restart loops for agents with persistent failures.
Notifications
The watchdog sends notifications for critical events (degraded, crash loop, repair attempts) through configured channels:- Telegram — when
TELEGRAM_BOT_TOKENandTELEGRAM_ADMIN_CHAT_IDare set - Discord — when
DISCORD_WEBHOOK_URLis set
Railway status webhook
This endpoint accepts webhooks from both status.railway.com (incident and component updates) and the Railway dashboard (deployment events). Configure webhook subscriptions in both locations to point to this URL.
Authentication
TheRAILWAY_WEBHOOK_SECRET environment variable must be configured. Every request must include the secret via one of the following methods:
The secret is verified using a constant-time comparison to prevent timing attacks.
Request body
The endpoint accepts two payload formats: deployment events from the Railway dashboard and status-page events from Railway’s status page.Deployment event
Sent by Railway when a deployment status changes.Status-page event
Sent by Railway’s status page for incident and component updates. The payload follows the Railway status page webhook format.Response
On success, the endpoint returns the received event along with the persisted record:The record is stored in Redis under the key
railway:status:latest with a 7-day TTL. When Redis is not configured (KV_REST_API_URL and KV_REST_API_TOKEN not set), the endpoint still processes the event and returns the record but does not persist it.Error response
Returned when the request body is not valid JSON:Example payloads
Deployment event
Incident event
Railway status polling
Response
When a status event has been received and persisted:
When no events have been received:
KV_REST_API_URL and KV_REST_API_TOKEN not set):