Get a push notification when your website goes down
Finding out your site is down from a customer's email is the wrong way to find out. You don't need a monitoring service with a dashboard and a plan — a small external cron that curls your site every minute and pings Lert when the status isn't 200 covers the case that matters, and tells you again the moment it recovers.
Check the status, alert on the change
The whole monitor is a curl that reads the HTTP status code and a bit of state so you get one alert going down and one coming back — never a buzz every minute of the outage. Store the last state in a file and compare:
#!/usr/bin/env bash LERT_URL="https://lert.dev/p/your-id" SITE="https://example.com" STATE="/tmp/uptime.state" # "up" or "down" # -s silent, -o discard body, -w print status; fail on timeout CODE=$(curl -s -o /dev/null -w "%{http_code}" \ --max-time 10 "$SITE" || echo "000") PREV=$(cat "$STATE" 2>/dev/null || echo "up") if [ "$CODE" != "200" ] && [ "$PREV" = "up" ]; then curl -s -X POST "$LERT_URL" \ -d "{\"title\":\"Site DOWN 🔴\",\"body\":\"$SITE returned $CODE\",\"tag\":\"uptime\"}" echo down > "$STATE" elif [ "$CODE" = "200" ] && [ "$PREV" = "down" ]; then curl -s -X POST "$LERT_URL" \ -d "{\"title\":\"Site recovered 🟢\",\"body\":\"$SITE is back (200)\",\"tag\":\"uptime\"}" echo up > "$STATE" fi
The || echo "000" turns a connection refused or timeout into a non-200 code so a hard-down site is caught, not just an HTTP error page. Because the alert only fires when $CODE disagrees with the stored state, you get a clean pair: Site DOWN when it breaks, Site recovered when it's back.
Set it up in three steps
1. Copy your Lert URL
Open the Lert app and copy your unique endpoint — something like https://lert.dev/p/your-id. Keep it in the script or an environment variable and treat it like a password.
2. Run the checker somewhere else
This is the one rule that matters: don't run the check on the server you're checking. If the box goes down, so does its cron, and you hear nothing. Put the script on a separate cheap VPS, a home machine, or a hosted cron provider — anywhere with its own network path to both your site and the internet.
3. Schedule it every minute
Cron's finest granularity is one minute, which is plenty for a small site. Add:
# Check every minute from an external host
* * * * * /opt/scripts/uptime-check.sh
Confirm before you cry wolf. A single dropped packet shouldn't page you. Have the script re-check a few seconds later and only alert on two failures in a row. For deeper signals from the host itself — CPU, disk, memory — pair this with server monitoring; the same curl approach also covers webhook endpoints and scheduled jobs.
Check more than a 200
An HTTP 200 means the server answered, not that the page is correct. A few cheap upgrades catch subtler outages:
- Content check:
curl -s "$SITE" | grep -q "Sign in"to confirm real content rendered, not a blank shell or an error page that still returns 200. - Latency: add
-w "%{time_total}"and alert when a response takes longer than a few seconds — slow is the outage before the outage. - TLS expiry: a weekly check of your certificate's expiry date, so a lapsed cert never surprises you.
- Health endpoint: point the check at a
/healthroute that verifies the database and queues, so a green check means the whole stack is up.
Why Lert for uptime alerts
Hosted uptime monitors are great until you want three of them and hit the paywall. Rolling your own with Lert costs nothing per monitor: a curl, an if, and one POST, running on a box you already have. The endpoint URL is the authentication — no account, no key — and because it's a real iOS push, "site down" wakes your locked phone at 3am instead of waiting politely in an inbox.
FAQ
Why run the check from an external server?
If the checker runs on the same machine as your site, an outage takes the checker down too and you get no alert. Run it from a different host — a cheap VPS or a separate cron provider — so it can still reach your phone when your server can't.
How do I avoid a notification every minute while the site is down?
Store the last known state in a small file and only POST when it changes — one alert going down, one coming back up. That gives you a clean down-then-recovered pair instead of a buzz every minute of the outage.
Should I alert on the very first failed check?
Usually confirm with a second request a few seconds later before alerting, so one dropped packet doesn't page you. Two failures in a row is a good threshold for a small site.
Do I need an API key or account?
No. Your Lert endpoint URL is the authentication — there's no separate key, token, or login. Keep it in the script or an env var.
How fast does the notification arrive?
Typically within a second or two of the POST. It's a real push, so it wakes a locked phone and buzzes a paired Apple Watch.
Related use cases
Be the first to know your site is down.
Download Lert, copy your URL, run one curl on a cron. Your phone buzzes the moment it's not 200 — and again when it's back.