Free · Open Source · No Signup

Webhooks to
Telegram, Slack
& Discord.

POST any payload to your unique URL.
It lands in your chat within seconds.
No account. No dashboard. No config.

✈️ Telegram + 💬 Slack + 🎮 Discord

Type /start — get your URL in under 10 seconds.

pings delivered today
🪝
PingHookBot
bot
🔔 [ci-failed]
{
  "repo": "myapp",
  "branch": "main",
  "status": "failed",
  "run": 142
}
14:32
🔔 [payment-received]
{
  "amount": 49.00,
  "currency": "USD",
  "customer": "jane@acme.com"
}
14:35

Works with anything that can send a POST request

GitHub Actions Grafana n8n Zapier Make cron jobs Python scripts Node.js curl Uptime Kuma Prometheus AlertManager Any HTTP client

Three steps. Under a minute.

No email. No OAuth. No SDK.

1

Start the bot

Open Telegram, message @PingHookBot, and type /start. You get a unique webhook URL immediately.

2

Paste the URL anywhere

Add it to GitHub Actions, Grafana, n8n, a cron job, or just curl it from your terminal. If it sends HTTP, it works.

3

Get notified instantly

Every POST becomes a message in your Telegram chat. Optionally connect Slack or Discord via /connect slack and fan out to all three at once.

Everything you need. Nothing you don't.

📡

Multi-Channel Delivery

Fan out to Telegram, Slack, and Discord simultaneously. Connect Slack with /connect slack <url> — PingHook validates and sends a test ping before saving.

🏷️

Smart Labels

Tag events by source: /send/key/ci-failed, /send/key/payment-received. The label shows in every message and powers alerting rules.

Smart Formatting

JSON is auto-indented in a code block. Plain text supports Markdown — **bold**, _italic_, and ~~strikethrough~~ render natively.

🎯

The Label Is the Logic

Fire /send/KEY/ci-failed only when CI fails. Fire /send/KEY/payment-received only on success. When you own the code, the label carries the signal — no backend rules needed.

Zero Config

No SDK. No OAuth. No account. Your webhook URL is your only credential — paste it, POST to it, done. The Telegram bot is the entire control plane.

📜

History & Replay

Use /history to see your last 10 delivered pings with payload previews. Use /replay 3 to re-dispatch any ping to all channels — perfect for recovering a missed alert or testing a rule change.

Advanced

Alerting rules — for webhook sources you don't control (Grafana, Uptime Kuma, GitHub webhooks). Add keyword filters, dedup windows, quiet hours, or label whitelists from the bot with /rules. Rules are global per API key — see the docs section below for details.

100/hr
Rate limit (free tier)
100 KB
Max payload size
3 platforms
Delivery targets
<1s
Typical delivery time

Paste. Send. Done.

Replace YOUR_KEY with the URL from the bot.

# Send a JSON payload with a label
curl -X POST https://pinghook.dev/send/YOUR_KEY/ci-failed \
  -H "Content-Type: application/json" \
  -d '{"event":"test_failed","repo":"myapp","branch":"main","run":142}'

# Response
{ "status": "success", "channels_notified": 2 }
# Plain text — no Content-Type header needed
curl -X POST https://pinghook.dev/send/YOUR_KEY/cron-done \
  -d "Backup completed at $(date)"

# Fan out to one specific platform only
curl -X POST "https://pinghook.dev/send/YOUR_KEY/deploy?channel=slack" \
  -d "Deploy succeeded on main"
# Plain text with Markdown — renders natively in Telegram
curl -X POST https://pinghook.dev/send/YOUR_KEY/deploy \
  -d "**Deploy succeeded** on main

_Started by:_ asaf
_Duration:_ 42s
_Status:_ ~~failing~~ passing"

# Supported: **bold**  _italic_  ~~strikethrough~~
# JSON payloads are auto-formatted in a code block — no Markdown needed
# .github/workflows/notify.yml
- name: Notify via PingHook
  if: always()
  run: |
    curl -s -X POST \
      https://pinghook.dev/send/${{ secrets.PINGHOOK_KEY }}/github \
      -H "Content-Type: application/json" \
      -d '{
        "event": "workflow_${{ job.status }}",
        "repo": "${{ github.repository }}",
        "branch": "${{ github.ref_name }}",
        "run": "${{ github.run_number }}"
      }'
# pip install requests
import requests

PINGHOOK_URL = "https://pinghook.dev/send/YOUR_KEY"

requests.post(
    f"{PINGHOOK_URL}/payment-received",
    json={"amount": 49.00, "customer": "jane@acme.com"}
)

