Getting Started
Wire CronRadar into your scheduler in under a minute. The fastest path is the framework SDK matching your runtime — drop in a single line and every recurring job is monitored.
Prerequisites
- A CronRadar account — sign in at app.cronradar.com with GitHub, Google, or Microsoft.
- An Application in the dashboard. Applications group related monitors (e.g. Production, Staging). Each has its own API key.
- The API key — format
ck_app_xxxxx. Copy it once; CronRadar stores a hash and cannot show it again.
Treat API keys like passwords. They go in environment variables, not source code. CronRadar can revoke and reissue them, but it can never recover the original.
Pick your integration
| Your scheduler | Use this |
|---|---|
| Hangfire | CronRadar.Hangfire — MonitorAll() |
| Quartz.NET | CronRadar.Quartz — MonitorAll() |
| Celery | cronradar — @monitor decorator |
| Laravel scheduler | cronradar/laravel — ->monitor() |
| Bull / BullMQ | base cronradar (Node) — extension in flight |
| APScheduler | base cronradar (Python) |
| Plain crontab / shell | curl directly |
| Anything else | base SDK in your language → HTTP API |
If your scheduler is in the top half, use the framework SDK — auto-discovery does the work. If it's in the bottom half, use a base SDK or curl.
Framework SDK quickstart
Install the matching package and add one line. Every recurring job is now monitored. Opt out per-job with the language-idiomatic skip annotation.
// dotnet add package CronRadar.Hangfire
services.AddHangfire(config =>
config.MonitorAll(apiKey: "ck_app_demo_key")
);
[SkipMonitor]
public void InternalMaintenance()
{
// not monitored
}
The SDK pulls CRONRADAR_API_KEY from the environment. Pass it explicitly to MonitorAll(apiKey: ...) or set it as an env var — your call.
Base SDK / curl quickstart
For schedulers we don't have a framework extension for. The first ping with ?schedule= self-registers the monitor.
crontab / shell
0 2 * * * /path/to/backup.sh && \
curl 'https://cron.life/ping/daily-backup/ck_app_demo_key?schedule=0%202%20*%20*%20*'
Node.js
// npm install cronradar
const cronradar = require('cronradar');
await cronradar.monitor('daily-backup', { schedule: '0 2 * * *' });
Python
# pip install cronradar
import cronradar
cronradar.monitor('daily-backup', schedule='0 2 * * *')
.NET
// dotnet add package CronRadar
CronRadar.Monitor("daily-backup", schedule: "0 2 * * *");
PHP
// composer require cronradar/php
use CronRadar\CronRadar;
CronRadar::monitor('daily-backup', '0 2 * * *');
For lifecycle tracking (start / complete / fail), see the Lifecycle reference.
Authentication
Every request authenticates with your application's API key, format ck_app_{appId}_{secret}. There are two methods.
URL-based (recommended) — key in the path, no headers. Best for cron one-liners:
curl https://cron.life/ping/daily-backup/ck_app_demo_key
curl https://cron.life/ping/daily-backup/ck_app_demo_key/start
curl https://cron.life/ping/daily-backup/ck_app_demo_key/complete
Basic Auth (alternate) — key as the username, empty password. Required for the bulk sync endpoint, which sends a POST body:
curl -u ck_app_demo_key: https://cron.life/api/sync
API keys are hashed with SHA256 and shown once — CronRadar can revoke and reissue, but never recover them. Keep them in environment variables, never in source control, and use a separate key per environment.
Verify it works
After the first run:
- The monitor appears in your dashboard with status
pendinguntil the first ping arrives, then transitions tohealthy. - Recent pings are listed with timestamps and durations.
- If you provided
?schedule=, the next expected ping is calculated and shown. - You can trigger a test ping manually:
curl 'https://cron.life/ping/your-job/ck_app_demo_key'
If the dashboard shows the ping within a second or two, you're good.
Alerts
Email is on by default for everyone on the team. Add channels in Application Settings → Notifications:
- Slack — webhook URL or OAuth integration
- Discord — webhook URL
- PagerDuty — Events API v2 integration key
- Webhook — generic JSON POST to your endpoint
- Email — already on; add per-member preferences if needed
CronRadar sends alerts when:
- A monitor misses its expected ping plus grace period (
InitialFailure) - A failure persists past escalation thresholds (
ContinuedFailure) - A monitor was registered but never received its first ping (
NeverExecuted) - A previously failing monitor recovers (
Recovered)
Troubleshooting
401 Unauthorized
API key is wrong or missing. The URL-path format is /ping/{monitor_key}/{api_key} — confirm you have both segments.
curl https://cron.life/ping/your-job/ck_app_demo_key
404 Monitor Not Found
The monitor doesn't exist yet and you didn't include ?schedule=. Add it once to auto-create:
curl 'https://cron.life/ping/your-job/ck_app_demo_key?schedule=0%202%20*%20*%20*'
After the first ping, you can drop the schedule parameter on subsequent calls.
How do I URL-encode a cron schedule?
Spaces become %20. The SDKs handle this automatically; it only matters for hand-written curl. Full encoding table in the Ping reference.
Can I test without waiting for the schedule?
Yes — fire a ping manually with curl. The dashboard updates within seconds. The next expected ping recalculates from your provided schedule.