Grupy powiadomień — API v1 i narzędzia MCP | Nodea
Grupa powiadomień agreguje trzy rodzaje członków — strony (website_ids), heartbeaty (heartbeat_ids) oraz integracje (integration_ids) — w jeden nazwany zestaw, przez który routowane są alerty. Ten artykuł opisuje interfejs API v1 REST oraz komplet 5 narzędzi MCP do zarządzania grupami. Wszystkie endpointy są dostępne pod ścieżką bazową /api/v1 (pełny host w przykładach: https://app.nodea.io/api/v1).
Uwierzytelnianie i wymagania
Uwierzytelnianie odbywa się osobistym tokenem Passport przekazywanym w nagłówku Authorization: Bearer <token>. Obowiązuje limit zapytań throttle:api-v1 = 240 żądań/min. Trasy grup powiadomień wymagają włączonej flagi Pennant notification_groups — bez niej zwracany jest błąd, że funkcja jest niedostępna.
Wymagane scope tokenu zależą od operacji:
- odczyt —
alerting:read - zapis (tworzenie i aktualizacja) —
alerting:write - usuwanie —
alerting:delete
Każdy dostęp jest ograniczony do właściciela (user_id równy użytkownikowi tokenu). Grupa należąca do innego użytkownika lub nieznane id konsekwentnie zwraca 404 — API nie potwierdza, że obce id istnieje.
API v1
| Metoda | Ścieżka | Scope | Opis |
|---|---|---|---|
| GET | /notification-groups | alerting:read | Lista grup użytkownika z licznikami członków (paginacja, wyszukiwanie, filtr usage). |
| GET | /notification-groups/{notificationGroup} | alerting:read | Szczegóły jednej grupy wraz z listami id członków. |
| POST | /notification-groups | alerting:write | Utworzenie grupy i (opcjonalnie) podpięcie członków. |
| PATCH / PUT | /notification-groups/{notificationGroup} | alerting:write | Częściowa aktualizacja — synchronizacja tylko przesłanych list członków. |
| DELETE | /notification-groups/{notificationGroup} | alerting:delete | Trwałe usunięcie grupy (członkowie tylko odpinani, nie usuwani). |
GET /notification-groups — lista
Parametry zapytania (wszystkie opcjonalne): search (string, max 255 — dopasowanie po nazwie), usage (filtr, patrz niżej), sort (name lub created_at), direction (asc / desc; domyślnie desc dla created_at, asc w pozostałych), per_page (1–100, domyślnie 20), page (od 1). Nieprawidłowa wartość dowolnego parametru zwraca 422.
Dozwolone wartości filtra usage: all (domyślnie), with_integrations, without_integrations, with_websites, without_websites. Odpowiadają one predykatom z widoku webowego — filtrują grupy odpowiednio posiadające bądź niemające integracji lub stron.
Każdy element listy zawiera liczniki integrations_count, websites_count, heartbeats_count oraz — dzięki stałemu eager-loadowaniu — pole integration_ids. Odpowiedź jest opakowana w kopertę data / links / meta Laravel Resource.
curl -s "https://app.nodea.io/api/v1/notification-groups?usage=with_websites&per_page=20" \
-H "Authorization: Bearer <token>" \
-H "Accept: application/json"GET /notification-groups/{notificationGroup} — szczegóły
Zwraca pojedynczą grupę wraz z listami id członków: integration_ids, website_ids, heartbeat_ids oraz licznikami *_count. Serializowane są wyłącznie id członków — pełne wiersze integracji (i ich sekretna konfiguracja) nigdy nie trafiają do odpowiedzi. Obca lub nieznana grupa → 404.
curl -s "https://app.nodea.io/api/v1/notification-groups/42" \
-H "Authorization: Bearer <token>" \
-H "Accept: application/json"POST /notification-groups — utworzenie
Ciało żądania: name (wymagane, string, max 255) oraz opcjonalne tablice integration_ids, website_ids, heartbeat_ids. Każde id członka musi należeć do użytkownika tokenu. Przekazanie id integracji, strony lub heartbeatu, którego nie jesteś właścicielem, kończy się błędem walidacji 422 — a nie cichym pominięciem, jak w przepływie webowym. Własność strony sprawdzana jest po pivocie sharables (typ OWNER) — udział FOREIGN nie wystarcza, bo podpięcie strony routuje jej alerty przez integracje tej grupy.
Powodzenie zwraca kod 201 i pełny kształt grupy z listami id oraz licznikami członków.
curl -s -X POST "https://app.nodea.io/api/v1/notification-groups" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"name": "Zespol dyzurny",
"integration_ids": [3, 7],
"website_ids": ["9f1c2d34-..."],
"heartbeat_ids": []
}'PATCH / PUT /notification-groups/{notificationGroup} — aktualizacja
Aktualizacja jest częściowa. name jest opcjonalne (sometimes). Klucze członków są synchronizowane tylko wtedy, gdy zostały przesłane w ciele żądania: pominięcie website_ids pozostawia strony bez zmian, natomiast przekazanie pustej tablicy odpina wszystkich członków danego typu. Te same reguły własności co przy tworzeniu — obce id członka → 422. Nieistniejąca lub obca grupa → 404.
curl -s -X PATCH "https://app.nodea.io/api/v1/notification-groups/42" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{ "name": "Nowa nazwa", "integration_ids": [3] }'DELETE /notification-groups/{notificationGroup} — usunięcie
Trwale usuwa grupę. Podpięci członkowie (strony, integracje, heartbeaty) są jedynie odpinani przez kaskady pivotów — same zasoby członków pozostają nietknięte. Powodzenie zwraca 204 No Content. Obca lub nieznana grupa → 404.
curl -s -X DELETE "https://app.nodea.io/api/v1/notification-groups/42" \
-H "Authorization: Bearer <token>" \
-H "Accept: application/json"Kody błędów
| Kod | Znaczenie |
|---|---|
| 401 | Brak lub nieprawidłowy token w nagłówku Authorization. |
| 403 | Token nie posiada wymaganego scope (np. alerting:write dla zapisu). |
| 404 | Grupa nie istnieje lub należy do innego użytkownika. |
| 422 | Błąd walidacji — { "message": ..., "errors": { ... } }. Obejmuje m.in. przekazanie id członka (strony / heartbeatu / integracji), którego nie jesteś właścicielem. |
MCP
Ten sam zestaw operacji jest dostępny jako narzędzia MCP. Każde narzędzie wymaga włączonej flagi notification_groups oraz odpowiedniego scope tokenu. Narzędzia zapisu/odczytu odrzucają obce id członków wprost (a nie wycinają je po cichu jak przepływ webowy), a narzędzie usuwania jest destrukcyjne i wymaga jawnego confirm: true.
| Nazwa | Scope | Tryb | Opis |
|---|---|---|---|
notification-groups-list | alerting:read | read-only | Paginowana lista grup z licznikami członków (bez list id). Parametry: search, page, per_page (max 50). |
notification-group-get | alerting:read | read-only | Jedna grupa z pełnymi listami członków: strony (id, name), integracje (id, name, type), heartbeaty (id, name). Parametr: id. |
notification-group-create | alerting:write | zapis | Utworzenie grupy z opcjonalnymi website_ids, heartbeat_ids, integration_ids. Obce id → odrzucenie, nic nie powstaje. |
notification-group-update | alerting:write | zapis | Częściowa aktualizacja; przesłana lista zastępuje dany zestaw członków (pusta tablica odpina wszystkich), pominięta pozostaje bez zmian. |
notification-group-delete | alerting:delete | destrukcyjny | Trwałe usunięcie grupy. Wymaga confirm: true. Członkowie tylko odpinani. |
Przykłady wywołań (JSON-RPC tools/call)
Lista grup zawierających strony:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "notification-groups-list",
"arguments": { "search": "dyzur", "per_page": 20 }
}
}Utworzenie grupy z członkami:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "notification-group-create",
"arguments": {
"name": "Zespol dyzurny",
"integration_ids": [3, 7],
"website_ids": ["9f1c2d34-..."]
}
}
}Usunięcie grupy — wymagane confirm: true:
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "notification-group-delete",
"arguments": { "id": 42, "confirm": true }
}
}Powiązane: Integracje oraz Polityki eskalacji.
