Cron monitoring that installs itself.
Add one package to your Laravel or Node.js app and every scheduled job is monitored: run duration, exit codes, and the actual exception when something fails. Anything else can check in with a plain HTTP ping.
// composer require pingark/pingark-laravel $schedule->command('backup:run') ->daily()->pingArk('nightly-backup');Copy
// npm install pingark import { monitor } from 'pingark' await monitor(() => runNightlyJob(), 'nightly-job')Copy
// npm install pingark import { withPingArk } from 'pingark/next' export const GET = withPingArk(handler, { check: 'nightly-job' })Copy
# any cron, any language: one line at the end of the job curl -fsS https://pingark.com/ping/pk_live_a1b2c3d4/nightly-backup # duration too? ping /start firstCopy
Three moving parts. That is the whole idea.
Your job checks in
Drop in the Laravel plugin or the JS SDK, or add a curl at the end of any job. Send start, success, fail, or an exit code.
We hold the deadline
We expect the next ping on your schedule plus a grace window. State slides from up to late quietly, with no noise while it is still in grace.
You hear about it first
Past grace, or on an explicit failure, we flip it down and notify every channel you have armed. Recovery sends an all-clear.
One line, wherever the job runs.
The official Laravel package and JavaScript SDK do the heavy lifting: start and finish signals, run duration, exit codes, and exception context, wrapped for the tools you already use. And a bare curl still works from anything that can reach the network.
// routes/console.php or app/Console/Kernel.php $schedule->command('backup:run') ->daily() ->pingArk('nightly-backup'); // duration, exit code & exceptions: automatic // or mirror the whole schedule as checks, // one credential in .env and you are done // php artisan pingark:syncCopy
// npm install pingark import { monitor, log } from 'pingark' // start, success or failure, duration: automatic await monitor(() => runNightlyJob(), 'nightly-job') // optional notes on the check's timeline await log('nightly-job', 'processed 5,000 rows') // works on Node.js 18+, Bun, Deno, and the edgeCopy
// app/api/cron/nightly/route.ts import { withPingArk } from 'pingark/next' export const GET = withPingArk( async () => { await runNightlyJob() return Response.json({ ok: true }) }, { check: 'nightly-job' }, )Copy
import express from 'express' import { pingarkExpress } from 'pingark/express' const app = express() // start on arrival, success on finish, failure on a 5xx app.get('/cron/nightly', pingarkExpress('nightly-job'), (req, res) => { runNightlyJob() res.send('ok') })Copy
// server/tasks/nightly.ts import { withPingArk } from 'pingark/nuxt' export default defineTask({ meta: { name: 'nightly' }, run: withPingArk(async () => { await runNightlyJob() return { result: 'ok' } }, { check: 'nightly-job' }), })Copy
# end of your cron job: one line curl -fsS https://pingark.com/ping/pk_live_a1b2c3d4/nightly-backup # richer timeline: start, then success or an exit code curl https://pingark.com/ping/pk_live_a1b2c3d4/nightly-backup/start curl https://pingark.com/ping/pk_live_a1b2c3d4/nightly-backup/$? # the first ping can even create the check curl "https://pingark.com/ping/pk_live_a1b2c3d4/nightly-backup?create=1"Copy
A check has exactly one state.
No dashboards full of ambiguous yellows. Five states, one meaning each, and only down ever pages you.
Created, inert. No alerts until the first ping arrives.
Pinging on time. Late is derived inside the grace window. Informational, never paged.
Deadline blown or an explicit fail. One alert out; recovery sends the all-clear.
Muted by hand for maintenance. Auto-resumes on the next ping.
Everything a heartbeat monitor should have.
Real schedules
Cron expressions with timezones, simple periods from a minute to a year, and systemd OnCalendar, each with its own grace.
Rich pings
Start and finish for run duration, explicit fail, exit codes, and an optional body for logs and exception context.
Nine alert channels
Email, Slack, Discord, Telegram, webhooks, and PagerDuty on every plan, plus WhatsApp, SMS, and voice call with bundled credits on higher plans.
A real dashboard
A status board, ping timeline, downtime history, and surfaced delivery failures, because a broken alert is the worst kind.
Management API
Create, pause, and list checks over a clean REST API with read-only and read-write keys per project.
Status badges
Drop a live SVG badge into any README so a project's heartbeat is visible at a glance.
Your scheduler, monitored. Zero ceremony.
Chain one method onto a scheduled command and the plugin wraps it: sending start and finish, and capturing duration, exit code, and the exception trace when it throws.
# then add your project key to .env
PINGARK_PING_KEY=pk_live_a1b2c3d4
Wrap the job. The rest is automatic.
One function around any scheduled job and the SDK reports it: start and finish, run duration, and the actual error with its message when the job throws. Never in the way, never breaking the job.
# then add your project key to .env
PINGARK_PING_KEY=pk_live_a1b2c3d4
Priced on checks, not seats or events.
Start free. Upgrade only when you outgrow your check count.
20 checks · Core monitoring for a side project or two, on us.
50 checks · For indie developers running real workloads.
250 checks · For teams that share on-call, with credits for premium alerts.
1,000 checks · Higher scale for bigger fleets and agencies.
Paid plans are launching soon. Join the founding list and you will get early access to Pro plus a founding-user perk when upgrades open. The founding cohort closes the day paid plans launch.
You are on the list. We will email you the moment Pro opens.
Start monitoring in two minutes.
One curl line stands between you and never being the last to know.