Get a phone notification when a long-running script finishes
Stop checking your terminal. Add one line to any Python, Bash, or Node.js script and get an iPhone push notification the moment it finishes.
You kick off a script that takes 20 minutes and wander off to make coffee. Then you forget about it entirely. An hour later you come back to find it finished — or crashed — long ago. Here's how to make your phone tell you the moment any script completes, in any language, in one line of code.
Long-running scripts are a fact of developer life: training runs, data migrations, batch exports, model inference, ETL pipelines. Checking back manually is pure waste. You either check too early and interrupt your flow, or too late and lose momentum waiting around.
TheNotificationApp solves this with a single HTTP call at the end of your script. No SDK, no daemon, no configuration file. The notification arrives the moment the job is done.
What you'll need
| Requirement | Notes |
|---|---|
| TheNotificationApp | Free tier covers 100 notifications — download on the App Store |
| Your API key | Found in the app after creating a project |
| curl | Pre-installed on macOS and Linux. On Windows: use Git Bash or WSL |
| Any language runtime | Python, Node.js, Bash, Ruby, Go — any environment that can run a shell command or make an HTTP request |
The core idea
Every operating system lets you chain commands with &&. Whatever runs last in the chain sends the notification. So the pattern is always the same: run your thing, then ping the API.
The notification on your phone looks like this:
Script finished ✓ train.py · completed in 18m 42s
Step 1 — Get your API key
Download TheNotificationApp, sign in with Apple, and create a project — something like "Dev Scripts" or "Terminal". Tap into it and copy your API key. You'll use it in every example below.
Step 2 — The quickest option: one-liner in your terminal
The simplest way is to chain your command with && and append a curl call at the end. Works in any shell — zsh, bash, fish:
# Run your script, then notify on success
python train.py && \
curl -s -X POST https://thenotification.app/api/sendNotification \
-H "app_key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title": "Script finished ✓", "body": "train.py completed"}'
Note:&&only fires if your script exits with code0(success). If the script crashes, no notification is sent. Scroll down to the failure-aware version if you want alerts for both outcomes.
Step 3 — Add it inside your script (with timing)
For repeatable jobs, it's cleaner to embed the notification call directly in your script so you don't have to remember the && chain. These examples also track elapsed time.
Python
import requests, time
API_KEY = "YOUR_API_KEY"
start = time.time()
# --- your code here ---
time.sleep(2) # replace with real work
# ----------------------
elapsed = time.time() - start
mins, secs = int(elapsed // 60), int(elapsed % 60)
requests.post(
"https://thenotification.app/api/sendNotification",
headers={"app_key": API_KEY, "Content-Type": "application/json"},
json={
"title": "Script finished ✓",
"body": f"train.py · completed in {mins}m {secs}s"
}
)
Bash
#!/bin/bash
API_KEY="YOUR_API_KEY"
START=$(date +%s)
# --- your code here ---
sleep 2
# ----------------------
END=$(date +%s)
ELAPSED=$(( END - START ))
MINS=$(( ELAPSED / 60 ))
SECS=$(( ELAPSED % 60 ))
/usr/bin/curl -s -X POST https://thenotification.app/api/sendNotification \
-H "app_key: ${API_KEY}" \
-H "Content-Type: application/json" \
-d "{\"title\": \"Script finished ✓\", \"body\": \"run.sh · ${MINS}m ${SECS}s\"}"
Node.js
const start = Date.now();
// --- your code here ---
await doYourWork();
// ----------------------
const elapsed = Math.round((Date.now() - start) / 1000);
const mins = Math.floor(elapsed / 60);
const secs = elapsed % 60;
await fetch("https://thenotification.app/api/sendNotification", {
method: "POST",
headers: { "app_key": "YOUR_API_KEY", "Content-Type": "application/json" },
body: JSON.stringify({
title: "Script finished ✓",
body: `index.js · ${mins}m ${secs}s`
})
});
Handle both success and failure
The && trick only fires on success. For long jobs where you also want to know about crashes, use the exit code to notify on failure too:
#!/bin/bash
API_KEY="YOUR_API_KEY"
notify() {
/usr/bin/curl -s -X POST https://thenotification.app/api/sendNotification \
-H "app_key: ${API_KEY}" \
-H "Content-Type: application/json" \
-d "{\"title\": \"$1\", \"body\": \"$2\"}"
}
# Run your script
python train.py
if [ $? -eq 0 ]; then
notify "Script finished ✓" "train.py completed successfully"
else
notify "Script failed ✗" "train.py exited with an error — check your logs"
fi
Use it with any tool
Because the notification is just an HTTP call, it plugs into any environment that can run a shell command or make an HTTP request at the end of a job:
| Tool | How to attach |
|---|---|
| ffmpeg / Handbrake | Chain with && after the encode command |
| DaVinci Resolve | Use the post-render script field on the Deliver page — full guide here |
| Makefile | Add the curl call as the last line of a make target |
| Docker | Run the curl call inside your container's entrypoint or CMD after the main process |
| Jupyter Notebook | Add a requests.post() call in the final cell |
| GitHub Actions | Add a curl step at the end of your workflow |
Make it reusable with a shell alias
If you chain commands ad-hoc a lot, add a short alias to your shell config (~/.zshrc or ~/.bashrc):
# ~/.zshrc
function done-notify() {
/usr/bin/curl -s -X POST https://thenotification.app/api/sendNotification \
-H "app_key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title": "Done ✓", "body": "Command finished"}'
}
alias dn=done-notify
Then just append && dn to any command:
python train.py && dn
make build && dn
npm run test && dn
Troubleshooting
No notification arrives
Run the curl command in isolation from your terminal first. If that works, the issue is likely the execution environment — some tools run scripts with a stripped PATH. Use the full path /usr/bin/curl rather than just curl to avoid this.
Notification arrives but the body is wrong
JSON inside a double-quoted shell string needs escaped quotes (\"). The Python and Node.js examples avoid this entirely by passing a native dict or object — prefer those if the shell escaping gets tricky.
I only get notified on success, not failure
Switch from && (success only) to the if/else pattern shown above, which checks the exit code explicitly and sends different messages for each outcome.
Wrapping up
One line at the end of your script is all it takes. No background processes, no polling, no third-party scheduler — just a push notification delivered to your iPhone via Apple's infrastructure the moment the job is done.
The free tier includes 100 notifications — more than enough to get started. Questions? Reach out at contact@thenotification.app.
Related posts
If this was useful, these cover the same pattern in different contexts:
- Quick Start — Download the app, create a project, and send your first notification in under 2 minutes.
- Get a phone notification when your DaVinci Resolve render finishes — Same idea, but using Resolve's built-in post-render script field. No terminal chaining needed.
- Bash Docs — The official Bash integration guide with copy-paste examples.
- Python Docs — Python
requestsintegration reference. - JavaScript Docs — Node.js and browser
fetchexamples.
Stop babysitting your scripts.
Free to download. Free tier available. Swiss-hosted, private by design.
Stop babysitting your scripts.
Free to download. Free tier available. Swiss-hosted, private by design.