Wszystkie operacje API trzymają się zbioru określonych konwencji. Są one szczegółowo opisane w tym dokumencie.
API korzysta z czterech metod HTTP.
Metoda GET służy do pobierania danych z API, zarówno pojedynczych obiektów, jak i większych ich zbiorów. O ile nie jest powiedziane inaczej, wywołania GET są bezpieczne i idempotentne - nie zmieniają stanu obiektów. Wszędzie tam, gdzie można użyć metody GET, można także użyć metody HEAD, aby pobrać jedynie nagłówki odpowiedzi.
Wywołania POST służą dwóm celom:
Wywołania POST nie są bezpieczne ani idempotentne. W większości przypadków wymagają określenia treści zapytania w formacie JSON. Każdą z operacji zaimplementowanych jako POST należy traktować jako potencjalnie nie wpasowującą się w żadne schematy. Dotyczy to także operacji tworzenia obiektów - zazwyczaj przy tej operacji nie jest wysyłany cały docelowy obiekt (choćby dlatego, że z reguły nie ma on jeszcze identyfikatora), a czasami konieczne jest podanie dodatkowych danych (np. danych użytkownika przy tworzeniu konta).
Wywołania PUT służą najczęściej do modyfikacji istniejących obiektów. Wymagają przesłania zakodowanej w JSON nowej reprezentacji (lub fragmentu reprezentacji) obiektu. W niektórych przypadkach mogą służyć do utworzenia lub modyfikacji obiektów, jeśli identyfikator obiektu jest znany przed jego utworzeniem. Wywołania PUT są idempotentne (wielokrotne wywołania mają taki sam efekt, jak jedno), ale nie bezpieczne (mogą zmieniać stan obiektów).
Wywołania DELETE służą do usuwania obiektów. Podobnie jak PUT, są idempotentne, ale nie bezpieczne.
API wykorzystuje następujące standardowe nagłówki zapytania HTTP:
Content-Type
- typ zawartości. W większości przypadków będzie to application/json
. Nagłówek ten jest wymagany jeśli operacja wymaga przesłania treści w zapytaniu.Accept-Language
- preferowany język użytkownika (dostępne: "pl" - polski i "en" - angielski). Wykorzystywany do tłumaczenia komunikatów błędów API i niektórych ze zwracanych wartości.Authorization
- dane autentykacyjne. Dostępne schematy to Basic (standardowa autentykacja HTTP) i Bearer (token OAuth2).If-None-Match
- wartość ETag zapamiętanego wyniku zapytania GET (używane przy cache'owaniu pobranej zawartości).Cache-Control
, Vary
- nagłówki odpowiedzialne za cache'owanie odpowiedzi API.Niektóre ze standardowych nagłówków odpowiedzi API:
Content-Type
- typ zawartości odpowiedzi.WWW-Authenticate
- sposób autentykacji, w przypadku błędu 401.Allow
- lista metod HTTP dostępnych dla obiektu.Location
- adres URL utworzonego obiektu.X-Total-Count
- całkowita liczba znalezionych obiektów (bez paginacji) w przypadku pobierania listy obiektów.Niektóre z operacji mogą definiować własne nagłówki. W takim przypadku ich znaczenie zostanie wyjaśnione w dokumentacji konkretnej operacji.
Wywołanie API może zakończyć się błędem - w takim przypadku kod odpowiedzi HTTP będzie jednym z następujących:
Wszystkie inne kody błędów, błędy warstwy niższej niż HTTP oraz błędy bez ustawionego nagłówka Content-Type: application/json
należy traktować jak 500 Internal Server Error.
Jeśli błędna odpowiedź zawiera nagłówek Content-Type: application/json
, to treść odpowiedzi zawiera
bardziej szczegółowe informacje o błędzie niż sam kod HTTP. Na przykład próba wykonania zapytania:
curl 'https://api.monit24.pl/v3/sensors?limit=foo&fields=id,bar'
zakończy się błędem walidacji (422) podobnym do poniższego:
[ { "code" : 4222064, "description" : "Niepoprawna wartość.", "error" : "incorrect_value", "field" : "query.fields[1]", "message" : "Allowed values: \"city\", \"continent\", \"country\", \"id\", \"is_available\", \"links\", \"name\"" }, { "code" : 4220555, "description" : "Niepoprawny typ wartości.", "error" : "incorrect_type", "field" : "query.limit", "message" : "Value has to be of the type integer" } ]
Opis błędu jest JSON-ową tablicą obiektów, z których każdy opisuje jeden "problem" z przesłanym zapytaniem. Obiekt ten zawiera pola:
code
- wewnętrzny 7-cyfrowy kod błędu, którego pierwsze 3 cyfry odpowiadają statusowi HTTP. Kod ten
odpowiada jednoznacznie tekstowej wartości w polu error
, bardziej przyjaznej użytkownikowi. Dokumentacja każdej z operacji
API zawiera szczegółową listę możliwych kodów błędów.description
- opis błędu dla programisty, w języku polskim. Nie jest przeznaczony do
wyświetlenia użytkownikowi końcowemu i nie jest obowiązkowy.error
- szczegółowy symbol błędu. Symbol ten odpowiada jednoznacznie liczbowemu kodowi błedu
w polu code
.field
- "wskaźnik" na fragment zapytania, który spowodował błąd. Składnia tego pola jest
następująca: kropka oznacza atrybut obiektu, zaś liczbowy indeks w nawiasach kwadratowych - element tablicy. Na
przykład query.fields[1]
ozancza drugą wartość w polu tablicy fields
przekazanej w
parametrze GET (podobnie data
oznacza JSON-ową treść zapytania POST lub PUT). To pole jest opcjonalne,
może zostać wykorzystane np. do przypisania komunikatów błędów do odpowiednich pól formularza przedstawianego
użytkownikowi końcowemu.message
- komunikat do wyświetlenia użytkownikowi, w języku polskim lub angielskim, w
zależności od nagłówka Accept-Language
zapytania.Większość operacji API operujących na obiektach trzyma się standardowych schematów interfejsu i reguł działania. Są one szczegółowo opisane w tym miejscu.
Niektóre operacje API nie wpasowują się łatwo w standardowe schematy opisane powyżej lub wpasowują się jedynie częściowo. Takie niestandardowe operacje dzielą się na dwie kategorie:
Pierwsza z tych kategorii zawiera na przykład operacje pobierania danych do wykresów (charts
), operacja pobierania
danych Service Level z wybranego przedziału czasowego, operacja pobierania pliku HAR, czy skompresowanej zawartości strony z momentu
awarii.
Wszystkie tego typu operacje wykorzystują metodę HTTP GET.
Definiują własny format (i być może typ) odpowiedzi, mogą także określać niestandardowe parametry i nagłówki.
Wyjątkiem są operacje "zaawansowanego pobierania", (POST */search
), które są zaimplementowane jako POST ze względu na
ograniczenia GET (operacje te działają podobnie do pobierania listy obiektów, ale zamiast w parametrach GET parametry są
przekazywane jako JSON, w treści zapytania).
Operacje z drugiej kategorii to np. operacje modyfikujące wiele obiektów jednocześnie ("bulk"), operacje wymuszania analiz, wysyłania testowych SMS, zmiany hasła do konta, czy rejestracji konta. Wszystkie wykorzystują metodę HTTP POST i definiują własny format zapytania oraz odpowiedzi. Wyjątkiem jest operacja aktywacji konta, która wykorzystuje metodę GET ze względu na to, że jej adres URL służy jako link aktywacyjny w wiadomości potwierdzającej adres e-mail użytkownika.
Format zapisu wartości określających moment w czasie odpowiada tokenowi date-time
gramatyki zdefiniowanej w punkcie 5.6
RFC 3339 ("Internet Date/Time Format"). Format ten jest podzbiorem standardu
ISO 8601. Przykłady poprawnych określeń daty i czasu w tym formacie:
2016-01-01T00:00:00Z
2000-02-15T15:30:45+01:00
1980-11-30T08:00:30-08:00
Ze względów technicznych API nie obsługuje dat wcześniejszych niż 1970-00-00T00:00:00Z
oraz późniejszych niż 9999-12-31T23:59:59Z
.
Przekazując daty w tym formacie do API można użyć dowolnego przesunięcia strefy czasowej, ale jest wymagane jego jawne określenie, aby uniknąć niejednoznaczności. Znak "T" można zastąpić pojedynczą spacją.
Można także alternatywnie użyć pojedynczej nieujemnej liczby całkowitej w miejsce czasu - zostanie ona zinterpretowana jako timestamp uniksowy. Liczby ujemne są interpretowane jako określenie czasu w przeszłości względem aktualnego czasu, np. "-7200" oznacza "2 godziny temu".
API zawsze zwraca czas w formacie RFC 3339, z przesunięciem Z
(+00:00
, UTC).
API udostępnia 4 metody autentykacji: HTTP Basic Auth, OAuth2, operacje na zasobie auth_token
oraz na zasobie sessions
.
Najprostsza metoda autentykacji. W tej metodzie autentykacja przebiega poprzez wysłanie odpowiednio zakodowanego loginu i hasła użytkownika w nagłówku
Authorization
zapytania HTTP do API. W programie curl
służy do tego opcja -u
, na przykład:
curl -u USERNAME:PASSWORD 'https://api.monit24.pl/v3/services'
W przypadku użycia tej metody autentykacji, zasięg (customer
lub administrator
) zostanie wykryty automatycznie.
Możliwa jest także autentykacja za pomocą operacji na obiektach sesji.
Sesję można utworzyć wykonując zapytanie POST
z loginem i hasłem na adres /sessions
, na przykład:
curl -X POST -H 'Content-Type: application/json' -d '{"username":"USERNAME","password":"PASSWORD"}' \ 'https://api.monit24.pl/v3/sessions' { "id" : "1c24bf6c90ecc2be5330ccef6dcd225846098197", "token" : "a42657354f9c90b9f4e25225e9c644a5" }
W odpowiedzi otrzymujemy identyfikator utworzonego obiektu sesji oraz token dostępowy stowarzyszony z nią. Nie jest możliwe późniejsze pobranie tego tokena, dlatego należy go zapamiętać po stronie klienta API.
Token można wykorzystać do autentykacji przekazując go w nagłówku Authorization z typem "Bearer", na przykład:
curl -H 'Authorization: Bearer a42657354f9c90b9f4e25225e9c644a5' https://api.monit24.pl/v3/services
Informacje o aktualnie posiadanej sesji (lub innej, znając jej identyfikator)
można pobrać za pomocą operacji GET /sessions/my_session
:
curl -H 'Authorization: Bearer a42657354f9c90b9f4e25225e9c644a5' 'https://api.monit24.pl/v3/sessions/my_session'
Przykładowa odpowiedź:
{ "account_id" : 1, "created_at" : "2020-02-21T08:46:12Z", "distribution_id" : null, "expiration_duration" : 3600, "expiration_time" : "2020-02-21T09:48:46Z", "id" : "1c24bf6c90ecc2be5330ccef6dcd225846098197", "manager_id" : null, "scope" : "customer", "user_agent" : "HTTPClient/1.0 (2.8.3, ruby 2.5.5 (2019-03-15))" }
Odpowiedź zawiera między innymi pozostały czas ważności tokena (jest on przedłużany przy
wykonywaniu operacji API, przy tworzeniu tokena można go zmienić za pomocą parametru expiration_duration
)
i zasięg autoryzacji ("customer" dla użytkowników lub "administrator" dla administratorów).
UWAGA: zasób auth_token
jest przestarzały i zostanie usunięty w jednej z nadchodzących wersji API. Zamiast niego należy używać operacji na zasobie sessions
.
Możliwa jest także autentykacja za pomocą starszych operacji na tokenie aktualnej sesji.
Token można uzyskać wykonując zapytanie POST
z loginem i hasłem na adres /auth_token
, na przykład:
curl -X POST -H 'Content-Type: application/json' -d '{"username":"USERNAME","password":"PASSWORD"}' \ 'https://api.monit24.pl/v3/auth_token' { "id" : "29e35628844df0696f437c7a6e255a88" }
Token można wykorzystać do autentykacji przekazując go w nagłówku Authorization z typem "Bearer", na przykład:
curl -H 'Authorization: Bearer 29e35628844df0696f437c7a6e255a88' https://api.monit24.pl/v3/services
Informacje o aktualnie posiadanej sesji można pobrać za pomocą operacji GET /auth_token
:
curl -H 'Authorization: Bearer 29e35628844df0696f437c7a6e255a88' 'https://api.monit24.pl/v3/auth_token'
Przykładowa odpowiedź:
{ "account_id" : 104, "expires_in" : 1800, "id" : "29e35628844df0696f437c7a6e255a88", "scope" : "customer" }
Odpowiedź zawiera między innymi pozostały czas ważności tokena (jest on przedłużany przy
wykonywaniu operacji API, przy tworzeniu tokena można go zmienić za pomocą parametru timeout
)
i zasięg autoryzacji ("customer" dla użytkowników lub "administrator" dla administratorów).
Sesję można zakończyć wykonując zapytanie DELETE /auth_token
.
Ostatnią z dostępnych metod autentykacji jest wykorzystanie OAuth2 w trybie implicit. Od poprzedniej metody różni się jedynie sposobem pozyskania tokena sesji - polega na przekierowaniu użytkownika do formularza logowania na serwerze autoryzacji Monit24.pl wraz z adresem przekierowania po poprawnej autentykacji i innymi parametrami zdefiniowanymi w specyfikacji OAuth2.
Tokeny generowane przez operacje na zasobach /auth_token
i sessions
mogą być stosowane
zamiennie z uzyskanymi przez OAuth2. Przykład działania można zobaczyć logując się do
Monit24.pl za pomocą OAuth2 w interaktywnej dokumentacji API.
Aktualnie posiadane uprawnienia do poszczególnych obiektów można pobrać za pomocą operacji GET na odpowiednim zasobie permissions
.
Na przykład, aby pobrać nasze uprawnienia do grupy o identyfikatorze 123456, można wykonać następujące zapytanie:
curl -u USERNAME:PASSWORD 'https://api.monit24.pl/v3/groups/123456/permissions'
Przykładowa odpowiedź API:
{ "create_periodic_report_addresses" : true, "create_notification_addresses" : true, "create_services" : true, "delete" : false, "own" : true, "read" : true, "send_test_sms_notifications" : true, "share" : true, "update" : true }
Każdy obiekt permissions
będzie zawierał standardowe pola:
Poza tymi standardowymi polami, obiekt permissions
może zawierać inne pola, różne dla różnych typów obiektów.
Dla grupy są to:
W większości przypadków można użyć mechanizmu dowiązywania ("embed"), aby pobrać uprawnienia razem z obiektem lub obiektami. Można także filtrować i sortować względem uprawnień.
Zasady obliczania uprawnień do poszczególnych typów obiektów są szczegółowo opisane w tym miejscu.
Słowniki to proste zasoby mające następujące właściwości:
Przykładami słowników są kanały powiadomień (notification_channels
) lub języki, które można przypisać do konta (languages
).
Słowniki są dostępne jako podzasoby zasobu /dictionaries
.
Nie posiadają stowarzyszonych obiektów uprawnień, zaś nazwy i opisy podlegają tłumaczeniom w zależności od nagłówka Accept-Language
.
API wspiera wykorzystanie pamięci podręcznej (cache) po stronie klienta na dwa sposoby:
Konta użytkowników posiadają dwa atrybuty odpowiedzialne za dostosowanie sposobu działania systemu monitorującego do lokalizacji i preferowanego języka użytkownika:
language_id
i time_zone_id
.
Atrybut language_id
określa preferowany język użytkownika.
Jest to identyfikator jednego z elementów słownika languages
.
Jego zmiana wpływa na:
Atrybut time_zone_id
określa strefę czasową konta.
Jest to identyfikator jednego z elementów słownika time_zones
.
Jego zmiana wpływa na:
Uwaga: aktualnie raporty okresowe są zawsze wysyłane dla strefy czasowej Europe/Warsaw, która jest także domyślną strefą nowych kont. W przyszłości raporty będą wysyłane w strefie czasowej konta, którego dotyczą.
Schemat numeracji wersji API jest w dużej części zgodny z zasadami Semantic Versioning. Numer wersji składa się z trzech liczb oddzielonych kropkami, w kolejności: MAJOR, MINOR i PATCH, przy czym PATCH nie jest obowiązkowy i domyślnie ma wartość 0. Na przykład wersja "3.1.5" składa się z MAJOR równego 3, MINOR równego 1 i PATCH równego 5. Numery specjalnych wersji (np. beta) mogą na końcu zawierać dodatkowe znaki, oddzielone od podstawowego numeru myślnikiem. Zmiany wprowadzane w poszczególnych wersjach będą opisane w historii zmian API.
Zmiany poszczególnych części numeru wersji mają różne znaczenie.
Zmiana głównego numeru wersji (np. z 3.1.4 na 4.0) oznacza duże zmiany, które nie są kompatybilne wstecznie. W takim przypadku zmienia się adres URL operacji API (np. fragment "/v3/" zmienia się na "/v4/"), zaś operacje z poprzedniej wersji są dostępne przez odpowiednio długi czas równolegle z nową wersją, aby umożliwić dostosowanie aplikacji klienckich do nowej wersji. Każda zmiana głównej wersji będzie opatrzona dokumentem szczegółowo opisującym poszczególne niekompatybilne wstecznie zmiany.
Wersje MINOR mogą zawierać zmiany interfejsu API, które są kompatybilne wstecznie. Przykładem takich zmian jest dodanie nowej operacji API lub nowego pola do obiektu. Takie wersje nie wiążą się ze zmianą adresu URL operacji API.
Wersje PATCH nie zawierają zmian w interfejsie API. Służą do drobnych poprawek (np. literówek w dokumentacji) oraz naprawiania znalezionych błędów w działaniu operacji API.