Pulse heartbeat API
The public ping endpoint: methods, responses, states and rate limits.
One endpoint, two methods. It is deliberately boring: no auth header, no SDK, no payload required. The token in the path is the credential.
POST /api/v1/ping/{token}
Ingests a heartbeat. Optional JSON body is stored with the ping and appears in the monitor detail. Returns 202 Accepted.
curl -X POST https://api.pingops.cloud/api/v1/ping/<token> \
-H 'Content-Type: application/json' \
-d '{"job":"nightly","rows":18422,"duration_s":41}'{
"ok": true,
"monitor": "nightly-backup",
"status": "healthy",
"queued": true
}GET /api/v1/ping/{token}
Same ingestion, no body, returns 200. This exists because cron lines, wget in a minimal container and uptime scripts in shell all prefer GET, and forcing a POST means writing a wrapper.
States
- healthy — a ping arrived within the interval.
- late — the interval elapsed, still inside the grace period. No alert yet.
- down — grace period elapsed with no ping. Alert fires.
- paused — monitoring suspended; pings are accepted and recorded but do not change the state.
The transition to down happens on a 30-second ticker, so detection is interval + grace + at most 30 seconds.
Response codes
- 200 / 202 — accepted. queued=true means it is in the Redis buffer; the worker flushes to Postgres every few seconds.
- 404 — unknown token. A deleted monitor returns this too.
- 429 — rate limit exceeded for this token.
Ping from anything
# crontab
0 3 * * * /usr/local/bin/backup.sh && curl -fsS https://api.pingops.cloud/api/v1/ping/<token>
# GitHub Actions, last step
- name: heartbeat
run: curl -fsS https://api.pingops.cloud/api/v1/ping/${{ secrets.PULSE_TOKEN }}
# systemd OnSuccess
[Service]
ExecStartPost=/usr/bin/curl -fsS https://api.pingops.cloud/api/v1/ping/<token> Something missing? Write to support and it gets added here.