Zasady ogólne komunikacji¶
Dokument opisuje reguły wspólne dla całego API partnerskiego. Pozostałe dokumenty opisują poszczególne moduły i zakładają, że te zasady są znane.
Adresy¶
| Wszystkie ścieżki | zaczynają się od /partner/v1 |
| Dokumentacja interaktywna | /partner-api (Swagger UI), /partner-api-json (OpenAPI) |
| Socket.IO (czat) | ten sam host, szczegóły w dokumentacji czatu |
Adresy środowiska testowego i produkcyjnego przekażemy razem z poświadczeniami.
Swagger partnerski zawiera wyłącznie endpointy udostępnione integracji i pozwala przejść pełny przebieg bez pisania kodu: po wpisaniu poświadczeń w „Authorize" są one zapamiętywane między odświeżeniami strony.
Nagłówki¶
| Nagłówek | Wymagany | Znaczenie |
|---|---|---|
x-client-id |
zawsze | identyfikator integracji |
x-api-key |
zawsze | klucz integracji |
x-user-id |
prawie zawsze | użytkownik końcowy, w którego imieniu działa żądanie |
x-language |
nie | język odpowiedzi |
Klucz nigdy nie powinien opuścić backendu partnera. Całe REST API jest pomyślane jako komunikacja serwer–serwer; z przeglądarki nawiązywane jest wyłącznie połączenie Socket.IO, uwierzytelniane osobnym, krótkożyciowym tokenem.
x-user-id¶
Identyfikator zwracany przez POST /partner/v1/users przy zakładaniu konta.
To on rozstrzyga, czyje dane są odczytywane i modyfikowane — nie ma innego
mechanizmu sesji.
Wyjątki, w których nagłówek nie jest potrzebny: POST /partner/v1/users (użytkownik
jeszcze nie istnieje) oraz endpointy słownikowe niezwiązane z użytkownikiem.
Podanie identyfikatora spoza własnej integracji kończy się 401 — użytkownicy jednej
integracji są dla drugiej niewidoczni.
x-language¶
Dopuszczalne wartości: pl i en.
| Nagłówek | Użyty język |
|---|---|
| pominięty albo pusty | język zapisany na profilu użytkownika, a w jego braku en |
pl albo en |
ta wartość; wielkość liter bez znaczenia (PL działa jak pl) |
| cokolwiek innego | en — bez zaglądania w profil |
Ostatni wiersz bywa mylący: literówka w nagłówku nie kończy się błędem ani powrotem do języka użytkownika, tylko cichym przełączeniem całego interfejsu na angielski. Jeśli partner nie wysyła świadomie konkretnego języka, najbezpieczniej jest nagłówek pominąć i zdać się na profil.
Język profilu pochodzi z konfiguracji integracji i jest wspólny dla wszystkich jej użytkowników — szczegóły w dokumentacji użytkowników.
Język steruje wyłącznie treściami słownikowymi — nazwami ras, chorób, zabiegów, opisami triażu. Dane wprowadzone przez użytkownika wracają zawsze tak, jak je zapisano.
Jeden słownik jest wyjątkiem: nazwy leków są polskie niezależnie od języka — szczegóły w dokumentacji leków.
Uprawnienia¶
System partnera jest źródłem prawdy co do tego, kto ma prawo korzystać z usługi. My sprawdzamy dwie rzeczy:
- czy
x-user-idnależy do tej integracji, - czy zasób, którego dotyczy żądanie, należy do tego użytkownika.
Drugi punkt dotyczy każdego zasobu — zwierzaka, wizyty, leku, prediagnozy, konwersacji.
Odwołanie się do cudzego kończy się 403 albo 404, nawet przy poprawnym kluczu.
Subskrypcji nie sprawdzamy. Użytkownik założony przez integrację ma pełny i bezterminowy dostęp do uzgodnionego zakresu; decyzja, czy może z niego korzystać, należy do partnera.
Format odpowiedzi¶
Odpowiedzi to czysty JSON, bez koperty — obiekt zasobu albo obiekt z nazwanym
polem, zależnie od endpointu. Nie ma wspólnego opakowania w rodzaju { data: … }.
Błędy mają jeden kształt:
message bywa kluczem tłumaczenia (postać errors::…) — to identyfikator
komunikatu w naszym systemie, nie tekst dla użytkownika. Treść komunikatu należy do
partnera; do rozpoznania sytuacji służy statusCode i sam klucz.
Przy błędach walidacji message jest tablicą opisów pól:
{ "statusCode": 400,
"message": ["date should not be empty", "treatAsWrapper must be a boolean value"],
"error": "Bad Request" }
Kody¶
| Kod | Znaczenie |
|---|---|
400 |
błąd walidacji ciała lub parametrów |
401 |
brak lub nieprawidłowe poświadczenia, albo nieznany x-user-id |
403 |
zasób nie należy do tego użytkownika |
404 |
zasób nie istnieje albo nie należy do wskazanego rodzica |
409 |
konflikt — dziś wyłącznie zajęty numer mikroczipa |
422 |
żądanie poprawne, ale niewykonalne przy obecnym stanie danych — np. wyliczenie diety dla nieuzupełnionego profilu |
500 |
błąd po naszej stronie; prosimy o zgłoszenie z czasem i treścią żądania |
Pole nieznane w ciele żądania kończy się 400, a nie cichym pominięciem:
{ "statusCode": 400,
"message": ["property treatAsWraper should not exist"],
"error": "Bad Request" }
Robimy to celowo — literówka w nazwie pola inaczej wyglądałaby jak poprawne żądanie, którego skutek po prostu nie nastąpił.
Stronicowanie¶
Nie ma jednego wzorca — moduły powstawały w różnym czasie i zachowujemy ich istniejące kontrakty:
| Wzorzec | Gdzie | Uwagi |
|---|---|---|
page + take |
listy zwierzaków | page liczone od zera, w odpowiedzi total |
skip + take |
pielęgnacja | w odpowiedzi count |
cursor + take |
oś czasu, czat | koniec listy to nextCursor: null |
take ma na listach sufit 100 i własną wartość domyślną w każdym module. Wartość
większa jest cicho przycinana do sufitu, nie powoduje błędu.
Wyjątkiem jest słownik leków (GET /pets/medicines-list), który domyślnie zwraca
wszystkie pozycje — jest pomyślany jako dane do podpowiadarki, nie jako lista do
przeglądania. Szczegóły w dokumentacji leków.
Daty i godziny¶
- daty przyjmujemy w obu postaciach:
YYYY-MM-DDalbo pełne ISO 8601 (2026-09-04T00:00:00.000Z). Sama data jest rozumiana jako północ UTC, więc przy strefach na wschód od UTC warto przesyłać pełny znacznik czasu, gdy liczy się konkretny dzień lokalny - w odpowiedziach daty wracają zawsze w pełnym ISO 8601
- godziny w ciele żądań i odpowiedziach modułów medycznych to tekst
"HH:MM" - wyjątek: oś czasu, gdzie
houriminutesą liczbami — szczegóły w jej dokumentacji
Wersjonowanie¶
Ścieżki zawierają v1. Zmiany niezgodne wstecz trafią do nowej wersji, a sposób
wygaszania poprzedniej ustalimy wspólnie. Zmiany zgodne wstecz — nowe pola
w odpowiedziach, nowe endpointy, nowe wartości pól opcjonalnych — mogą pojawić się
w v1 bez uprzedzenia, dlatego prosimy o tolerancyjne parsowanie: nieznane pole
w odpowiedzi nie powinno psuć integracji.
Zdarzenia przychodzące¶
Wszystko, co dzieje się po naszej stronie bez udziału partnera — odpowiedź weterynarza, przypomnienie, ankieta po wizycie — dociera webhookiem. Nie wysyłamy użytkownikom partnera naszych maili, powiadomień ani pushy. Szczegóły w dokumentacji webhooków.