Quickstart
Monitor any scheduled job in under a minute. Create a check, add its one-line ping to your job, and LastPing emails you the moment the job misses its window — no alert routing to configure.
1 · Sign in
Sign in at app.lastping.dev with GitHub or with email. Everything below happens in the same console.
2 · Create a check
Click + New check, set how often the job runs and a grace period (how long to wait past the deadline before it counts as late). Your verified email is attached as an alert destination automatically — so a brand-new check can already reach you.
3 · Add the ping to your job
Append the check's ping URL to the end of your cron, backup, or CI job:
# at the very end of your job, once it has succeeded
curl -fsS https://ping.lastping.dev/<your-check-id>
Miss the window and you get an email; recover and you get the all-clear. Add Telegram, Slack, Discord, or webhook destinations any time.
curl quiet on success, fail on HTTP errors,
but still show real errors — the recommended flags for a ping in a job.Send your first ping
A ping is a plain HTTP request to your check's URL. The path decides what it means. Each check has its own unique ping URL — you'll find it on the check page.
Signal types
| Meaning | Request |
|---|---|
| Success (job finished OK) | curl -fsS https://ping.lastping.dev/<id> |
| Job started | curl -fsS https://ping.lastping.dev/<id>/start |
| Explicit failure | curl -fsS https://ping.lastping.dev/<id>/fail |
| Exit-code form | curl -fsS https://ping.lastping.dev/<id>/$? |
The exit-code form reads the number: 0 is treated as success, any non-zero
value as a failure. Put it right after the command you want to report on so $?
holds that command's exit status.
Shell example
# run the real work, then report whether it succeeded
/usr/local/bin/backup.sh
curl -fsS https://ping.lastping.dev/<id>/$?
Start & finish (with a run id)
Send a start ping before the work and a success/fail ping after. Add an
optional ?rid=<run-id> to correlate the two halves of one run:
RID=$(date +%s) curl -fsS "https://ping.lastping.dev/<id>/start?rid=$RID" /usr/local/bin/backup.sh curl -fsS "https://ping.lastping.dev/<id>/$??rid=$RID"
Cron example
# /etc/cron.d/backup — ping only if the job exits 0
0 3 * * * root /usr/local/bin/backup.sh && curl -fsS https://ping.lastping.dev/<id>
Signing in
LastPing supports two sign-in methods, both landing in the same console:
- GitHub OAuth — one click, no password to manage.
- Email + password — sign up, verify your email, then set a password.
One account, either way
You can add a password to a GitHub-created account, or link an email/password account to GitHub, as long as the email is verified and matches. Your verified email doubles as your first alert destination.
Checks & schedules
A check expects a ping on a schedule. If the ping doesn't arrive in time, the check goes late and then down, and LastPing alerts you.
Schedule kinds
- Simple interval — "expected every N minutes / hours / days".
- Cron — a cron expression, evaluated in a timezone you choose.
On top of the schedule, a grace period gives the job slack before it's considered late — set it to cover normal run-time jitter.
Statuses
Every check is in one of four states:
| Status | Meaning |
|---|---|
| new | Created, no ping received yet. |
| up | Pinged on time; healthy. |
| late | Past the deadline, still inside grace. |
| down | Grace exhausted; an incident is open and you're alerted. |
Pause, resume & the ping URL
Pause or resume a check from its page — a paused check never alerts, regardless of ping status. Each check has one unique ping URL that never changes; that's the URL you put in your job.
Alerts & destinations
When you create your first check, your verified email is auto-attached for down and recovery events — so the first check you ever make can already reach you without any setup.
Destinations
Add more under Destinations. LastPing supports:
- Telegram
- Slack
- Discord
- Webhook
Event types
| Event | When it fires |
|---|---|
| down | A check misses its window and an incident opens. |
| recovery | A down check pings again — the all-clear. |
| fail | A job reports an explicit failure (a /fail or non-zero exit-code ping). |
Send test & the alerts log
Send test fires a real alert through the pipeline so you can prove a destination actually works. A check with no destination shows a loud "won't alert anyone" warning. The Recent alerts log on the check shows what was sent, where, and whether it delivered.
Monitor a CI/CD pipeline
Instead of curling a ping URL at the end of a job script, you can point a provider webhook at LastPing. Every workflow run — pass or fail — is captured as a ping event; missed runs alert with a deep link to the failing run.
Setup overview
The webhook URL has the form:
https://ping.lastping.dev/ci/<provider>/<check-id>
where <provider> is github, gitlab, or
jenkins.
GitHub Actions
Go to your repository on GitHub, then Settings → Webhooks → Add webhook:
- Payload URL — paste the webhook URL.
- Content type — select
application/json. - Secret — paste the one-time secret.
- Under Which events would you like to trigger this webhook? choose Let me select individual events and tick Workflow runs (uncheck Pushes which is pre-ticked).
- Click Add webhook.
.github/workflows YAML are
needed. A missed or failed run alerts with a direct link to the run log.GitLab CI
Go to your project on GitLab, then Settings → Webhooks:
- URL — paste the webhook URL.
- Secret token — paste the one-time secret.
- Under Trigger tick Pipeline events.
- Click Add webhook.
.gitlab-ci.yml changes are needed.Jenkins
Use the Notification Plugin (or any generic outbound webhook mechanism) to POST to the webhook URL. Include the secret in the request header:
X-LastPing-Token: <your-secret>
With the Notification Plugin, add a Job Notification endpoint in the job
configuration: set the URL to the webhook URL, Protocol HTTP, Format
JSON, and add the header above. No Jenkinsfile changes are
required.
Status pages
Publish the health of your checks on a shareable page. Go to Status pages → New and choose public or private.
Public pages
A public page lives at https://lastping.dev/status/<slug>
(also reachable at app.lastping.dev/status/<slug>). It shows per-check
status, 90-day uptime, and incident history.
Badges
Embed a status badge anywhere with:
https://lastping.dev/badge/<slug>/<check>
Troubleshooting
No alert arrived
Does the check have a verified destination? The check page warns loudly if not. Is the destination itself verified/connected? Use Send test to fire a real alert and confirm the whole path works.
Check stuck late or down
Confirm the job actually pings on success, and that the schedule and grace period match how the job really runs. A job that succeeds but never pings will always look down.
Ping isn't registering
Double-check the URL and check-id. A bare visit to ping.lastping.dev from a
browser redirects humans to the marketing site — that's expected; the ping still needs the
full /<id> path.
API reference
LastPing has a REST API under /api/v1 (base
https://app.lastping.dev). Authenticate every request with an API key in the
X-Api-Key header. Create a key in Settings → API keys; it's shown once,
so copy it then.
Main resources
| Method | Path | What it does |
|---|---|---|
| GET | /api/v1/whoami | Verify the key; returns your project id. |
| POST | /api/v1/checks | Create a check (upsert by slug). |
| GET | /api/v1/checks | List all checks. |
| GET | /api/v1/checks/{id} | Get one check. |
| PATCH | /api/v1/checks/{id} | Update a check's schedule. |
| DELETE | /api/v1/checks/{id} | Delete a check. |
| POST | /api/v1/checks/{id}/pause | Pause a check (stop alerting). |
| POST | /api/v1/checks/{id}/resume | Resume a paused check. |
| POST | /api/v1/channels | Create a notification channel (webhook or telegram kind). |
| GET | /api/v1/channels | List channels. |
| PUT | /api/v1/checks/{id}/routes/{event_type} | Route an event type to channels. |
| GET | /api/v1/checks/{id}/pings | List recent pings. |
| GET | /api/v1/checks/{id}/incidents | List incidents. |
Event types for routes are down, recovery, and fail.
Channel secrets (webhook secret, Telegram bot_token) are
write-only and never returned.
CLI & curl recipes
Practical snippets using curl and your X-Api-Key. Set your key
once and reuse it:
export LP_KEY="lp_your_api_key_here" export LP_BASE="https://app.lastping.dev"
Verify your key
curl -fsS "$LP_BASE/api/v1/whoami" \ -H "X-Api-Key: $LP_KEY"
Create (or upsert) a check
Passing a slug makes this idempotent: a matching slug updates the existing
check and returns 200 instead of 201.
curl -fsS "$LP_BASE/api/v1/checks" \
-H "X-Api-Key: $LP_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Daily backup job",
"slug": "daily-backup",
"schedule_kind": "simple",
"period_s": 86400,
"grace_s": 600
}'
For a cron schedule, use "schedule_kind":"cron" with
"cron_expr":"0 3 * * *" and an optional "tz":"Europe/London".
List checks
curl -fsS "$LP_BASE/api/v1/checks" \ -H "X-Api-Key: $LP_KEY"
Ping a check
Pings don't use the API key — they're a plain GET to the check's ping URL:
curl -fsS https://ping.lastping.dev/<check-id>
Create a channel
The API creates webhook and telegram channels. Email, Slack, and Discord destinations are configured in the app under Destinations.
curl -fsS "$LP_BASE/api/v1/channels" \
-H "X-Api-Key: $LP_KEY" \
-H "Content-Type: application/json" \
-d '{
"kind": "webhook",
"name": "Ops webhook",
"config": { "url": "https://example.com/hook", "secret": "s3cr3t" }
}'
Attach a route
Route the down event on a check to one or more channels
(channel_ids is the complete list; an empty list clears it):
curl -fsS -X PUT \
"$LP_BASE/api/v1/checks/<check-id>/routes/down" \
-H "X-Api-Key: $LP_KEY" \
-H "Content-Type: application/json" \
-d '{ "channel_ids": ["c1d2e3f4-0000-0000-0000-000000000001"] }'