Documentation

Integrate heartbeat monitoring into your workflow

Everything you need to wire App Pulse Check into cron jobs, scripts, and background workers — and get alerted when they go quiet.

What the product is and why you should care

App Pulse Check is a heartbeat monitorfor background jobs, cron tasks, and scripts. Each monitored job gets a unique ping URL. When the job runs successfully, it calls that URL to signal it's alive. If pings stop arriving within the expected window, the check is marked down and your team gets notified.

This is nottraditional HTTP uptime monitoring. You don't point us at a public endpoint and wait for it to respond. Instead, your job tells us it finished — which catches silent failures: scripts that crash, crons that never fire, workers that hang, pipelines that stall without raising an error.

What it's for

  • Nightly backups and database maintenance scripts
  • Scheduled data syncs and ETL pipelines
  • Queue workers and background processors
  • GitHub Actions or CI jobs that must run on a schedule
  • Any recurring task that can fail without anyone noticing

Heartbeat vs. health checks

App Pulse Check exposes GET /health on the API server for monitoring the service itself. Your jobs use GET /ping/:uuid — a separate, public endpoint scoped to each check you create.

What we offer

App Pulse Check gives indie hackers and small teams focused monitoring — everything you need to know when scheduled work stops running, without a full observability stack.

One-line integration
No SDK required. Copy a ping URL and add a single GET request to your existing job.
Smart missed-ping detection
A background worker evaluates every check every 60 seconds, respecting your interval and grace window.
Actionable down alerts
Know the moment something stops checking in — before your users or data pipeline do.
Built for small teams
Lightweight monitoring without standing up Prometheus, Grafana, or a full observability stack.

Also included

  • Web dashboard with live status badges and relative last-ping times
  • Copy-ping-URL workflow — no SDK, no package install
  • Per-check Slack and Discord webhook configuration
  • Pause checks during planned maintenance
  • Configurable interval and grace period per job
  • JWT-protected API for creating and managing checks

Plans & limits

App Pulse Check offers four plans: Free, Supporter, Enterprise, and Enterprise Plus. New accounts start on Free. Paid tiers unlock higher limits and additional alert channels as they launch.

PlanMax checksPing logs per checkStatus
Free20100Available
Supporter20100Available
Enterprise1001000Coming soon
Enterprise Plus10001000Coming soon

Ping log retention

Every successful ping creates a log entry on that check's history page. Each plan caps how many entries are kept per check. When a new ping would exceed your plan's limit, the oldest log entries are deleted automatically — both when pings arrive and during a periodic retention cleanup.

On Free and Supporter, up to 100 pings per check are retained. Enterprise and Enterprise Plus retain up to 1,000 per check.

Check limits

Each plan also limits how many checks you can create. The dashboard shows your current usage (for example, "12 / 20 checks"). When you reach the limit, existing checks keep running but you cannot create new ones until you delete a check or upgrade your plan.

See the full comparison on the pricing page.

Quick start

Get your first check running in about five minutes.

  1. Sign up and open the dashboard.
  2. Click Create Check — give it a name, set an expected interval (seconds between successful runs), and a grace period (extra buffer before marking down).
  3. Copy the ping URL from the check row. It looks like https://your-api.example.com/ping/a1b2c3d4-…
  4. Add a single HTTP GET at the end of your job, only when the work succeeds. See How to integrate for copy-paste examples.
  5. Configure Slack or Discord alerts under Alerts on the check row. See Alerts for setup steps.
  6. Run your job once. The check should move from NEW to UP after the first ping.

Ping API reference

The ping endpoint is public and requires no authentication. The UUID in the URL acts as the secret — treat it like an API key.

MethodGET
URL{API_URL}/ping/{uuid}
AuthNone
When to callAfter your job completes successfully
Response200 { ok: true, checkId, pingedAt }

Test with curl

bash
curl -fsS -o /dev/null "https://your-api.example.com/ping/YOUR-UUID"

-f fails on non-2xx responses; -sS keeps output quiet but surfaces errors.

Errors

  • 404 — UUID not found (wrong URL or deleted check)
  • 500 — server error; retry is safe

Interval & grace period

When you create a check, you set two timing values that control when a missed ping triggers a down state.

FieldRangeMeaning
Interval60 – 86,400 sExpected time between successful runs
Grace0 – 3,600 sExtra buffer before marking DOWN

Down detection formula

A check goes DOWN when:
  now > lastPingedAt + intervalSeconds + graceSeconds

A background worker evaluates all non-paused checks every 60 seconds, so detection can lag by up to ~60 seconds after the deadline passes.

Suggested presets

Job typeIntervalGrace
Every 5 minutes300 s60 s
Hourly cron3,600 s300 s
Daily backup86,400 s3,600 s

Tip: set the interval slightly above your real schedule if jobs sometimes run a few minutes late.

Statuses & pause

