Documentation

Everything Checkmeup does today, in plain language — how to set up a monitor, what triggers an alert, and what each plan actually includes.

Getting started

Sign up, pick a monitor type from the dashboard, and fill in the form. There's no setup wizard and no required onboarding call — the whole thing takes under a minute for your first monitor.

Checkmeup watches six kinds of things: scheduled jobs that should run on a cadence (cron monitors), URLs that should always respond (uptime monitors), TLS certificates that shouldn't be allowed to quietly expire (SSL monitors), domain registrations that shouldn't be allowed to lapse (domain monitors), raw host:port connectivity for anything that isn't HTTP (port monitors), and DNS records that shouldn't change unexpectedly (DNS monitors). Connect Telegram, Slack, email, a webhook, or SMS (paid plans) — every monitor type alerts through whichever channels you enable.

Cron job monitoring

Create a cron monitor and you'll get a unique ping URL. Call it at the end of your job — if the ping doesn't arrive on schedule, you get alerted.

# Add this to the end of any cron job, script, or pipeline step
curl -s https://checkmeup.net/ping/<your-monitor-token>

# Optional: also ping /start when the job begins, to detect a stuck run
curl -s https://checkmeup.net/ping/<your-monitor-token>/start
...
curl -s https://checkmeup.net/ping/<your-monitor-token>
  • Schedule presets — every hour, every 30 minutes, daily at a fixed time, or weekdays only. Standard cron expressions also work.
  • Grace period — how late a ping can arrive before it counts as missed. Choose from 1 minute up to 1 hour, depending on how tight your job's timing is.
  • Execution history — every ping is logged, so you can see exactly when a job ran and how that compares to its schedule. If the job also sends a start ping, the log shows how long that run took.
  • Stuck run detection — send a start ping when the job begins, set a max run duration on the monitor, and you'll get a distinct alert if a run is still going once that time is up — instead of waiting on the completion ping that a stuck job will never send. Off by default; monitors that only send the completion ping are unaffected.
  • Attach custom data to a ping — add query params to the ping URL and they're stored with that ping, e.g. curl -s "https://checkmeup.net/ping/<token>?build=142&state=success". Capped at 20 key/value pairs, 64 characters per key, 256 per value — extra pairs are silently dropped rather than failing the ping. Only the most recent ping's data is kept (each ping overwrites it, it isn't a history). Read it back through the public API.

Uptime monitoring

Point an uptime monitor at any URL on your chosen interval — 5, 10, or 30 minutes on Hobby, plus 1 minute on paid plans. By default we send a GET request with a 10-second timeout and expect an HTTP 200 back, but all three are configurable per monitor under "Advanced check settings". Anything outside your configuration (an unaccepted status code, a timeout, a connection error) opens an incident.

  • Request method — GET, HEAD, or POST; GET by default.
  • Accepted status codes — choose which codes count as up, e.g. if your API legitimately returns 201 or 204 on success instead of a plain 200.
  • Request timeout — 1 to 30 seconds, 10 by default; a response that doesn't arrive in time aborts and counts as down.
  • Response time tracking — every check records how long your server took to respond.
  • Incident history — start time, resolution time, and duration for every outage, so you can see patterns over time.
  • Uptime percentage — rolling 24-hour, 7-day, and 30-day uptime shown on the monitor detail page.
  • Keyword monitoring (every plan, including Hobby) — add an optional keyword check alongside the status code, so a maintenance page served with a 200 or an error embedded in a JSON response still trips an alert. Set it to require the keyword (Contains) or to fail when it's present (Does not contain), with an optional case-sensitive toggle. We search the first 512 KB of the response body — no extra request, and the body itself is never stored, only the pass/fail reason.
  • JSON assertions — assert on one or more fields in a JSON response, e.g. $.status equals ok. Each assertion is a path, a comparator (equals, not equals, contains, >, <), and an expected value; add as many as you need — all of them must pass, same 512 KB response-body limit as keyword monitoring. The failure reason (which assertion didn't match) shows on the monitor's incident history.

SSL expiry monitoring

Give us a hostname — no https:// and no path, just the domain. We check the certificate on port 443 once a day and alert you at 30, 14, and 7 days before it expires, plus immediately if a check fails or the cert is already invalid.

The dashboard shows the current issuer and exact expiry date for every monitored certificate, so renewal is never a surprise.

Domain expiry monitoring

Separate from your SSL certificate — this tracks the domain registration itself, which is rarer to lapse but far more catastrophic when it does (your site disappears entirely, and the domain can get squatted before you notice). Give us an apex domain, same format as an SSL monitor's hostname, and we check its registration once a day and alert you at 30, 14, and 7 days before it expires, plus immediately if it's already expired.

The dashboard shows the current registrar and exact expiry date for every monitored domain.

Port (TCP) monitoring

For anything that doesn't speak HTTP — a mail server, a database, a custom daemon — give us a host and a port and we open a raw TCP connection on your chosen interval, no data sent or received. Host and port are editable after creation, unlike SSL and domain monitors' hostname field.

Each monitor has an expected state. The default, open, alerts if the port stops accepting connections — the familiar uptime check. The other option, closed, inverts that: alerts if the port unexpectedly starts accepting connections. That's a security check, not an uptime one — confirming a port that should be firewalled off (a database bound to a public interface, an admin panel, a debug port left on by mistake) actually stays unreachable, and catching the exact moment it doesn't.

DNS record monitoring

A hijacked or accidentally-changed DNS record doesn't fail the way a downed server does — traffic just starts going somewhere else. Give us a hostname and a record type (A, AAAA, CNAME, MX, TXT, or NS) and we resolve it on your chosen interval, comparing every check against a stored value.

Set an expected value to pin exactly what the record should resolve to — you'll be alerted from the moment the monitor is created if reality doesn't match. Leave it blank and the first successful check captures whatever it currently resolves to as a baseline instead; every later check compares against that captured value the same way.

A lookup failure (NXDOMAIN, SERVFAIL, timeout) alerts as a distinct "can't resolve" state, separate from a value mismatch's "changed from X to Y" — those are different problems with different fixes. Editing a monitor to accept a new value (or clearing it back to blank) is how you tell Checkmeup an intentional change is fine going forward.

Telegram alerts

Every monitor type can alert through Telegram. Set it up in Settings → Notification channels:

  1. Open @checkmeupnet_bot in Telegram and send /start.
  2. The bot replies with your Chat ID.
  3. In Settings → Notification channels, click Add channel, choose Telegram, paste your Chat ID, and click Send test message to confirm it works.

Alerts are capped per incident — by default, 3 alerts and then silence until the monitor recovers, so a flapping check doesn't spam your phone. The recovery alert always sends, regardless of the cap. The alert limit is configurable per monitor.

Email alerts

Send alerts to any email address — use alongside Telegram and Slack, or on its own. Set it up in Settings → Notification channels:

  1. Click Add channel and choose Email.
  2. Enter an address — can be a shared inbox like alerts@yourteam.com rather than your login email.
  3. Click Send test email to confirm it's deliverable, then Save.

Down and recovery alerts include monitor name, reason, and timestamp, with a subject line containing the monitor name and "DOWN" for inbox filtering. A single alert event fires on each assigned channel independently; the per-incident alert cap counts it as one notification regardless of how many channels fire.

Webhook alerts

A generic alert channel for wiring monitor events into your own automation — PagerDuty, a custom script, or anything else that isn't a first-class integration. Set it up in Settings → Notification channels:

  1. Click Add channel, choose Webhook, and enter a URL that starts with https://.
  2. Click Send test webhook to verify delivery before saving.
  3. A signing secret is generated automatically once the channel is saved — use it to verify requests really came from Checkmeup (see below). Regenerate it any time from the channel's edit view.

On every down/recovery event (and for the test button), Checkmeup sends a single unretried POST with a JSON body:

{
  "eventType": "down",
  "monitorName": "api.example.com",
  "monitorType": "uptime",
  "reason": "HTTP 503",
  "timestamp": "2026-07-10T14:32:00Z"
}

The request carries an X-Checkmeup-Signature header — a hex-encoded HMAC-SHA256 of the raw body, signed with your channel's secret — so you can verify it before acting on it. You can add multiple webhook channels and assign them to specific monitors rather than all of them.

Slack alerts

Post alerts to any Slack channel via an Incoming Webhook. Set it up in Settings → Notification channels:

  1. In Slack, go to Apps → Incoming Webhooks and create a new webhook for your target channel.
  2. Copy the Webhook URL (starts with https://hooks.slack.com/services/).
  3. In Settings → Notification channels, click Add channel, choose Slack, paste the URL, and click Send test message to verify, then Save.

You can add multiple Slack channels — name each after the workspace or channel it posts to — and assign them to specific monitors rather than all of them.

SMS alerts

Text alerts to a phone number — available on Solo, Startup, and Enterprise (not Hobby), since carrier fees give SMS a real per-message cost the other channels don't have. Set it up in Settings → Notification channels:

  1. Click Add channel and choose SMS.
  2. Enter the number in E.164 format (e.g. +14155551234) and check the consent box — required before any automated text can be sent to that number.
  3. Click Send test SMS to confirm delivery, then Save.

Down and recovery texts are kept to a single message segment. Each plan includes a monthly SMS credit allowance (Solo 10 / Startup 30 / Enterprise 100 — one credit per message sent) that resets on the 1st of each calendar month and doesn't roll over; if a month's credits run out, that monitor's other alert channels (or your account email) still fire as normal.

Status pages

Create a public status page at checkmeup.net/status/your-slug and add any of your monitors to it. Visitors see live status and incident history — no login required, nothing to install on their end.

There's no subdomain or DNS setup. Status pages live on the same domain by design, which means freelancers and agencies can share a clean link with clients in seconds instead of provisioning DNS for every account.

Every status page also has embeddable status badges — an overall-status SVG for the page, plus one per monitor on it. Copy the Markdown or HTML snippet from the status page's detail view (each links back to the public page) and drop it in a README, wiki, or internal dashboard.

Each status page also has a layout choice in its edit settings: the original single-column layout, or a wider grid that lays monitors out two-per-row with incidents in a sidebar — better suited to a page watching a lot of monitors. Set per page and available on every plan.

On Solo and above, each status page has a hide branding toggle in its edit settings that removes the "Powered by Checkmeup" line and FAQ/Terms/Privacy links from the public footer — set per page, so you can leave it on for some pages and off for others.

Incident management

Declare an incident from the Incidents page for anything affecting visitors that isn't a plain monitor-down — degraded performance, a partial outage, or something you want to narrate before a monitor even trips. Pick a title, an initial message, a severity (Minor / Major / Critical), and any combination of affected monitors.

  • Progress updates — post timestamped updates as you work the incident; status moves forward through Investigating → Identified → Monitoring → Resolved with each one.
  • Shown on the public status page — active incidents appear above the monitor list, and a Major or Critical incident escalates the overall status banner. Resolved incidents move to a paginated history.
  • Independent of monitor status — declaring, updating, or resolving an incident never changes a monitor's own up/down state, and doesn't trigger alerts on any channel.
  • Maintenance-aware — declaring an incident against a monitor already under an active maintenance window shows a warning first, so the two don't collide by accident.
  • 90-day history — resolved incidents stay in the public history for 90 days, the same window as check history, on every plan. A still-active incident is never removed on a timer, no matter how old.
  • Up to 100 open at once — every plan can have up to 100 unresolved incidents at the same time. Resolve one to free up room for the next; this is a safety cap on how many can pile up, not a per-plan allowance.
  • Up to 100 updates per incident — same safety-cap philosophy, per incident rather than per org.

Maintenance windows

Schedule a maintenance window from the Maintenance page and pick any combination of cron, uptime, SSL, domain, port, and DNS monitors to cover. While a window is active, those monitors aren't checked at all — no alerts, no incidents, and your uptime stats stay untouched.

  • Planned or unplanned — set a start and end time ahead of a deploy, or start one immediately with no end date and close it manually with End now once the incident is resolved.
  • Multiple monitors per window — one window can cover everything affected by a single deploy or maintenance task.
  • Visible on status pages — any covered monitor shows "Under maintenance" with an optional message instead of up/down, and doesn't trigger an outage banner.
  • Up to 100 per org — on every plan. Delete an old one to free up room for a new one.

Appearance

Checkmeup supports light and dark themes. Switch anytime from the toggle in the app shell or Settings → Appearance — it applies instantly, no reload. First visit defaults to your OS-level light/dark preference; after that, your choice is remembered on this device.

Plans & limits

Limits are per organization and apply across all monitor types combined. The free Hobby plan is meant to be genuinely usable, not a trial.

Plan Monitors Status pages SMS credits/mo
Hobby — Free101
Solo — $9/mo30310
Startup — $29/mo1001030
Enterprise — $99/mo1000100100

Keyword monitoring is available on every plan, including Hobby. See the full feature comparison for everything else that's the same across every plan.

Paid plans can also be billed annually — two months free compared to paying monthly — toggle it in Settings → Billing.

Full pricing details →

Public API

Read a monitor's current status from scripts, CI pipelines, or your own dashboard — useful for a build step that should surface its result somewhere else, or a status display that isn't Checkmeup itself (think a physical LED, an internal ops dashboard). Generate a key in Settings → API keys — the raw key is shown once, so copy it immediately — then send it as an X-API-Key header. Keys are read-only for now and rate-limited to 60 requests/minute.

curl -H "X-API-Key: cmu_live_..." \
https://checkmeup.net/api/v1/public/monitors/cron/<monitor-id>/status

The monitor ID is the UUID in its detail page URL. Swap cron for uptime, ssl, domain, or port, or dns to match the monitor type. A cron monitor's response looks like:

{
"id": "5e2b...",
"name": "Nightly export",
"type": "cron",
"status": "up",
"lastCheckedAt": "2026-07-03T20:33:47Z",
"lastPingMetadata": { "build": "142", "state": "success" }
}

lastPingMetadata only appears for cron monitors, and only once a ping has arrived — a CI job can attach its own key/value pairs (build number, exit state, anything short) as query params on the ping URL itself, e.g. ?build=142&state=success, and read them back through this endpoint. It always reflects the most recent ping — sending a new one overwrites it, it isn't a history. Capped at 20 key/value pairs per ping, 64 characters per key, and 256 characters per value; anything past that is silently dropped rather than rejected, since a ping must always succeed. SSL and domain monitors instead include expiresAt and daysUntilExpiry.

Up to 100 active keys per org, on every plan — revoke an old one to free up room for a new one.

Need help?

There's no support ticket queue — questions, bug reports, and feature requests all reach an engineer directly.

We use cookies for basic web analytics (page views, traffic sources). No ads, no cross-site tracking.