# Anatomy of a check

Every monitor, whatever its type, runs through the same cycle on every scheduled check. Knowing the cycle makes
the settings screen easier to read: each settings group controls one step of it.

## The cycle, step by step

| Step | What happens | Controlled by |
|---|---|---|
| 1. Schedule | The monitor becomes due - every N seconds for an interval, or at the next fire time for a cron schedule. | [Interval or cron](/monitors/intervals/) (`interval` / `cronSchedule`) |
| 2. Pick a checkpoint | One checkpoint from the monitor's selected locations runs the check. Checkpoints are taken in turn, so successive checks come from different places. Types without a location picker (SSL/domain expiry, DNSBL, Web Risk, Database, SNMP, Counter) run where HostTracker places them. | [Monitoring locations](/monitors/default-locations/) (`locations`) |
| 3. Run the request | The checkpoint resolves the host, connects, and performs the type's request (HTTP request, ping, TCP connect, browser load, SQL query...). | The type's settings (`settings.*`) |
| 4. Wait up to the timeout | If no complete answer arrives in time, the check fails with a timeout. | [Timeout](/monitors/advanced/response-limits/) (`settings.timeout`) |
| 5. Judge the result | Pass or fail: status codes, keywords, [assertions](/monitors/advanced/assertions/), [TLS policy](/monitors/advanced/tls-policy/), thresholds, depending on the type. | Response Validation settings |
| 6. Confirm a change | If the verdict differs from the monitor's current state (up -> down or down -> up), other checkpoints re-check before the state changes. | [Recheck strategy](/monitors/advanced/recheck-strategy/) (`recheck`) |
| 7. Record | The result is stored, the uptime statistics move, and a confirmed change opens or closes an [incident](/incidents/what-is-an-incident/). | [Full Log](#what-gets-recorded) (`fullLog`) |
| 8. Notify | Subscribed contacts get the Down, Up or still-down alert, after each contact's own delay. A [maintenance window](/maintenance/what-it-suppresses/) can hold alerts back. | [Alert subscriptions](/alerts/subscriptions/) |

Steps 6-8 are explained in detail in [How down detection works](/monitors/down-detection/).

## When the first check runs

A new or edited monitor is picked up by the scheduler within about a minute of saving, then runs on its
schedule. A check that could not be carried out at all (the checkpoint was busy, or failed internally) does not
count as up or down: it is retried shortly, and a checkpoint that produced an internal failure is trusted less for
this monitor's next checks.

## What gets recorded

- **Every check** updates the monitor's statistics (uptime, response time) and its last result.
- **Events** group consecutive checks with the same outcome. With **Full Log** off, results are grouped into
  events of up to about an hour; with Full Log on, into events of about 5 minutes, so reports can show a much
  finer event log. Full Log (`fullLog`) is a plan feature; if your plan does not include it, the switch is
  disabled with "Not supported in current package".
- **State spans** record each continuous up or down period and are what uptime percentages are computed from.
  Time inside a maintenance window that suppresses statistics is left out of the percentage.
- **Snapshots** (a screenshot or the response body, depending on the type) are captured for some results,
  depending on the type and your plan. See [Result snapshots](/incidents/snapshots/).

## Read the results

| What you want | App | API (scope `monitor:read`) | MCP |
|---|---|---|---|
| The latest result | Open the monitor's row on **Sites** | `GET /monitor/{id}?expand=lastResult` | `get_monitor` with `expand=lastResult` |
| Raw results in a window | The monitor's statistics page | `GET /monitor/{id}/result?from=...&to=...` | `list_monitor_results` |
| Which locations confirmed a change | The incident's details | `GET /monitor/{id}/result/{resultId}?expand=recheck` | `list_monitor_results` with `expand=recheck` |
| Uptime and response time over a window | Sites dashboard uptime column | `GET /monitor/result/summary?monitor=...&from=...&to=...` | `get_uptime_summary` |
| Up/down periods | The uptime strip | `GET /monitor/{id}/span?from=...&to=...` | `api_request` |
| Incidents | The incidents panel on **Sites** | `GET /monitor/{id}/incident` | `list_incidents` |

## Related

- [What a monitor is](/monitors/what-a-monitor-is/)
- [How down detection works](/monitors/down-detection/)
- [Reading check results](/incidents/reading-results/)
- [HTTP request configuration](/monitors/advanced/http-request-config/)
