Nodea — logo

Heartbeats — API v1 i MCP | Dokumentacja Nodea

Moduł Heartbeats obsługuje monitory typu cron / dead-man-switch: usługa lub zadanie cron musi cyklicznie wywołać publiczny URL ping (/hb/{token}), a pominięcie terminu (interwał + grace) wywołuje alert. Dokument opisuje endpointy REST API v1 oraz narzędzia MCP tego modułu. Publiczny endpoint ping to osobna, nieuwierzytelniona trasa web i nie jest częścią tego API.

Uwierzytelnianie, zakresy i flaga

Bearer token Passport (Authorization: Bearer <token>). Zakresy: monitoring:read (index, show, runs), monitoring:write (create, update, pause, resume), monitoring:delete (usunięcie). Cały moduł bramkowany flagą features:heartbeats.

Własność, widoczność i maskowanie tokenu

Dostęp wymusza HeartbeatPolicy: view = właściciel lub zaakceptowany udział FOREIGN, manage = wyłącznie właściciel. Istniejący, niewidoczny identyfikator zwraca 403, nieznany — 404. Kluczowa zasada bezpieczeństwa: pola token oraz pochodny ping_url są sekretem (z nich wynika URL crona klienta), więc serializują się tylko dla właściciela (przechodzącego politykę manage). Zaakceptowany udział widzi heartbeat, ale nigdy jego tokenu. Token generowany jest raz przy tworzeniu i jest niezmienny — update go nie regeneruje.

API v1 — endpointy

MetodaŚcieżkaScopeOpis
GET/api/v1/heartbeatsmonitoring:readLista heartbeatów (własne + zaakceptowane udziały), paginowana.
GET/api/v1/heartbeats/{heartbeat}monitoring:readSzczegóły; meta.can_manage. Token tylko dla właściciela.
GET/api/v1/heartbeats/{heartbeat}/runsmonitoring:readHistoria pingów/pominięć, najnowsze pierwsze.
POST/api/v1/heartbeatsmonitoring:writeUtworzenie heartbeatu (generuje token). Zwraca 201. Limit planu → 402 (kod plan_limit_exceeded).
PUT/PATCH/api/v1/heartbeats/{heartbeat}monitoring:writeAktualizacja name/interval/grace/note. Token niezmienny.
POST/api/v1/heartbeats/{heartbeat}/pausemonitoring:writeIdempotentna pauza (ustawia paused_at).
POST/api/v1/heartbeats/{heartbeat}/resumemonitoring:writeIdempotentne wznowienie (czyści paused_at).
DELETE/api/v1/heartbeats/{heartbeat}monitoring:deleteTrwałe usunięcie (kaskada historii). Zwraca 204.

GET /heartbeats — parametry zapytania

  • search (string, max 255) — dopasowanie po nazwie.
  • status (enum: active|paused).
  • sort (enum: name|interval_seconds|last_ping_at|created_at, domyślnie created_at).
  • direction (asc|desc).
  • per_page (int 1–100, domyślnie 20), page.

POST/PATCH — parametry ciała

  • name (string, wymagany, max 255).
  • intervalSeconds (int, wymagany, 60–259200) — oczekiwany interwał pingu.
  • graceSeconds (int, wymagany, 0–86400) — okres karencji dodany do interwału.
  • note (string, opcjonalny, max 5000).
  • notificationGroupsId[] (tylko POST) — muszą należeć do użytkownika tokenu (inaczej 422). Update nie przyjmuje sync grup.

Kształt odpowiedzi (HeartbeatResource)

Pola: id, name, status (paused→waiting→late→ok), interval_seconds, grace_seconds, note, token (tylko właściciel), ping_url (tylko właściciel), ownership (owner|shared), last_ping_at, deadline_at (dopiero po pierwszym pingu), paused_at, created_at, updated_at. Wpis historii (HeartbeatRunResource): id, heartbeat_id, state, state_name (Success = ping / Failure = pominięty termin), reason, reason_code, created_at.

Kody błędów

  • 401 — brak/niepoprawny token; 403 — scope/polityka; 404 — nieznany id; 422 — walidacja lub cudza grupa powiadomień; 402 — przekroczony limit planu przy tworzeniu (plan_limit_exceeded).

Przykłady — API

Utworzenie heartbeatu (co 5 min, grace 60 s)

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 * * *"
  }'

Odpowiedź zawiera token i ping_url — jednorazowy moment na podpięcie crona. Skrypt wywołuje potem ping_url po każdym udanym przebiegu.

Lista aktywnych heartbeatów

curl -s "https://app.nodea.io/api/v1/heartbeats?status=active&sort=last_ping_at&direction=desc" \
  -H "Authorization: Bearer $NODEA_TOKEN"

MCP — narzędzia

Ten sam model auth/scope co API v1 (ensureScope) i flaga features:heartbeats. Token i ping_url pojawiają się w odpowiedzi tylko gdy wywołujący ma uprawnienie manage (właściciel).

NarzędzieScopeTypOpis
heartbeats-listmonitoring:readread-onlyLista; search, status (active/paused), page, per_page (max 50). Bez tokenu.
heartbeat-getmonitoring:readread-onlySzczegóły; token + ping_url tylko dla właściciela. Param: id.
heartbeat-createmonitoring:writezapisname, interval_seconds (60–259200), grace_seconds (0–86400), note. Limit planu → błąd. Zwraca token+ping_url.
heartbeat-updatemonitoring:writeidempotentneCzęściowa aktualizacja name/interval/grace/note. Tylko właściciel. Token niezmienny.
heartbeat-set-pausedmonitoring:writeidempotentnePauza/wznowienie przez paused: true|false.
heartbeat-deletemonitoring:deletedestrukcyjneTrwałe usunięcie; wymaga confirm: true.
heartbeat-runsmonitoring:readread-onlyHistoria pingów/pominięć; page, per_page (max 50).

Przykład — 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 }
  }
}