# Heartbeat > Probes endpoints, for health and monitoring Base URL: https://heartbeat.resola.net. Query API is read-only except POST /api/v1/monitors/{name}/ping (manual watchdog ping). Jobs ping GET|POST /ping/{token}. There is no create, update, delete, or pause endpoint. Authentication: every path under /api/v1/ requires header Authorization: Bearer . Missing or wrong token returns HTTP 401 {"error":"invalid or missing bearer token"}. If the API is disabled the same paths return HTTP 503. Do not send the metrics scrape token to /api/v1/*. Statuses: ok (passing), warn (reachable, policy miss), error (failed), pending (configured, no probe yet; last_check omitted), paused (outside its probe window). Filters combine with AND. ?tag=a,b means the monitor must have every listed tag. Success envelope: {"data":...,"generated_at":""}. Endpoints that take window also return "window":"24h" (Go duration; defaults 24h for stats, 7d for incidents). Errors: {"error":"..."} with 401, 404, 503, or 500. Empty lists are [], never null. Timestamps are RFC3339. paused rows hide a frozen last-fail (last_ok true, last_reason empty) so they do not look like a current outage. Monitor object: monitor, url, status, since, last_check, last_ok, last_latency_ms, last_reason, last_timing (dns_ms/tcp_ms/first_byte_ms/download_ms; HTTP only), cert_expiry, tags, ping_source, ping_timing. Result row: at, ok, status (HTTP code), latency_ms, timing (same four phases), reason, truncated, ping_source, ping_timing. Stats: window, total, ok, failed, uptime_pct, latency_p50_ms, latency_p90_ms, latency_p99_ms (uptime treats warn as ok). Incident: monitor, started_at, resolved_at, duration_seconds, ongoing, reason (error to ok only). Summary: total, ok, warn, error, pending, paused, soonest_cert_expiry, open_incidents, by_tag (each tag: total/ok/warn/error/pending/paused). Watchdog timing labels: early, received, grace, late, failing. ## Query API - [List monitors](https://heartbeat.resola.net/api/v1/monitors): GET. Query state (ok|warn|error|pending|paused), q (name substring, case-insensitive), tag (comma list, AND). - [One monitor](https://heartbeat.resola.net/api/v1/monitors/{name}): GET. 404 if unknown or no state yet. - [Results](https://heartbeat.resola.net/api/v1/monitors/{name}/results): GET. Newest first. limit (default 100, max 1000), before (RFC3339, exclusive) for pagination. - [Stats](https://heartbeat.resola.net/api/v1/monitors/{name}/stats): GET. window default 24h (example: ?window=24h). - [Summary](https://heartbeat.resola.net/api/v1/summary): GET. Fleet counts plus by_tag and soonest_cert_expiry. - [Incidents](https://heartbeat.resola.net/api/v1/incidents): GET. window default 7d (example: ?window=7d). - [Manual ping](https://heartbeat.resola.net/api/v1/monitors/{name}/ping): POST. Same auth as the query API. source is "manual". Starts or resets a protocol:heartbeat timer. ## Open - [Landing](https://heartbeat.resola.net/): GET HTML by default. JSON when Accept is application/json or ?format=json. Text when Accept is text/plain or ?format=text. - [Liveness](https://heartbeat.resola.net/healthz): GET {"status":"ok"}. No auth. - [This file](https://heartbeat.resola.net/llms.txt): GET text/plain. No auth. - [Job ping](https://heartbeat.resola.net/ping/{token}): GET or POST. Path token identifies the watchdog. Optional Authorization: Bearer when the monitor sets ping_auth. Origin / Referer become ping_source. ## Optional - [Metrics](https://heartbeat.resola.net/metrics): GET Prometheus text. Requires a dedicated bearer token, not the query-API token.