A cron job. A nightly backup. An agent that runs every hour. Each one hits its own ping URL when it finishes.
If the ping does not arrive in time, you get an email. On the paid plan you also get a signed webhook.
No dashboard to babysit. No SMS. No phone calls. Just the alert, when it matters.
How it works
- Create a check. Give it a name, how often the job runs (
period_s), and how late is too late (grace_s). - Ping it from the job. Put the check's
ping_urlat the end of your script.GETorPOST, no key needed, body ignored. - Get told when it is late. No ping within
period + gracesends acheck.lateevent. The next ping sendscheck.recovered. If the job knows it broke, it can call/ping/<id>/failright away.
Plans
| Plan | Price | Checks | Alerts | Event log |
|---|---|---|---|---|
| Free | $0 | 10 | 30 days | |
| Paid | $7 a month, flat | 100 | email + webhooks | 30 days |
No per-seat fee. To upgrade, call POST /v1/billing/checkout with your API key. You get a Stripe Checkout page; pay there and your plan flips to paid.
Cancel any time from the billing portal.
Quick start
Three calls. Replace the email with yours.
# 1. sign up (free). The API key is shown once. Save it.
curl -s -X POST https://beat.austinoaksapi.com/v1/signup \
-H 'Content-Type: application/json' \
-d '{"email":"you@example.com"}'
# 2. create a check: runs every 5 minutes, 60 seconds of grace
curl -s -X POST https://beat.austinoaksapi.com/v1/checks \
-H "Authorization: Bearer $KEY" \
-H 'Content-Type: application/json' \
-d '{"name":"nightly-backup","period_s":300,"grace_s":60}'
# the reply includes "ping_url" and "fail_url"
# 3. from the job itself, at the end of each run
curl -s https://beat.austinoaksapi.com/ping/<check id>
# the job knows it broke? say so now instead of waiting for the clock
curl -s -X POST https://beat.austinoaksapi.com/ping/<check id>/fail
Paid plan: add a webhook target and every event is POSTed to it.
curl -s -X POST https://beat.austinoaksapi.com/v1/targets \
-H "Authorization: Bearer $KEY" \
-H 'Content-Type: application/json' \
-d '{"kind":"webhook","url":"https://hooks.example.com/alerts","secret":"shared"}'
See what happened: GET /v1/checks/<id>/events returns the last 100 events with their delivery results. The full route list is in openapi.json.
Signed events
Every alert is a JSON event signed with an Ed25519 key. You can check that it really came from this service and was not changed.
The envelope is {"event", "sig", "kid", "ts"}. The signed bytes are the canonical JSON of {"event", "kid", "ts"}: keys sorted, no whitespace. The public key is at GET /v1/keys. Any Ed25519 library can verify it.
A signature proves this service issued the event, unchanged, at the stated time. It does not prove your job is healthy.
Webhook deliveries also carry X-AOKit-Event (the event type) and, when your target has a secret, X-AOKit-Signature: sha256=<HMAC of the body>. Deliveries are tried 3 times with 1, 2 and 4 second waits.
Limits worth knowing
period_sis 60 seconds to 30 days.grace_sis 0 to 30 days.- Pings are limited to 10 a minute per check. Extra pings still answer
200with"dropped": true, so a chatty job never sees an error. - Alert email goes only to the address you signed up with.
- Webhook targets must be public
httporhttpsaddresses. Private networks and local addresses are refused. - One account per email address. Signups are rate limited per IP.
More
- OpenAPI 3.0 description of every route.
- Looking for a Healthchecks.io alternative?
- Service health (JSON).