Check types
All seven live check types and when to reach for each.
Seven check types are live, and picking one comes down to a single question: what signal do you need? Is my page up, is my API returning the right data, is my cron job still running, is my infrastructure reachable, is my DNS what I published?
| Type | Direction | Success means |
|---|---|---|
| HTTP | Outbound | The URL responds with an acceptable status. |
| Keyword | Outbound | The response body contains (or omits) the text you named. |
| API | Outbound | A JSON field in the response has the value you expect. |
| Heartbeat | Inbound | Your job checked in on time. |
| Scheduler | Outbound | Your endpoint ran when we called it. |
| Port | Outbound | The TCP port accepted a connection. |
| DNS | Outbound | The record resolves, optionally to the value you expect. |
HTTP, Keyword, Heartbeat, and Port are included on the free plan; API, DNS, and Scheduler require a paid plan.
#The HTTP family: HTTP, Keyword, API
These three share one engine: an HTTP request on your interval, judged by rules. They differ only in what does the judging:
- HTTP judges the status code: any 2xx or 3xx by default, or an exact expected status you set.
- Keyword adds text rules: the body must contain, or must not contain, the strings you set. A 200 that renders an error page still fails.
- API adds JSON field rules, like
status: ok, so you watch a health endpoint's real signal instead of its status code. A paid type.
All three default to a HEAD request and switch to GET automatically when content rules need the body. Request headers (for auth) and request bodies (for write methods) are available on every one; see Create a monitor for the full field list.
#Heartbeat
Everything else here reaches out to your systems; a heartbeat waits for your system to reach in. Each heartbeat monitor gets a ping URL, and your cron job, worker, or backup script calls it (a plain GET or POST, no auth) at the end of every run:
curl https://upcheck-api-a.rekwiem.com/v1/heartbeats/<id>/pingYou declare the expected gap between pings, plus a grace buffer (60 seconds by default) for jobs that run a little long. If the gap passes with no ping, the monitor goes down: silence is the failure signal. A new heartbeat sits pending until its first ping arrives, so wire the ping in right after creating it.
Set the grace to your job's worst normal runtime. A nightly backup that usually takes 5 minutes but sometimes 20 wants a daily interval with a grace around 30 minutes, so a slow night is not a false alarm.
#In cron
Append the ping to the job itself, so it only fires when the job succeeded:
0 3 * * * /usr/local/bin/backup.sh && curl -fsS https://upcheck-api-a.rekwiem.com/v1/heartbeats/<id>/ping#In CI
Add a final step that only runs when the workflow is green:
- name: Ping UpCheck
if: success()
run: curl -fsS https://upcheck-api-a.rekwiem.com/v1/heartbeats/<id>/pingThe same pattern works anywhere that can run curl at the end of a successful run: systemd timers, worker loops, backup scripts.
#Scheduler
A scheduler is the inverse of a heartbeat: UpCheck calls your URL on the interval, so it is cron as a service, with alerting built in. Point it at an endpoint that does work when called, a cleanup route, a report generator, a queue drain.
Because it is a trigger and not a health check, the rules are stricter:
- Success is a 2xx, and only a 2xx. Redirects are not followed; a 3xx means the endpoint moved, which is a miss.
- Each run's result is the status. There is no fail-streak debounce: a failed trigger is immediately worth knowing about.
POSTis the default method, and read-only methods are excluded, a trigger must act. Auth headers and a request body are supported.
The endpoint you point it at is now callable on a schedule, so protect it: require a secret in a request header, set the header on the scheduler, and reject calls without it. Typical targets are the routes you would otherwise cron by hand, a cleanup route, a report generator, a queue drain, a cache warmer.
#Port
A port monitor opens a TCP connection to a host and port on your interval. No HTTP, no rules: success is "the port accepted", and the connect time is recorded as latency. The host can be a hostname or a public IP address, the timeout defaults to 10 seconds, and the usual thresholds apply (3 consecutive failures down, 1 pass back up, both tunable).
Use it for anything that listens on a port but does not speak HTTP: databases, mail servers, game servers, SSH. It answers "is it accepting connections", not "is it healthy", so pair it with an HTTP or API check when the service has a health endpoint.
#DNS
A DNS monitor resolves a record on your interval and fails when resolution fails. Record types: A, AAAA, CNAME, MX, TXT, and NS. Optionally set an expected value, and the check also fails when the answer does not contain it, which catches hijacked or fat-fingered records, not just missing ones. The target must be a hostname; resolving an IP literal is refused.
Two moments it earns its keep: during a DNS migration, point it at the record with the new value as the expected answer and watch the cutover land; and permanently on your apex domain, where a surprise answer change is exactly the alert you want to be woken up for. The monitor page keeps the most recent resolved answers, so you can see what the record actually said, not just that it differed.
Ping and UDP