How to Monitor a Cron Job in Python
Picture this: a Python script has been quietly failing every night for two weeks because a dependency changed its API, and the only reason anyone noticed is that finance asked why last month's report never arrived. No traceback ever reached a human. No alert ever fired. The script just stopped doing its job, silently, exactly like cron jobs tend to when nobody's specifically watching them.
That's what a heartbeat is for. Your script pings a unique URL when it finishes, and if that ping goes missing on schedule, you find out immediately instead of two weeks later. Here's how to add that to a Python cron job using the Downdar API.
What You Will Need
A Downdar API key from your account, and the requests library (pip install requests). Authentication is via Bearer token in the Authorization header. Your API key must always be kept server-side, never commit it to version control or embed it in client-facing code.
Creating a Heartbeat Monitor
The /api/v1/heartbeats/create endpoint accepts a POST request with a name and returns the full heartbeat object, including the unique url your job will call on schedule. You only need to do this once per job, not on every run. If scripting this isn't necessary for your setup, you can just as easily create the heartbeat from your Downdar dashboard and copy the URL, the API is mainly there for provisioning heartbeats automatically as part of a deploy pipeline.
The response looks like this:
Save the url field somewhere your job can reach it, an environment variable is the simplest option. You can also pass alert_channel_keys in the create request if you want this heartbeat routed to a specific Slack, Discord, or Telegram channel instead of the default.
Pinging the Heartbeat From Your Job
Once the heartbeat exists, the actual monitoring is a single HTTP request to its url at the end of a successful run. No library beyond requests is needed.
The important detail is in the except block: only ping the heartbeat when the job actually succeeds. If generate_report() raises, skip the ping entirely, the heartbeat will notice the missing check-in on its own schedule and open an incident. This is what catches a silent failure, if you pinged unconditionally in a finally block instead, a broken job would still report as healthy.
If your job runs as a standalone script rather than something with its own error handling, the same call works from crontab directly:
The && means curl only runs if the Python script exits successfully. If report.py exits with a non-zero status, the ping never fires, and a missed check-in is exactly what should happen.
Checking Heartbeat Status Programmatically
If you want to surface a heartbeat's current state in your own dashboard or admin panel, the /api/v1/heartbeats/status endpoint returns just the essentials, lighter than a full get call.
status reflects the heartbeat's current state directly, so you can show "last report: healthy" somewhere your team already looks, without them needing to check Downdar itself.
A Note on API Key Security
Store your API key as an environment variable and never hardcode it. The python-dotenv package (pip install python-dotenv) makes this easy to manage locally.
Unlike the API key, the heartbeat URL itself isn't sensitive in the same way, it only accepts a check-in and can't read or modify anything in your account, so it's fine to keep alongside your other deploy config. The API key is what actually needs protecting here.
Get Started
You can set this up in about the time it takes to run the script once. Create the heartbeat, drop the URL into your environment, and the next scheduled run is already being watched.