# Or plain text
requests.post(PINGHOOK_URL + "/cron-done", data="ETL pipeline finished")
📖 Full Documentation API reference · bot commands · alerting rules · demo

API Reference

One endpoint. No authentication headers — the API key lives in the path.

POST https://pinghook.dev/send/{api_key} POST https://pinghook.dev/send/{api_key}/{label} # Query params ?channel=telegram # send to one platform only (telegram | slack | discord) # Response { "status": "success", "channels_notified": 2 } { "status": "suppressed", "reason": "dedup" } { "status": "failed", "channels_notified": 0 }

The label is any URL path segment after your key — use slashes for hierarchy: /send/KEY/github/ci/prod. Max payload 100 KB. Supported Content-Type: application/json or plain text (or none).

Bot Commands

Command Description
/startCreate account and get your webhook URL
/mykeyShow your current webhook URL
/regen confirmInvalidate current key, get a new one; all channels notified
/channelsList connected delivery channels
/connect slack <url>Add a Slack Incoming Webhook URL
/connect discord <url>Add a Discord webhook URL
/disconnect <n>Remove channel by number from /channels
/rulesList active alerting rules
/rules add …Add a rule (see Alerting Rules below)
/rules remove <n>Remove rule by number
/rules clear confirmRemove all rules
/usagePing stats — today, this week, all time
/historyLast 10 successfully delivered pings with payload preview
/replay <n>Re-dispatch ping #n from /history to all channels
/helpShow command list

Alerting Rules (Advanced)

Rules are AND conditions — a ping is delivered only when every active rule passes. Add multiple rules to compose filters.

When do you need rules? Only for webhook sources you don't control — Grafana alerts, Uptime Kuma, GitHub webhooks, third-party SaaS. If you're writing the code that fires the webhook, use a conditional in your code and pick a specific label instead. That's simpler and more flexible.

/rules add keyword error

Only deliver if the payload contains "error" (case-insensitive).

/rules add dedup 30

Suppress the same label if it was delivered in the last 30 minutes.

/rules add quiet 23 7

No pings between 23:00 and 07:00 UTC. Supports overnight windows.

/rules add labels ci deploy

Only deliver pings whose label is "ci" or "deploy" — ignore everything else.

⚠️ Rules are global per API key. If you have multiple uncontrolled webhook sources (e.g. Grafana + GitHub) with conflicting rule needs, multi-key support is coming in a future update. For now, use labels to distinguish sources and keep rules simple.

Demo — From Zero to Notified

What a first session looks like in Telegram.

🪝
PingHookBot
bot
/start
👋 Welcome to PingHook!

Your webhook URL:
https://pinghook.dev/send/abc123…/your-label

Quick test — paste in terminal:
curl -X POST …/test -d "Hello!"
14:00
🔔 [test]
Hello!
14:00
/rules add dedup 10
✅ Added: suppress same label repeated within 10 min
14:01
/connect slack https://hooks.slack.com/…
✅ Slack channel connected and test ping sent.
14:02
/history
📜 Last deliveries:

1. test — 2 min ago
   Hello!
14:02
/replay 1
🔁 Replayed ping #1 (2 min ago)
Label: test
Delivered to 2/2 channel(s).
14:02

Common questions

How do I add Slack or Discord?

Open the Telegram bot and send /connect slack https://hooks.slack.com/... or /connect discord https://discord.com/api/webhooks/.... PingHook validates the URL with a test ping before saving. Once connected, all future webhooks fan out to every channel at once.

What's the rate limit?

Free tier: 100 requests per hour, 1,000 per day, per webhook URL. Payloads over 100 KB are rejected with a 413. The error response includes a resets_in field so you know exactly when you can retry.

What payload formats are supported?

JSON is auto-indented in a monospace code block. Plain text supports Markdown — **bold**, _italic_, and ~~strikethrough~~ all render natively in Telegram. Both formats support labels.

How do alerting rules work?

Rules are AND conditions — a ping is delivered only if all active rules pass. Use /rules add keyword error to filter by content, /rules add dedup 10 to suppress the same label within 10 minutes, /rules add quiet 22 8 for overnight silence, or /rules add labels ci-failed deploy-prod to whitelist specific labels.

What if someone gets my webhook URL?

The URL is write-only — it can only trigger notifications to your chat, never read data. If compromised, send /regen confirm in the bot. Your old key is invalidated immediately and all connected channels receive the new URL automatically.

Can I self-host this?

Yes. PingHook is fully open source. Clone the repo, add your own .env, run the schema in Supabase, and start with Uvicorn. The schema.sql creates everything in any PostgreSQL database.