# Quietbeat > Uptime and cron-heartbeat monitoring with an alerting layer: HTTP, TCP and > DNS checks, dead-man switches for scheduled jobs, incidents with > forensics captured at the moment of failure, on-call rotations, and public > status pages. Everything the web UI does is available over a JSON API and a > write-capable MCP server, so an agent can run the account end to end. > Browser and Lighthouse checks are not available yet: the fields exist in the > API, execution is unavailable and no run is queued. Silence is the signal. A cron job pings its own URL after every successful run; if the window (interval + grace) passes without a beat, that is the incident. Website and service checks share the same record. All paths below are relative to the site root this file is served from. Placeholders in braces (`{id}`, `{token}`, `{slug}`) are yours to fill in. ## Auth model - **REST API and MCP** — `Authorization: Bearer qb_…`. Mint tokens at [/api_tokens](/api_tokens); they are shown once. A token can be marked read-only, in which case REST writes answer 403 and the MCP write tools are withheld from `tools/list`. 240 requests per minute per token; over that, 429. Errors are JSON: `error.message` for people, `error.code` to match on (`unauthorized`, `read_only_token`, `not_found`, `validation_failed`, `rate_limited`, …), plus per-field `error.details` on validation failures. - **Team workspaces** — send `x-quietbeat-workspace: {owner_id}` to act inside a workspace the token's user holds a seat on. No seat, or a value that is not an id, is a 404 `workspace not found` — the request never lands on the token owner's own account instead. `GET /api/v1/workspaces` still answers under a stale header and marks the selected workspace `current`. - **Heartbeat pings and event intake** — the token in the URL is the credential; no header, no session. Treat those URLs as secrets. - **Relay and probe agents** — `Authorization: Bearer qbr_…`, a different token family with its own two-endpoint pull protocol. - **Web UI** — session cookie; sign in with a password or an emailed sign-in link, with optional TOTP two-factor. Status pages are public per slug and may carry a page password. ## API - [REST reference](/docs/api): worked request/response pairs for every group below. - `/api/openapi.json`: the OpenAPI 3.1 document — hand-authored against the real endpoints, not a generated sample, and held to the router by a test that fails if either side drifts. Generate a client from it. - **`qb`, the official CLI** — one static binary, installed with `brew install mightyworks-sk/tap/qb` or from GitHub releases. It speaks this same REST API and nothing privileged. `qb status`, `qb monitors list --json`, `qb incidents ack `, `qb ping `. `qb llms` prints every command as JSON — flags, the endpoint each calls, and the exit codes — so an agent can drive it without scraping help text. - `GET /api/v1/status`: the whole account in one call — counts, what is down. - `GET /api/v1/monitors`, `POST /api/v1/monitors`: list and create. Active monitor kinds are `http`, `heartbeat`, `tcp`, `dns`, `certificate` and `event`. A `certificate` monitor watches one certificate — pasted in, served by an endpoint, or read off a workload by an agent — and reports individual technical checks with their evidence, never a compliance verdict. `browser` is not available yet: creation is refused while execution is unavailable and no browser run is queued. Intervals are 30/60/300/900/1800/3600/21600/86400 seconds (30s is team-plan only). - `GET /api/v1/monitors/{id}`, `PATCH /api/v1/monitors/{id}`, `DELETE /api/v1/monitors/{id}`: one monitor. - `POST /api/v1/monitors/{id}/pause`, `POST /api/v1/monitors/{id}/resume`. - `GET /api/v1/monitors/{id}/stats`: uptime and response-time percentiles for a window. Uptime is span-honest — `covers_full_window` stays false until the monitor has lived the whole window. - `GET /api/v1/monitors/{id}/checks`, `GET /api/v1/monitors/{id}/beats`: the raw record behind the chart. - `GET /api/v1/incidents`, `GET /api/v1/incidents/{id}`, `POST /api/v1/incidents/{id}/ack`: incidents and acknowledgement. Each incident carries its `title` and `stage` as the status page shows them; the detail adds `gap_texts` and `delivery`, who was alerted or paged and whether it landed. - `GET /api/v1/incidents/{id}/updates`, `POST /api/v1/incidents/{id}/updates`: the stage timeline, and posting to it (`stage`, `body`). Owners and admins only; `stage: resolved` resolves the incident by hand. - `GET /api/v1/status_pages`, `POST /api/v1/status_pages`, `GET /api/v1/status_pages/{id}`, `PATCH /api/v1/status_pages/{id}`, `DELETE /api/v1/status_pages/{id}`: the public pages themselves. Modes are `all`, `group` and `selected`. A page's custom domain and password are not manageable here — both sit behind their own plan-gated flows in the app. - `GET /api/v1/alert_channels`, `POST /api/v1/alert_channels`, `GET /api/v1/alert_channels/{id}`, `PATCH /api/v1/alert_channels/{id}`, `DELETE /api/v1/alert_channels/{id}`: where alerts land. `config` is write-only — it carries a live credential, is encrypted at rest, and is never read back. - `GET /api/v1/escalation_steps`, `POST /api/v1/escalation_steps`, `GET /api/v1/escalation_steps/{id}`, `PATCH /api/v1/escalation_steps/{id}`, `DELETE /api/v1/escalation_steps/{id}`: one rung of a monitor's alert ladder. `?monitor_id=` narrows the list to one ladder. An empty ladder is the default — everything fires at once. - `GET /api/v1/on_call_schedules`, `GET /api/v1/on_call_schedules/{id}`: rotas, read-only, each with its rotation and who holds the pager right now. `?name=` narrows; names are not unique, so it narrows rather than resolves. - `POST /api/v1/sync`: monitoring as code. A name-keyed diff over YAML or JSON — creates what is missing, updates drift, `prune: true` deletes what is not listed, `?dry_run=true` previews. - `GET /api/v1/deploys`, `POST /api/v1/deploys`: deploy markers, so an incident reads "went down 41 seconds after a3f19c2 shipped". - `GET /api/v1/maintenance`, `POST /api/v1/maintenance`, `DELETE /api/v1/maintenance/{id}`: maintenance windows that mute alerts. A monitor's `maintenance_ends_at` and `maintenance_window_ids` say whether it is silenced right now, until when, and by which windows. - `GET /api/v1/workspaces`: workspaces this token can act in. - `POST /api/v1/import/uptimerobot`: bulk import from another provider. - `POST /api/v1/events/{token}`: inbound event intake (Alertmanager, Grafana, Sentry and generic payloads) against an event monitor. - `POST /api/v1/pair`, `POST /api/v1/devices`, `DELETE /api/v1/devices`: mobile device pairing and push registration (beta mobile app). ## Heartbeats - `GET /b/{token}` (also POST, HEAD): the beat. A POST body up to 10 KB is kept as that run's evidence and quoted back in the alert. - `GET /b/{token}/start`: pairs with the finishing beat to record run duration. - `GET /b/{token}/fail`: the job reporting its own bad news — optional `exit_code`, `runtime_ms`, `message` — which opens an incident immediately instead of waiting out the grace window. ## MCP (agents) - [MCP setup guide](/docs/mcp): copy-paste config for Claude Code, Codex, Gemini CLI, Cursor, VS Code, Windsurf, or any client via `mcp-remote`. - `POST /mcp`: JSON-RPC 2.0 over streamable HTTP, protocol version `2025-06-18`, authenticated with the same `qb_…` bearer token. `GET /mcp` answers 405 — there is no SSE stream. - Read tools: `get_status_summary`, `list_monitors`, `get_monitor`, `list_incidents`, `get_incident_evidence`, `get_diagnosis`. - Write tools: `create_monitor`, `pause_monitor`, `resume_monitor`, `delete_monitor` (requires `confirm: true`), `trigger_check`, `ack_incident`, `post_incident_update`. - `create_monitor` with `kind: "heartbeat"` returns the ping URL and a ready-to-paste crontab line, so an agent that writes a cron job can wire its own dead-man switch in one call. ## Relays and the probe fleet - `GET /api/v1/relay/due`, `POST /api/v1/relay/results`: the entire pull protocol. Outbound-only, so a relay runs inside a private network with no inbound ports; a custom client is an afternoon in any language. - [Relays](/relays): create one and pin monitors to it ("checked from"). Paid plans. - `GET /used-ips`, `GET /used-ips.json`: the addresses our checks come from, for firewall allowlists. While none are published the JSON list is empty and the text form is a single `#` comment saying "not yet published" — an empty list means not yet published, not "nothing to allow". - `GET /health/deep`: liveness for an out-of-band watchdog — 200 only when the database answers and the scheduler has run recently. ## Status pages - `GET /s/{slug}`: the public page. `GET /s/{slug}/day/{date}` is one day in detail. - `GET /s/{slug}/api/v2/status.json`, `GET /s/{slug}/api/v2/summary.json`, `GET /s/{slug}/api/v2/incidents/unresolved.json`, `GET /s/{slug}/api/v2/components.json`: the Statuspage-compatible envelope, so anything that already reads one can read ours. - `GET /s/{slug}/badge.svg`, `GET /s/{slug}/{monitor_id}/badge.svg`: badges. ## App (session-authenticated UI) - [Monitors](/monitors) · [new](/monitors/new) · [scan a site](/monitors/scan) - [Incidents](/incidents) · [maintenance windows](/maintenance) - [Alert channels](/alert_channels): email is always on and free. Every other destination is a paid-plan channel — Slack, Discord, Telegram, Mattermost, Google Chat, Microsoft Teams, PagerDuty, Opsgenie, Splunk HEC, Pushover, Pushbullet and generic webhooks, with a hand-off to PagerDuty. Pages repeat until someone acknowledges. Nothing is billed per message. The Quietbeat mobile app (beta) adds push; it is not in the app stores yet. - [On-call](/oncall) · [your paging profile](/oncall/me) - [Status pages](/pages) · [custom domains](/domains) · [reports](/reports) - [API tokens](/api_tokens) · [team](/team) · [import](/import) · [settings](/users/settings) ## Docs and background - [Manual](/docs): the quickstart and the concepts. - [Integrations](/integrations): every alert destination and importer. - [Monitoring for AI-built apps](/for/ai-apps). - [Cron job monitoring](/cron-job-monitoring): dead-man switches for scheduled jobs, with a ping URL per job and a grace window. - [Compare](/compare): Quietbeat against other monitoring tools, with each tool's prices and limits dated. - [PagerDuty](/compare/pagerduty) - [UptimeRobot](/compare/uptimerobot) - [Better Stack](/compare/better-stack) - [Healthchecks.io](/compare/healthchecks-io) - [Cronitor](/compare/cronitor) - [Migrate from UptimeRobot](/migrate/uptimerobot): import monitors and history with a read-only API key; what transfers and what does not. - [Migrate from Freshping](/migrate/freshping): Free Freshping accounts were disabled in March 2026; how to rebuild its checks here. There is no importer. - [Vendor status](/status): current readings of the major vendors' public status feeds, one page per vendor. Quoted, not interpreted. - [Terms](/terms) · [Privacy](/privacy) - [Sign up](/users/register) · [Sign in](/users/log-in) ## Pricing Flat per account, never per monitor. Free: 10 monitors, 60-second checks, email alerts, and the full API and MCP — commercial use welcome. $9/mo solo: 50 monitors, the other alert channels, relays, a status page. $19/mo team: 200 monitors, 30-second checks, unlimited seats. See [the home page](/) for the current table. ## Machine-readable extras - `/llms.txt`: this file. - `/api/openapi.json`: OpenAPI 3.1 for the REST surface. - `/robots.txt`: crawl policy.