Each check moves through a simple lifecycle visible on your dashboard.

  • NEWCheck created but never pinged. Will not go DOWN until the first successful ping arrives.
  • UPLast ping arrived within the expected window. Everything looks healthy.
  • DOWNPings stopped arriving on time. A Slack or Discord alert fires if configured.

Pause

Use Pause on the dashboard during planned maintenance, deployments, or migrations. Paused checks are skipped by the evaluation worker and will not be marked DOWN or send alerts.

How to integrate

Add one HTTP GET at the end of your job, only after work completes successfully. Store the ping URL in an environment variable — never commit it to version control.

Linux cron

crontab
# Run backup at 2 AM; ping only if backup succeeds
0 2 * * * /usr/local/bin/nightly-backup.sh && curl -fsS -o /dev/null "$PULSECHECK_URL"

Bash script

backup.sh
#!/usr/bin/env bash
set -euo pipefail

# ... your backup logic ...

curl -fsS -o /dev/null "$PULSECHECK_URL"

Node.js

job.js
async function runJob() {
  // ... your work ...
  const res = await fetch(process.env.PULSECHECK_URL);
  if (!res.ok) throw new Error(`Ping failed: ${res.status}`);
}

runJob().catch((err) => {
  console.error(err);
  process.exit(1);
});

Python

job.py
import os
import urllib.request

def run_job():
    # ... your work ...
    urllib.request.urlopen(os.environ["PULSECHECK_URL"])

if __name__ == "__main__":
    run_job()

GitHub Actions

.github/workflows/scheduled.yml
jobs:
  nightly:
    runs-on: ubuntu-latest
    steps:
      - name: Run task
        run: ./scripts/nightly-task.sh
      - name: Ping App Pulse Check
        if: success()
        run: curl -fsS -o /dev/null "$PULSECHECK_URL"
    env:
      PULSECHECK_URL: ${{ secrets.PULSECHECK_URL }}

Docker / Kubernetes CronJob

Run your main container command first, then ping in a post-step or wrapper script. In Kubernetes, use an init-style wrapper or chain commands with && so the ping only runs on success.

wrapper.sh
#!/bin/sh
set -e
/node-app/run-sync.sh
curl -fsS -o /dev/null "$PULSECHECK_URL"

Alerts

Get notified the moment a check goes DOWN — before your users or downstream systems notice something is wrong.

Coming soon
Email
Inbox alerts when a check goes down.
Coming soon
PagerDuty
Escalate critical failures to your on-call rotation.

Setting up Discord alerts

  1. In Discord, open your server and go to Server Settings → Integrations → Webhooks.
  2. Click New Webhook, choose the channel for alerts, and copy the webhook URL — it starts with https://discord.com/api/webhooks/…
  3. On the dashboard, open Alerts for your check, paste the Discord webhook URL, and save settings.

You can configure Slack, Discord, or both on the same check. Recovery alerts are sent to the same channels when a down check receives a ping again.

Setting up Slack alerts

  1. In Slack, go to Apps → Incoming Webhooks (or create a Slack app with Incoming Webhooks enabled).
  2. Add a new webhook and choose the channel where alerts should appear (e.g. #alerts).
  3. Copy the webhook URL — it starts with https://hooks.slack.com/services/…
  4. On the dashboard, click Alerts on your check and paste the URL. Save settings.

Alerts are configured per check, so different jobs can notify different channels. An alert fires when a check transitions to DOWN. More channels ship soon — no migration needed when they land.

Best practices

  • Ping after success, not before. A ping at the start of a job will mark it UP even if the job crashes midway.
  • Don't ping on failure. Let the missed ping surface the problem — unless you intentionally want failures to look healthy.
  • One check per distinct job. Don't reuse one UUID for unrelated tasks.
  • Use environment variables. Store PULSECHECK_URL in your secrets manager or CI secrets — never in source code.
  • Pause during maintenance. Avoid false alarms when you intentionally stop a job.
  • Leave headroom in your interval. If a job usually finishes in 50 minutes but sometimes takes 70, don't set a 3,600-second interval with zero grace.

FAQ & troubleshooting

My check is stuck on NEW

No ping has been received yet. Test manually with curl using the URL from your dashboard. Confirm the UUID is correct and the request returns 200.

My check went DOWN but the job is fine

Your interval may be too tight or the job ran slower than expected. Increase the grace period or interval. Also confirm you're pinging after the work finishes, not before.

I didn't get a Slack or Discord alert

Verify at least one webhook URL is saved on the check's alert settings, the URL is valid, and the check isn't paused. Alerts fire on DOWN transitions — not on every evaluation cycle.

Ping returns 404

The UUID is wrong or the check was deleted. Copy a fresh URL from the dashboard.

Status changed late

The evaluation worker runs every 60 seconds. A check may appear DOWN up to a minute after the actual deadline.

Can I ping from multiple places?

Yes — any successful GET to the ping URL updates lastPingedAtand sets status to UP. Use one check per logical job, not per server instance, unless that's intentional.

Ready to add your first check?

Create an account and copy a ping URL in under a minute.

Get started free