Healthchecks.io check down or up notifications on your phone.

Get a push notification when a Healthchecks.io cron job or heartbeat misses its ping or reports a failure, and a quiet one when it recovers.

How it works

Three steps to your first push

STEP 01

Install the recipe

One click in Studio gives you a personal webhook URL.

STEP 02

Paste your URL into Healthchecks.io

Add it as a webhook for Check status.

STEP 03

Get a push on your phone

With the text, sound and buttons from the recipe.

Setup

How to set up the Healthchecks.io check status webhook

  1. Click Install in Studio and sign in. The recipe is added to your account and you get a personal webhook URL.
  2. In Healthchecks.io, open your project's Integrations and add a Webhook integration.
  3. Use your webhook URL with method POST and the body and header from the setup notes below, for both down and up.https://••••••••/•••••••• your personal URL, shown after install
  4. Enable the integration on the checks that should notify you, then press Test.
  5. In Healthchecks.io, open your project's **Integrations → Webhook**. Fill in **both** the "goes down" and "goes up" sections the same way:
  6. **URL:** the URL above, method **POST**
  7. **Request headers:** `Content-Type: application/json`
  8. **Request body:**
  9. ```json
  10. {
  11. "status": "$STATUS",
  12. "now": "$NOW",
  13. "exitstatus": $EXITSTATUS,
  14. "check": $JSON
  15. }
  16. ```
  17. Then enable the integration on your checks and press **Test**. `$JSON` stays valid JSON even when a check's name contains quotes. For a self-hosted Healthchecks, change `HEALTHCHECKS_URL` at the top of the code.
  18. Healthchecks.io doesn't sign webhooks, so keep your endpoint URL private.
The code

What runs when the webhook arrives

Studio calls handleRequest(request) with the incoming webhook and sends the message it returns. It's yours after install; change anything.

transform.js
1// Healthchecks.io → check down or back up
2// Fires when a Healthchecks.io check misses its ping (or reports a failure) and when it
3// recovers, using the webhook body from INSTALL.md.
4// Docs: https://healthchecks.io/docs/configuring_notifications/
5
6// Where "View check" links go; change this for a self-hosted Healthchecks.
7const HEALTHCHECKS_URL = "https://healthchecks.io"
8
9// "4m 12s" / "2h 5m" from a number of seconds.
10function duration(seconds) {
11 const s = Math.round(Number(seconds))
12 if (!Number.isFinite(s) || s <= 0) return null
13 if (s < 60) return `${s}s`
14 if (s < 3600) return `${Math.floor(s / 60)}m ${s % 60}s`
15 return `${Math.floor(s / 3600)}h ${Math.floor((s % 3600) / 60)}m`
16}
17
18// Only link to real http(s) URLs.
19function link(url, cta) {
20 return typeof url === "string" && /^https?:\/\//.test(url) ? [{ cta, url }] : []
21}
22
23function handleRequest(request) {
24 const body = request.body || {}
25 const check = body.check && typeof body.check === "object" ? body.check : {}
26 const status = body.status ?? check.status
27
28 // Guard: only the down/up webhook from INSTALL.md.
29 if (!["down", "up"].includes(status)) {
30 console.log(`Not a Healthchecks.io status change ("${status ?? "unknown"}") — skipping`)
31 return null
32 }
33
34 const name = check.name || body.name || "Your check"
35 const tags = typeof check.tags === "string" && check.tags.trim() ? check.tags.trim().split(/\s+/).join(", ") : null
36 const url = check.uuid ? `${HEALTHCHECKS_URL}/checks/${check.uuid}/details/` : null
37 const exit = Number(body.exitstatus)
38
39 if (status === "down") {
40 const why = Number.isFinite(exit) && exit > 0 ? `Last run exited with ${exit}` : "It missed its expected ping"
41 return {
42 title: `🔴 ${name} is down`,
43 message: why + (tags ? ` · ${tags}` : ""),
44 topic: "Healthchecks.io",
45 priority: 1, // High — a job you rely on stopped reporting in
46 buttons: link(url, "View check"),
47 }
48 }
49
50 const took = duration(check.last_duration)
51
52 return {
53 title: `✅ ${name} is back up`,
54 message: (took ? `Last run took ${took}` : "It's pinging again") + (tags ? ` · ${tags}` : ""),
55 topic: "Healthchecks.io",
56 priority: -1, // Low — back to normal
57 buttons: link(url, "View check"),
58 }
59}
Payload

The Healthchecks.io status webhook

This is what Healthchecks.io sends to your URL for check status. It is a sample, trimmed to the fields recipes use.

status · sample.json
1{
2 "now": "2026-09-29T03:15:00+00:00",
3 "check": {
4 "desc": "pg_dump to B2",
5 "name": "Nightly backup",
6 "slug": "nightly-backup",
7 "tags": "prod backups",
8 "uuid": "5f1c9a44-0e3b-4e7c-9d2a-7c1e8b3f6a90",
9 "grace": 3600,
10 "status": "down",
11 "methods": "",
12 "n_pings": 412,
13 "started": false,
14 "ping_url": "https://hc-ping.com/5f1c9a44-0e3b-4e7c-9d2a-7c1e8b3f6a90",
15 "last_ping": "2026-09-29T02:00:04+00:00",
16 "next_ping": null,
17 "last_duration": 312,
18 "manual_resume": false
19 },
20 "status": "down",
21 "exitstatus": 1
22}
FAQ

Healthchecks.io check down or up notifications: questions

Does this work on iPhone and Android?

Yes. Install the JustPush app from the App Store or Google Play and sign in. Every phone signed in to your account gets the notification.

Do I need to write code?

No. Install the recipe in Studio, paste your webhook URL into Healthchecks.io and you are done. The code is there if you want to change the text, the sound or the buttons.

Can I change what the notification says?

Yes. After install the recipe's code is yours. Edit it in Studio and test it against the sample payload before you save.

What does it cost?

JustPush is free for 30 days. After that it's $19.99 a year, or $39.99 once. There is no extra charge for recipes.

Ready when you are

Healthchecks.io on your phone in two minutes.

Install the recipe, paste one URL, done. Free for 30 days, no credit card required.