Send Free Push Notifications from Python and Bash Scripts Using ntfy.sh


When I started working on automation tasks, email notifications seemed like the easiest way to stay updated. However, managing email authentication and dealing with lengthy code quickly became complicated. The notifications also felt too generic for task updates, and they required a lot of extra setup. This made it clear that there was a need for a simpler, more efficient solution. Wouldn’t it be nice if we could get phone notifications instead of SMS or email, in addition to desktop notifications? And even better, what if all of this was free? That's where ntfy
came in.
ntfy
(pronounced "notify") is a lightweight, simple-to-use push notification system that can easily send messages to our phone or computer without the complications of emails.
What Is a Channel?
In ntfy
, messages are sent to a channel, which is just a topic name.
We can name our channel anything we like, such as test-backups or build-notify. Then, we can view or subscribe to it using a browser or the ntfy
mobile app. The only thing to keep in mind is that, since creating and subscribing to a generic channel doesn’t require an account, the channel name must be unique. If we want to ensure that no one else can access it, we should choose a name that is difficult for others to guess.
For example, here is a sample URL to access a channel in a web browser:
https://ntfy.sh/test-automation
Send Notifications from Python
Simple Notification
When running automation scripts, our main aim is to get notifications about task completion or errors. To send a basic notification from Python, use this single line of code:
import requests
requests.post("https://ntfy.sh/test-automation", data="Script completed")
Add a Title
We can add a title to our message, which will appear in bold in the notification. Here’s how we can add a title:
import requests
requests.post("https://ntfy.sh/test-automation", data="Backup completed", headers={"Title": "Backup Status"})
Send Priority Messages
Higher priority messages appear more strikingly. The priority can range from 1
(low) to 5
(high). Here's an example of how to set a high priority:
import requests
requests.post("https://ntfy.sh/test-automation", data="Disk space low", headers={"Title": "Alert", "Priority": "5"})
Email Notifications
ntfy supports forwarding notifications as emails by adding the "Email"
header with a valid recipient address. This is helpful when we want certain alerts to persist longer or also reach our inbox. Due to lack of authentication, email sending is rate-limited, allowing up to 16 emails per IP address, followed by one per hour. The sender’s IP is included in the email body to prevent abuse.
import requests
requests.post("https://ntfy.sh/test-automation", data="Disk space on server-1 has dropped below 10%", headers={"Email": "myemail@example.com", "Tags": "warning,disk-monitor", "Priority": "high"})
Clickable Links
We can include URLs in our message and they will automatically become clickable in the notification:
import requests
requests.post("https://ntfy.sh/test-automation", data="Check results: https://example.com/report")
File Attachment Links
We can attach external file links using the Attach
header:
import requests
requests.post("https://ntfy.sh/test-automation", data="Backup completed successfully", headers={"Title": "Backup Completed", "Attach": "https://example.com/report.pdf"})
Actual File Attachment
If we want to send an actual file (like a log or image) as an attachment, make sure to use a PUT
request instead of POST
, and include the filename in the headers. Here is how:
import requests
with open("log.txt", "rb") as f:
requests.put("https://ntfy.sh/test-automation", data=f, headers={"Title": "Backup Completed", "Filename": "log.txt"})
Add Emojis
We can tag our messages with emojis using the Tags
header. Tags must be comma-separated. If a tag matches a known emoji shortcode, ntfy will automatically convert it into an emoji and prepend it to the title or message. Tags that don't match an emoji will still appear as labels beneath the notification. This is especially useful for marking different types of alerts or organizing our messages visually. Refer to the complete list of supported emojis and their shortcodes here.
import requests
requests.post("https://ntfy.sh/test-automation", data="Backup completed successfully", headers={"Tags": "heavy_check_mark,nightly-job"})
Delayed Delivery
We can delay the delivery of messages and let ntfy send them at a later time. For this, we use the "In"
header to specify a relative delay in seconds, minutes, or hours. For example "10s"
for 10 seconds,"2m"
for 2 minutes and "3h"
for 3 hours.
We might think we can do the same thing with Python code that checks the target time in a loop and sends a notification when the time is right. But there is a reason to use ntfy instead. With Python, the script will stop and wait until the condition is met. But with ntfy, we can calculate the time difference between now and the target time, set a delayed notification, and keep the rest of the script running. The ntfy server will handle the waiting and send the notification at the right time. This makes the script simpler for us.
While ntfy also supports scheduling messages at an exact time using the "At"
header, we have not covered that in this article to avoid complications arising from time zone differences. We are only using relative delays (In
) for simplicity and predictability.
import requests
requests.post("https://ntfy.sh/test-automation", data="This message will be sent in 1 minute", headers={ "In": "1m" })
Sending JSON Messages
Instead of plain text, we can send a JSON payload when we need to send multiple pieces of information together:
import requests
requests.post("https://ntfy.sh", json={"topic": "test-automation", "message": "Job failed", "title": "Job Status", "priority": 5})
Send Notifications from Bash
Simple Notification
curl -d "Script completed" https://ntfy.sh/test-automation
Add a Title
curl -d "Backup completed" -H "Title: Backup Status" https://ntfy.sh/test-automation
Send Priority Messages
curl -d "Disk space low" -H "Title: Alert" -H "Priority: 5" https://ntfy.sh/test-automation
Email Notifications
curl -d "Disk space on server-1 has dropped below 10%" -H "Email: myemail@example.com" -H "Tags: warning,disk-monitor" -H "Priority: high" ntfy.sh/test-automation
Clickable Links
curl -d "Check results: https://example.com/report" https://ntfy.sh/test-automation
File Attachment Links
curl -d "Backup completed successfully" -H "Title: Backup Completed" -H "Attach: https://example.com/report.pdf" https://ntfy.sh/test-automation
Actual File Attachment
curl -T log.txt -H "Title: Backup Completed" -H "Filename: log.txt" https://ntfy.sh/test-automation
Add Emojis
curl -d "Backup completed successfully" -H "Tags: heavy_check_mark,nightly-job" https://ntfy.sh/test-automation
Delayed Delivery
curl -d "This message will be sent in 1 minute" -H "In: 1m" https://ntfy.sh/test-automation
Sending JSON Messages
curl -H "Content-Type: application/json" -d '{"topic":"test-automation","message":"Job failed","title":"Job Status","priority":5}' https://ntfy.sh
For more details, check the official documentation here.
Subscribe to my newsletter
Read articles from Ash directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Ash
Ash
DevOps Automation Engineer with around 7 years of experience in CI/CD pipeline automation, cloud deployments, and process optimization. Specializing in Harness CD, I have streamlined deployments, automated processes, reduced manual efforts, and improved release workflows.