Pingdom check alert notifications on your phone.

Get a Highest-priority push notification when a Pingdom uptime check goes down or a transaction check starts failing, 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 Pingdom

Add it as a webhook for State change webhook.

STEP 03

Get a push on your phone

With the text, sound and buttons from the recipe.

Setup

How to set up the Pingdom state change webhook 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 My Pingdom, open Integrations > Integrations and click Add new.
  3. Give it a name, paste your webhook URL as the URL and click Save integration.https://••••••••/•••••••• your personal URL, shown after install
  4. Open each uptime or transaction check that should notify you and tick the new webhook.
  5. In My Pingdom, open **Integrations → Integrations** and click **Add new**. Give the integration a name, paste the URL above into the **URL** field and click **Save integration**.
  6. Then open each check under **Monitoring → Uptime** (or your transaction checks) and tick the new webhook. Pingdom sends one JSON POST per state change: **UP ↔ DOWN** for uptime checks (HTTP, TCP, Ping, DNS, UDP, SMTP, POP3, IMAP) and **SUCCESS ↔ FAILING** for transaction checks. Every check type works with this recipe.
  7. These are Pingdom's *state change* webhooks, not BeepManager webhooks, which have a different payload and aren't supported here.
  8. A test webhook sent from My Pingdom arrives as a quiet "Pingdom connected" push. A down alert is Highest priority, or High when the check's alert importance is set to low (Pingdom's docs only show the `HIGH` value, so the low value is assumed).
  9. Pingdom doesn't document signing or retries for 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// Pingdom → state change webhook (uptime and transaction checks)
2// Fires when an uptime check goes UP ↔ DOWN, or a transaction check goes SUCCESS ↔ FAILING.
3// Docs: https://www.pingdom.com/resources/webhooks/
4
5// Each state, how to word it, and how loud to be.
6const STATES = {
7 DOWN: { emoji: "🔴", verb: "is down", bad: true },
8 FAILING: { emoji: "🔴", verb: "is failing", bad: true },
9 UP: { emoji: "✅", verb: "is back up", bad: false },
10 SUCCESS: { emoji: "✅", verb: "is passing again", bad: false },
11}
12
13// Pingdom's check types, in words. Anything unlisted falls back to "Check".
14const TYPES = {
15 HTTP: "HTTP check",
16 HTTP_CUSTOM: "HTTP custom check",
17 PORT_TCP: "TCP check",
18 PING: "Ping check",
19 DNS: "DNS check",
20 UDP: "UDP check",
21 SMTP: "SMTP check",
22 POP3: "POP3 check",
23 IMAP: "IMAP check",
24 TRANSACTION: "Transaction check",
25}
26
27// Table lookup that ignores inherited keys like "toString".
28function pick(table, key, fallback) {
29 return typeof key === "string" && Object.prototype.hasOwnProperty.call(table, key) ? table[key] : fallback
30}
31
32// Only link to real http(s) URLs.
33function link(url, cta) {
34 return typeof url === "string" && /^https?:\/\//.test(url) ? [{ cta, url }] : []
35}
36
37// A trimmed string, or null when empty or not a string/number.
38function text(value) {
39 if (typeof value !== "string" && typeof value !== "number") return null
40 const s = String(value).trim()
41 return s || null
42}
43
44function handleRequest(request) {
45 const body = request.body && typeof request.body === "object" ? request.body : {}
46 const state = pick(STATES, text(body.current_state)?.toUpperCase(), null)
47
48 // Guard: Pingdom sends no event header, so recognise its state change payload by shape.
49 if (body.check_id == null || !state) {
50 console.log("Not a Pingdom state change webhook — skipping")
51 return null
52 }
53
54 const params = body.check_params && typeof body.check_params === "object" ? body.check_params : {}
55 const type = text(body.check_type)?.toUpperCase()
56 const name = text(body.check_name) ?? text(params.hostname) ?? pick(TYPES, type, "Your Pingdom check")
57 // Uptime checks carry full_url; transaction checks put the start URL in url.
58 const url = [params.full_url, params.url].map(text).find((u) => u && /^https?:\/\//.test(u)) ?? null
59 const where = url ?? text(params.hostname)
60 const buttons = link(url, "Open site")
61
62 // "Test" in My Pingdom sends description "test" and this long_description.
63 const longText = text(body.long_description)
64 if (text(body.description) === "test" || /test message triggered by a user/i.test(longText ?? "")) {
65 return {
66 title: "🔔 Pingdom connected",
67 message: `Test webhook for ${name} received`,
68 topic: "Pingdom",
69 priority: -1, // Low — just confirming the setup works
70 }
71 }
72
73 if (state.bad) {
74 const reason = text(body.description) ?? longText
75 const low = text(body.importance_level)?.toUpperCase() === "LOW"
76 return {
77 title: `${state.emoji} ${name} ${state.verb}`,
78 message: [reason, where].filter(Boolean).join(" · ") || `${pick(TYPES, type, "Check")} ${state.verb}`,
79 topic: "Pingdom",
80 // Highest — the site or user flow is broken right now. High when the check's
81 // alert importance is set to low in Pingdom.
82 priority: low ? 1 : 2,
83 buttons,
84 }
85 }
86
87 // Recovery: description is "OK" (uptime) or empty (transaction), so show where instead.
88 return {
89 title: `${state.emoji} ${name} ${state.verb}`,
90 message: where ? `Recovered · ${where}` : `${pick(TYPES, type, "Check")} recovered`,
91 topic: "Pingdom",
92 priority: -1, // Low — good news, nothing to do
93 buttons,
94 }
95}
Payload

The Pingdom state_change webhook

This is what Pingdom sends to your URL for state change webhook. It is a sample, trimmed to the fields recipes use.

state_change · sample.json
1{
2 "tags": [
3 "production"
4 ],
5 "check_id": 8123456,
6 "check_name": "Acme website",
7 "check_type": "HTTP",
8 "description": "HTTP Error 503",
9 "first_probe": {
10 "ip": "192.0.2.10",
11 "ipv6": "2001:db8::10",
12 "location": "Stockholm, Sweden"
13 },
14 "check_params": {
15 "url": "/",
16 "ipv6": false,
17 "port": 443,
18 "header": "User-Agent:Pingdom.com_bot",
19 "full_url": "https://www.example.com/",
20 "hostname": "www.example.com",
21 "basic_auth": false,
22 "encryption": true
23 },
24 "second_probe": {
25 "ip": "192.0.2.20",
26 "ipv6": "",
27 "version": 1,
28 "location": "Austin, US"
29 },
30 "current_state": "DOWN",
31 "previous_state": "UP",
32 "importance_level": "HIGH",
33 "long_description": "HTTP Server Error 503 Service Unavailable",
34 "state_changed_utc_time": "2026-09-21T14:13:20",
35 "state_changed_timestamp": 1790000000
36}
FAQ

Pingdom check alert 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 Pingdom 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

Pingdom on your phone in two minutes.

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