Webhooks
Any HTTP POST becomes an SMS
One URL, no integration code
Create a webhook, get a secret URL, paste it into any tool that can send an HTTP request. Uptime Kuma, Grafana, Prometheus Alertmanager, GitHub Actions, Zabbix, cron jobs, your own scripts — if it can POST, it can text you.
How it stays safe
Recipients are fixed when you create the webhook
The incoming payload can only influence what the message says — never who receives it. Phone numbers are never read from the request body.
This is deliberate. A webhook URL tends to end up in config files, dashboards and screenshots. If the payload could choose the recipient, anyone who saw the URL could send messages to any number at your expense — including premium-rate numbers.
Default 20/hour per webhook. An alert storm can't drain your quota or upset your carrier.
Optionally restrict which sources may trigger it. Exact IPs or CIDR ranges.
If a URL leaks, rotate it — the old one stops working immediately.
1. Create a webhook
curl -X POST https://smstunnel.io/api/v1/webhooks \
-H "Authorization: Bearer YOUR_JWT" \
-H "Content-Type: application/json" \
-d '{
"name": "Server alerts",
"recipients": ["+40712345678"],
"maxPerHour": 20
}' The response contains your secret URL:
{
"id": "...",
"token": "a1b2c3...",
"url": "/api/v1/webhook/a1b2c3..."
}
Full URL: https://smstunnel.io/api/v1/webhook/<token>
2. Trigger it
curl -X POST https://smstunnel.io/api/v1/webhook/<token> \
-H "Content-Type: application/json" \
-d '{"message": "Backup finished successfully"}'
A plain GET works too, for tools
that can only ping a URL — the query string becomes the payload:
…/webhook/<token>?message=Disk+almost+full
3. What the SMS says
Automatic (no configuration)
Common formats are recognised out of the box, so most tools work immediately:
- Uptime Kuma — monitor name, up/down status and message
- Prometheus Alertmanager / Grafana — status, alert name and summary
- Generic — any
message,text,title,bodyorsummaryfield
Custom template
Set messageTemplate and pull any
field out of the payload with {{path}},
including array indexes:
"[{{status}}] {{alerts.0.labels.alertname}} on {{alerts.0.labels.instance}}" Messages are trimmed to 480 characters — alerts should be short, and it keeps one noisy payload from consuming several SMS.
Ready-made setups
Uptime Kuma
Settings → Notifications → Setup Notification
- Notification Type: Webhook
- Post URL:
https://smstunnel.io/api/v1/webhook/<token> - Request Body: Preset - application/json
No template needed — the monitor name and up/down status are detected automatically.
Prometheus Alertmanager
receivers:
- name: sms
webhook_configs:
- url: https://smstunnel.io/api/v1/webhook/<token> Grafana
Alerting → Contact points → Add contact point → Webhook, then paste the URL. Grafana's unified alerting payload is recognised automatically.
GitHub Actions
- name: Notify on failure
if: failure()
run: |
curl -X POST "${{ secrets.SMS_WEBHOOK }}" \
-H "Content-Type: application/json" \
-d '{"message":"Build failed on ${{ github.repository }}"}' Cron / any script
0 3 * * * /opt/backup.sh || curl -s -X POST \
https://smstunnel.io/api/v1/webhook/<token> \
-H 'Content-Type: application/json' \
-d '{"message":"Nightly backup FAILED"}' Managing webhooks
| Endpoint | Purpose |
|---|---|
| GET /api/v1/webhooks | List, with usage counters |
| PATCH /api/v1/webhooks/:id | Change recipients, template, limits |
| POST /api/v1/webhooks/:id/rotate | Issue a new secret URL |
| DELETE /api/v1/webhooks/:id | Remove it |
All management endpoints require your account JWT.
Responsible use
Webhooks are meant for alerting and transactional notifications. Sending unsolicited bulk messages from a consumer SIM generally breaches mobile carrier terms — keep volumes low and make sure your usage complies with local regulations.
Prefer a visual workflow?
The n8n node gives you the same power with a drag-and-drop editor.
See the n8n integration