SMSTunnel for Prometheus Alertmanager
Alert texts from your own phone and number
Firing alerts, by text
When an alert group fires, or resolves, Alertmanager hands it to your SMSTunnel account and your own Android phone texts it to you from your own number. Alertmanager's grouping and repeat settings decide how often, so one incident is one text.
1. Get your key
- 1. Install the SMSTunnel app from Google Play on your Android phone and sign in.
- 2. In your dashboard, open Apps → Add an app, pick Script or server, name it (for example "Alertmanager") and click Create the key.
- 3. Copy the key right away: it's shown only once. You can stop or delete the app there anytime, and Alertmanager can't send texts anymore.
Get the steps with your key in them
It opens Add an app with Script or server picked. Once the key is made, the dashboard shows every step and command with the key already filled in, ready to copy.
On Alertmanager before 0.32, or to skip the key on any version, use a webhook address.
2. Add the receiver (Alertmanager 0.32+)
Put the key in a file Alertmanager can read, so it stays out of the config:
printf '%s' 'sk_live_...' > /etc/alertmanager/smstunnel.key
chmod 600 /etc/alertmanager/smstunnel.key Then add this to alertmanager.yml and reload Alertmanager:
route:
receiver: sms-me
group_by: ['alertname']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receivers:
- name: sms-me
webhook_configs:
- url: https://smstunnel.io/api/v1/sms/send
http_config:
http_headers:
X-API-Key:
files: ['/etc/alertmanager/smstunnel.key']
payload:
to: '+1 415 555 0123'
message: '[{{ .Status | toUpper }}] {{ .CommonLabels.alertname }} - {{ (index .Alerts 0).Annotations.summary }}' - Write the number with spaces, like
'+1 415 555 0123'. Alertmanager reads each value inpayloadas YAML once it's filled in: a bare+14155550123turns into a number, loses its+, and the text goes to the wrong number. SMSTunnel removes the spaces. - Keep the text starting with
[, as above. A text likeFIRING: DiskFullcan be read as YAML too, and then it isn't text anymore.
3. Test it
Send Alertmanager a test alert; your phone texts it within the group wait (30 seconds above):
curl -X POST http://localhost:9093/api/v2/alerts \
-H "Content-Type: application/json" \
-d '[{"labels": {"alertname": "SMSTest", "instance": "nas1"},
"annotations": {"summary": "Test text from Alertmanager"}}]' [FIRING] DiskFull - Disk 95% full: /volume1 on nas1
[RESOLVED] DiskFull - Disk 95% full: /volume1 on nas1 The easy way, on any version: a webhook address
A webhook address is a secret URL that turns each call into a text to the numbers you save with it, sent by your own phone from your own number. The call only sets the words, never the number, so Alertmanager needs no key.
- 1. Install the SMSTunnel app from Google Play on your Android phone and sign in.
- 2. In your dashboard, open Apps → Webhooks, click New webhook and pick Alertmanager. That fills in the name. Leave Text of the message empty, so the words come from each call.
- 3. Add the numbers that should get the texts, with
+and the country code: up to 10, and each one gets its own text. Then click Create the webhook. - 4. Copy the address, which looks like
https://smstunnel.io/api/v1/webhook/<token>. Keep it secret, like a password: whoever has it can text these numbers from your phone, though never any other number.
Get the steps with your address in them
It opens New webhook with Alertmanager picked. Once the webhook is made, the dashboard shows its address and the Alertmanager steps with the address already in them, ready to copy, and Send a test, which texts the webhook's numbers.
- Calls an hour: 20 unless you set another number, up to 500. The limit counts calls, not texts: each call texts every number of the webhook, and a test from the dashboard counts too. Past the limit, calls are refused until the hour is over, so a storm of alerts can't use up your texts.
- You can copy the address again anytime, under Address and setup. If it gets out, New address in the webhook's menu replaces it, and the old one stops working at once.
- SMSTunnel reads Alertmanager's own alerts: their status, name and summary. Texts are cut at 480 characters.
-
Or with the API, for scripts:
POST /api/v1/webhookswith your sign-in token, as the webhooks guide shows.
Then, in Alertmanager
In alertmanager.yml, add this receiver with the webhook's address, and send it the
alerts that deserve a text with receiver: sms on a route. Then reload Alertmanager:
route:
receiver: sms
group_by: ['alertname']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receivers:
- name: sms
webhook_configs:
- url: https://smstunnel.io/api/v1/webhook/<token> SMSTunnel reads Alertmanager's own alerts: one text per group, to each number saved in the webhook, with "(+2 more)" when a group holds several alerts. The test alert above works here too.
[FIRING] DiskFull - Disk 95% full: /volume1
[RESOLVED] DiskFull - Disk 95% full: /volume1 Worth knowing
- Resolved alerts text too:
send_resolvedis on by default for webhooks.repeat_intervalresends a firing alert (every 4 hours above). - Several people? One webhook address texts up to 10 numbers, each its own text. With a key,
one
webhook_configsentry per number, each with its ownto: SMSTunnel sends one text to one number per request. - Route only what deserves a text, for example with
matchers: ['severity="critical"']on a child route. - 30 sends a minute; a text can be up to 1600 characters (480 through a webhook address, which
takes 20 calls an hour unless you raise it). Alertmanager doesn't retry a
429right away: the group tries again at its nextgroup_interval. - Phone offline? The text waits and goes out as soon as the phone is back.
If it doesn't work
- A text went to a strange number, like
+4014155550123: the number inpayloadwas written without spaces. Write it as'+1 415 555 0123'. -
400"property version should not exist" (or groupKey, alerts…): Alertmanager sent its default JSON to the API URL.payloadneeds Alertmanager 0.32 or newer; on older versions use a webhook address. -
Alertmanager logs the answer: look for
Notify for alerts failedandunexpected status code. -
401"Invalid or expired API key": the key is wrong or was deleted. "API key is required. Use X-API-Key header.": the key isn't in anX-API-Keyheader. SMSTunnel reads the key only from that header: Bearer or Basic authentication won't work. -
403withPERMISSION_REQUIRED: the key may not send texts. Make a new one under Apps → Add an app. -
400"property … should not exist": the body has a field SMSTunnel doesn't know. Send onlytoandmessage(and, if you need them,deviceIdanddefaultCountryCode). "message must be shorter than or equal to 1600 characters": shorten the text. "Phone number must contain…": put the number in international format, like+14155550123. -
400with "to must be a string" and "message must be a string": the body didn't arrive as JSON. Add the headerContent-Type: application/json. -
404"Cannot GET /api/v1/sms/send": the tool sent a GET. Choose POST. -
404"Webhook not found or disabled": the address is wrong, was replaced with New address, or the webhook is stopped or deleted. Copy it again from Apps → Webhooks → Address and setup. -
400"Could not build a message from the payload": the call had no words in it. Add?message=…to a GET, or amessagefield to the JSON. With a text of the message, check that the names between braces are the call's. -
429: too many texts at once. SMSTunnel takes 30 send requests a minute. Wait a minute and try again. -
429"Rate limit reached for this webhook (20/hour)": the webhook took all its calls for this hour. Wait, or raise Calls an hour (up to 500) with Edit in Apps → Webhooks. It counts calls, not texts: each call texts every number of the webhook. - In Apps → Webhooks, the webhook's row shows when it was last used and, if its last call sent no text, why.
- No text, but no error? If your phone is offline, the text waits and goes out as soon as the phone is back online. Open the SMSTunnel app on the phone to check it's linked.
Build it with an AI assistant
Copy this prompt into Claude, ChatGPT, Cursor or Copilot and replace the part in [brackets]. Don't paste your API key into the chat: the prompt doesn't need it.
Help me get Prometheus Alertmanager alerts as text messages from my own phone, with SMSTunnel.
About SMSTunnel (https://smstunnel.io): my own apps and tools hand text messages (SMS) to my SMSTunnel account, and my own Android phone sends them from my own number, on my own SIM and plan. The phone runs the SMSTunnel app from Google Play (https://play.google.com/store/apps/details?id=io.smstunnel.app), signed in to my account.
What I want: [describe what should send a text, to whom, and when]
How it works:
- No plugin. The easy way, on any Alertmanager version: an SMSTunnel webhook address (made in my dashboard with Alertmanager picked) as a webhook_configs receiver's url. With an API key instead, on Alertmanager 0.32 or newer: a receiver with "payload" and "http_config.http_headers" calls SMSTunnel's API.
- Webhook address way (any version):
route:
receiver: sms
group_by: ['alertname']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receivers:
- name: sms
webhook_configs:
- url: https://smstunnel.io/api/v1/webhook/<token>
SMSTunnel reads Alertmanager's own JSON and texts "[FIRING] <alertname> - <summary>" (and "(+N more)" for groups) to the numbers saved in the webhook. Each notification of a group is one call.
- Without a key: an SMSTunnel webhook address, https://smstunnel.io/api/v1/webhook/<token>. I make it in my dashboard (https://dashboard.smstunnel.io): Apps → Webhooks → New webhook, pick the tool that will call it (Grafana, Uptime Kuma, Healthchecks, Gatus, Alertmanager, Odoo Online, or Something else), add 1 to 10 numbers (each gets its own text), optionally a text of the message that pulls fields out of the JSON with {{path}}, like {{alarm.name}}, then Create the webhook and copy the address. A GET with ?message=… or a POST with JSON (its message, text, title or body field) texts those numbers; the call never sets the number. Texts are cut at 480 characters. "Calls an hour" (20 unless I set another number, up to 500) counts calls, not texts: each call texts every number, and calls past it are refused until the hour is over. The address can be copied again under Address and setup; New address replaces it if it leaks. Scripts can make one with POST https://smstunnel.io/api/v1/webhooks and my sign-in token instead.
- API key way, config (0.32+):
route:
receiver: sms-me
group_by: ['alertname']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receivers:
- name: sms-me
webhook_configs:
- url: https://smstunnel.io/api/v1/sms/send
http_config:
http_headers:
X-API-Key:
files: ['/etc/alertmanager/smstunnel.key']
payload:
to: '+1 415 555 0123'
message: '[{{ .Status | toUpper }}] {{ .CommonLabels.alertname }} - {{ (index .Alerts 0).Annotations.summary }}'
The key file holds only the key (no newline). "secrets: ['<key>']" works too but keeps the key in the config.
- Careful with the API key way: Alertmanager reads every rendered payload value as YAML. A bare +14155550123 turns into a number without its +, and SMSTunnel then adds the phone's country code: a wrong number. Write the number with spaces, like '+1 415 555 0123' (SMSTunnel removes them). A text like "FIRING: x" can turn into a map: keep it starting with "[", as above. toJson doesn't help in 0.32–0.34 (its quotes stay in the value).
- One recipient per request: SMSTunnel sends one text to one number. For several people, one request (or one notification) per number. With a key, one webhook_configs entry per number; a webhook address texts up to 10 numbers itself.
- send_resolved is true by default for webhooks: resolved alerts text too. repeat_interval resends a firing alert (4h above).
- Test: curl -X POST http://localhost:9093/api/v2/alerts -H "Content-Type: application/json" -d '[{"labels": {"alertname": "SMSTest", "instance": "nas1"},
"annotations": {"summary": "Test text from Alertmanager"}}]'
- Answers: 200 {"success": true, "messageId": "…"}; 401 wrong or deleted key; 403 the key lacks a permission ("code": "PERMISSION_REQUIRED"); 400 a missing, unknown or too long field; 429 too many requests (30 sends a minute, with Retry-After): wait and retry; without Retry-After, the plan's limit for the day or month is reached. If my phone is offline the text waits and goes out when it is back, within 3 days.
- The API key comes from my SMSTunnel dashboard (https://dashboard.smstunnel.io): Apps → Add an app → Create the key. It is shown only once and can send texts and check whether they went out.
Rules for your answer:
- Do not ask for my SMSTunnel password or API key and do not put a real key in your answer; I will not paste it in this chat.
- Phone numbers must be in international format (+ and the country code).
- Help me test it with my own number first.
- Only send texts people expect from me. No unsolicited texts.
- Help me route only the alerts that deserve a text to this receiver, and avoid floods (grouping, repeat_interval, inhibit rules). Responsible use
Built for alerts to yourself and your team, and texts people expect from you. One text goes to one number. Sending unsolicited messages from a consumer SIM generally breaches mobile carrier terms of service.
Prometheus is a trademark of the Linux Foundation; Alertmanager is part of the Prometheus project. SMSTunnel is a third-party integration and is not affiliated with, endorsed by, or sponsored by the Prometheus project or the Linux Foundation.