Send Grafana alerts to WhatsApp
A contact point, a URL and a key. No phone number of your own, no Meta business account, no message template, and nothing running in between.
Every other answer to this needs something in the middle — a messaging account you pay separately for, or a small service you write and then have to keep alive, which is a strange thing to put in charge of telling you that things have stopped working. This route reads Grafana's own webhook body, so there is nothing between Grafana and the phone.
It takes about two minutes, and the first three alerts are free.
1. Make a key
In the Jabee dashboard, go to Management then
Approvals and create an API key. It starts jak_. Copy
it now; it is not shown again.
Whoever is going to be woken up needs a verified phone, which they get by tapping a link in the dashboard and sending one message. Until somebody has done that there is nobody to deliver to.
2. Add the contact point
In Grafana: Alerting → Contact points → Add contact point, and choose Webhook as the integration.
URL https://api.jabee.ai/api/v1/alerts/grafana
Method POST
Then open Optional Webhook settings and set the authorisation header:
Authorization Header Scheme Bearer
Authorization Header Credentials jak_your_key_here
That is the whole configuration. Leave everything else alone — in particular, you do not need a notification template, and you do not need Grafana 12. The route reads the body Grafana sends by default, which is the point of it.
Press Test. A WhatsApp message should arrive in about a second.
3. Point a notification policy at it
A contact point does nothing until something routes to it: Alerting → Notification policies, then either make it the default or add a child policy matching the labels you care about.
Worth setting deliberately rather than leaving at the default: Group wait, Group interval and Repeat interval. They decide how often a continuing problem messages you again, and on WhatsApp that is the difference between being informed and being nagged. A repeat interval of four hours is a reasonable starting point for something that wakes a person.
What arrives
Grafana groups alerts, so a bad minute is one notification carrying several problems. That arrives as one WhatsApp message, not one per alert — which is both quieter and the difference between spending three of your monthly allowance and spending twenty:
3 alerts firing: DiskPressure, HighLatency, QueueBacklog
Disk is nearly full
• DiskPressure — instance=db-1 — A=94.24
• HighLatency — instance=api-2
• QueueBacklog — instance=worker-1
https://grafana.example/d/abc
Eight alerts get a line each; beyond that they are counted
(and 12 more), including any Grafana itself truncated. The link is the
dashboard the first alert came from, falling back to the panel, then the alert rule,
then your Grafana front page.
If you already use a notification template, its title and message are sent as you wrote them. Somebody who went to that trouble has said what they want the message to read like, and overriding it would be a strange thanks.
Sending it to the right person
A monitoring tool will not let you write the request body, so addressing lives on the query string. Add it to the contact point's URL:
| Add to the URL | What it does |
|---|---|
?resolved=true | Also be told when things recover. Off by default. |
?resolved=true is the only parameter this route reads. There is
nothing to address: alerts go to the one phone this business has verified, or the
account owner's.
Recovery messages are off unless you ask
Grafana posts again with status: "resolved" when a problem clears.
Passing those on doubles the messages per incident, so they are dropped unless the
URL says ?resolved=true.
A dropped one answers 200 OK with
{"ignored": "resolved"} rather than an error. That is deliberate:
Grafana treats any 4xx or 5xx as a failed delivery and retries it, and there is no
number of retries that will make us want a message you have switched off.
Prometheus Alertmanager works on the same URL
Grafana's webhook body is Alertmanager's, extended — so Alertmanager, and anything that speaks its shape, posts to exactly the same place:
receivers:
- name: jabee
webhook_configs:
- url: https://api.jabee.ai/api/v1/alerts/grafana
send_resolved: false
http_config:
authorization:
type: Bearer
credentials: jak_your_key_here
send_resolved is worth setting explicitly, because Alertmanager
defaults it to true. Left alone, it posts every recovery and this
end drops every one of them — harmless, and a lot of pointless requests. Set
it to false, or leave it true and add ?resolved=true to
the URL if you want the all-clear.
One honest caveat: no deduplication
If Grafana retries a delivery it never saw succeed, you may get the same message twice.
That is a deliberate choice rather than an oversight. The obvious thing to
deduplicate on is Grafana's groupKey, and it is the wrong key: Grafana
reuses it for every repeat of an ongoing incident, so suppressing on it would
silence exactly the reminders your repeat interval exists to send — and a
later, genuinely new incident on the same group would be swallowed by the first one.
A duplicate message is a smaller harm than an alert that never arrives, so that is
the trade we made.
What it costs
$29 a month for 500 alerts and approvals together, then 3 cents each. The first three are free, so you can wire up the contact point, press Test, and watch one arrive before paying for anything.
No per-seat charge. Remember that one notification is one alert here however many problems it carries, so the 500 goes further than it looks if your grouping is sensible.
Questions
Do I need a WhatsApp number or a Meta account?
No, neither, at any point. The message goes over Meta's official Cloud API on Jabee's registered number using Jabee's approved template, so you need an API key and nothing else. There is no number of yours involved, so there is nothing of yours to get banned.
Does this need Grafana 12?
No. Grafana 12 added custom webhook payloads, which would let you reshape the body yourself — but this route reads the default body, so any Grafana that can send a webhook with an authorisation header works, Grafana Cloud included.
Can it message my customers?
No, deliberately. It reaches your own people, once they have verified their phone. A shared number messaging strangers is what gets numbers banned. To reach customers you connect your own number, which is the inbox.
What happens when twenty things break at once?
Grafana groups them into one notification and you get one WhatsApp message naming the first few and counting the rest, with the dashboard link for the detail. It costs one alert against your allowance, not twenty.
Can I send to different teams for different alerts?
Not on Jabee's number. Alerts go to one phone per business — the account owner's, or an ops handset you verify in the dashboard, under Where alerts go — so there is nothing to address. To route different alerts to different people, connect your own WhatsApp number and send from there.
Why did my test send nothing?
Most often no phone is verified yet — open the dashboard, tap the link
and send the one message it writes for you. After that, check the key is on the
Authorization header as Bearer jak_..., and that you are
not sending only recoveries with ?resolved=true absent.