---
title: "Heartbeats — API v1 and MCP | Nodea Documentation"
description: "Reference for the Heartbeats module (cron / dead-man-switch monitors): API v1 endpoints (CRUD, pause/resume, runs), monitoring:* scopes, ping-token masking, MCP tools and curl / JSON-RPC examples."
url: "https://nodea.io/en/api-docs/heartbeats"
lang: "en"
updated: "2026-07-16"
---

# Heartbeats — API v1 and MCP | Nodea Documentation

> Heartbeats module reference — cron/dead-man-switch monitors: API v1 endpoints (CRUD, pause/resume, runs), ping-token masking (owner only), MCP tools and examples.

The **Heartbeats** module handles cron / dead-man-switch monitors: a service or cron job must periodically call the public ping URL (/hb/{token}), and a missed deadline (interval + grace) raises an alert. This document describes the REST API v1 endpoints and the module's MCP tools. The public ping endpoint is a separate, unauthenticated web route and is **not** part of this API.

## Authentication, scopes and flag

Passport Bearer token (Authorization: Bearer \<token\>). Scopes: monitoring:read (index, show, runs), monitoring:write (create, update, pause, resume), monitoring:delete (delete). The whole module is gated by the features:heartbeats flag.

## Ownership, visibility and token masking

Access is enforced by HeartbeatPolicy: **view** = owner or accepted FOREIGN share, **manage** = owner only. An existing but invisible id yields 403, an unknown id 404. Key security rule: the token and the derived ping\_url are secrets (the customer's cron URL is derived from them), so they are serialized **only for the owner** (passing the manage policy). An accepted share sees the heartbeat but never its token. The token is generated once on create and is immutable — update never regenerates it.

## API v1 — endpoints

MethodPathScopeDescriptionGET/api/v1/heartbeatsmonitoring:readList heartbeats (owned + accepted shares), paginated. GET/api/v1/heartbeats/{heartbeat}monitoring:readDetail; meta.can\_manage. Token for owner only. GET/api/v1/heartbeats/{heartbeat}/runsmonitoring:readPing/miss history, newest first. POST/api/v1/heartbeatsmonitoring:writeCreate a heartbeat (generates token). Returns 201. Plan limit → 402 (code plan\_limit\_exceeded). PUT/PATCH/api/v1/heartbeats/{heartbeat}monitoring:writeUpdate name/interval/grace/note. Token immutable. POST/api/v1/heartbeats/{heartbeat}/pausemonitoring:writeIdempotent pause (sets paused\_at). POST/api/v1/heartbeats/{heartbeat}/resumemonitoring:writeIdempotent resume (clears paused\_at). DELETE/api/v1/heartbeats/{heartbeat}monitoring:deletePermanently delete (history cascade). Returns 204.

### GET /heartbeats — query parameters

- search (string, max 255) — matched against name.
- status (enum: active|paused).
- sort (enum: name|interval\_seconds|last\_ping\_at|created\_at, default created\_at).
- direction (asc|desc).
- per\_page (int 1–100, default 20), page.

### POST/PATCH — body parameters

- name (string, required, max 255).
- intervalSeconds (int, required, 60–259200) — expected ping interval.
- graceSeconds (int, required, 0–86400) — grace period added on top of the interval.
- note (string, optional, max 5000).
- notificationGroupsId\[\] (POST only) — must belong to the token user (otherwise 422). Update does **not** accept group sync.

### Response shape (HeartbeatResource)

Fields: id, name, status (paused→waiting→late→ok), interval\_seconds, grace\_seconds, note, token (owner only), ping\_url (owner only), ownership (owner|shared), last\_ping\_at, deadline\_at (only after the first ping), paused\_at, created\_at, updated\_at. History entry (HeartbeatRunResource): id, heartbeat\_id, state, state\_name (Success = ping / Failure = missed deadline), reason, reason\_code, created\_at.

### Error codes

- 401 — missing/invalid token; 403 — scope/policy; 404 — unknown id; 422 — validation or a foreign notification group; 402 — plan limit exceeded on create (plan\_limit\_exceeded).

## Examples — API

### Create a heartbeat (every 5 min, 60s grace)

curl -s -X POST https://app.nodea.io/api/v1/heartbeats \\ -H "Authorization: Bearer $NODEA\_TOKEN" \\ -H "Content-Type: application/json" \\ -d '{ "name": "Nightly backup", "intervalSeconds": 300, "graceSeconds": 60, "note": "cron 0 3 \* \* \*" }'

The response includes token and ping\_url — the one-time moment to wire up the cron. The script then calls ping\_url after each successful run.

### List active heartbeats

curl -s "https://app.nodea.io/api/v1/heartbeats?status=active&sort=last\_ping\_at&direction=desc" \\ -H "Authorization: Bearer $NODEA\_TOKEN"

## MCP — tools

Same auth/scope model as API v1 (ensureScope) and the features:heartbeats flag. The token and ping\_url appear in the response only when the caller holds the manage ability (owner).

ToolScopeTypeDescriptionheartbeats-listmonitoring:readread-onlyList; search, status (active/paused), page, per\_page (max 50). No token. heartbeat-getmonitoring:readread-onlyDetail; token + ping\_url for owner only. Param: id. heartbeat-createmonitoring:writewritename, interval\_seconds (60–259200), grace\_seconds (0–86400), note. Plan limit → error. Returns token+ping\_url. heartbeat-updatemonitoring:writeidempotentPartial update of name/interval/grace/note. Owner only. Token immutable. heartbeat-set-pausedmonitoring:writeidempotentPause/resume via paused: true|false. heartbeat-deletemonitoring:deletedestructivePermanent delete; requires confirm: true. heartbeat-runsmonitoring:readread-onlyPing/miss history; page, per\_page (max 50).

### Example — MCP (JSON-RPC)

{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "heartbeat-create", "arguments": { "name": "Nightly backup", "interval\_seconds": 300, "grace\_seconds": 60, "note": "cron 0 3 \* \* \*" } } } { "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "heartbeat-set-paused", "arguments": { "id": "3af0...uuid", "paused": false } } }

## Related

- [Websites — API v1 and MCP | Nodea Documentation](https://nodea.io/en/api-docs/websites)
- [Reports (SSL / WHOIS) — API v1 and MCP | Nodea Documentation](https://nodea.io/en/api-docs/reports)
- [Status Pages — API v1 and MCP | Nodea Documentation](https://nodea.io/en/api-docs/status-pages)

---

Languages: [pl](https://nodea.pl/pl/dokumentacja-api/heartbeats.md)  
Site index: [llms.txt](https://nodea.io/en/llms.txt)
