Changelog
2026-10-07: GET /api/v1/payouts/ready zwraca strony
Niezgodna wstecz zmiana struktury istniejącego endpointu.
- Odpowiedź to standardowa koperta ze stronami.
GET /api/v1/payouts/readyzwraca{ items, page, pageSize, total, totalPages }jak wszystkie inne endpointy list, zamiast samej tablicy. Wiersze witemssię nie zmieniają. - Parametry zapytania
pageipageSize. Domyślniepageto 1, apageSize20, maksymalnie 100. Pobieraj kolejne strony, dopóki nie zachodzipage >= totalPages, aby odczytać wszystkie wpisy gotowe do wypłaty. - Przed wypłatą pobierz wszystkie strony. Wypłacone wpisy znikają z listy, więc pozostałe
wpisy przesuwają się na wcześniejsze strony. Najpierw pobierz wszystkie strony, usuń
duplikaty według
id, a dopiero potem utwórz wypłatę przezPOST /api/v1/payouts. Wypłacanie strona po stronie pomija wpisy. - Kolejność się nie zmienia. Ostatnio zatwierdzone wpisy są pierwsze.
2026-10-05: vehicleId przy wydatkach innych niż kilometrówka jest ignorowany
Zmiana zachowania w istniejących endpointach; brak zmian w strukturze.
- Pojazd jest zapisywany tylko przy wydatkach z tytułu kilometrówki.
POST /api/v1/travel-entries/{id}/expenses,PUT /api/v1/travel-entries/{id}/expenses/{expenseId}orazexpenseswPOST /api/v1/travel-entrieszapisują wydatek na paliwo, opłatę drogową, parking, nocleg lub inny wydatek bez pojazdu, a każdy odczyt zwraca dla niegovehicle: null.vehicleIdwysłany przy takim wydatku był dotąd zapisywany i zwracany w odpowiedzi. - Istniejące wartości są czyszczone. Przy aktualizacji usuwana jest wartość pola
vehicleprzy istniejących wydatkach innych niż kilometrówka, więc i one zwracająvehicle: null. - Pojazd spoza Twojej firmy jest odrzucany przy każdym rodzaju wydatku. Jeśli
vehicleIdwskazuje pojazd spoza Twojej firmy, API zwraca 400VALIDATION_FAILED, także przy wydatkach innych niż kilometrówka. Przy tych wydatkach endpointy pojedynczego wydatku zapisywały dotądvehicleIdbez sprawdzenia. Zarchiwizowany samochód służbowy przy wydatku innym niż kilometrówka nie jest już odrzucany przezPOST /api/v1/travel-entries; jest tam ignorowany jak każdy inny pojazd.
2026-10-03: tworzenie pojazdu odrzuca nieznany type
Zmiana zachowania w istniejącym endpoincie; brak zmian w strukturze.
POST /api/v1/vehiclesz wartościątypespozaCompanyiPersonalzwraca 400. Wartość liczbowa, taka jak2(usunięty typ transportu publicznego), była dotąd zapisywana. Teraz jest odrzucana odpowiedzią 400VALIDATION_FAILEDwerrors.Type, tak jak już robił toPUT /api/v1/vehicles/{id}.
2026-10-03: nowe uprawnienie ManageVehicles, zapisy pojazdów go wymagają
Nowa wartość enuma i zmiany uprawnień w istniejących endpointach dotyczących pojazdów; brak zmian w strukturze.
ManageVehicleswCompanyPermissions. Nowa flaga atomowa do zarządzania samochodami służbowymi: same pojazdy, ich koszty, dokumenty, terminy i przypomnienia e-mail. Odpowiedzi dotyczące pracowników i komunikaty webhook wymieniają ją jak każdą inną flagę, a każdyCompanyAdminma ją teraz przyznaną.ManageCompanyDatanadal obejmuje działy, miejsca powstawania kosztów i kursy walut, ale już nie pojazdy.- Zapisy pojazdów wymagają
ManageVehicles.POST /api/v1/vehicles,PUT /api/v1/vehicles/{id},DELETE /api/v1/vehicles/{id},POST /api/v1/vehicles/{id}/archiveiPOST /api/v1/vehicles/{id}/unarchivezwracają 403 wywołującemu bez tego uprawnienia, niezależnie od pozostałych uprawnień. Każdy pracownik, który przed tym wydaniem miałManageCompanyData, otrzymałManageVehicles, więc żaden istniejący użytkownik nie traci dostępu. - Odczyt prywatnych pojazdów innych pracowników wymaga
ManageVehicles.GET /api/v1/vehiclesiGET /api/v1/vehicles/{id}zwracają prywatne pojazdy innych pracowników tylko wywołującemu z uprawnieniemManageVehicleslubEditAllEntries(dotądManageCompanyData). - Odsyłaj całą listę. Klient, który odrzuca nieznane nazwy flag, a potem zapisuje uprawnienia pracownika z powrotem, usuwa temu pracownikowi
ManageVehicles. Przy odsyłaniu uprawnień zachowuj nieznane nazwy. - Zestaw
FleetManagerna wejściu. Zapis uprawnień akceptujeFleetManager, który serwer zapisuje jakoReadAllEntriesiManageVehicles. Wynik pozostaje listą flag atomowych.
2026-10-03: moc silnika w pojazdach
Dodatkowe pole kontraktu; brak zmian w strukturze.
enginePowerKww pojazdach. Żądania utworzenia i aktualizacji pojazdu akceptują opcjonalną maksymalną moc silnika jako liczbę całkowitą w kilowatach (pole P.2 dowodu rejestracyjnego, od 1 do 2000), a odpowiedź ze szczegółami oraz lista pojazdów ją zwracają. Przy aktualizacji pominięcie pola zachowuje zapisaną wartość, a0ją czyści.
2026-10-03: uszkodzone bajty obrazu w załącznikach multipart zwracają 400
Zmiana działania dwóch istniejących endpointów; brak zmian w strukturze.
POST /api/v1/travel-entrieszałącznik multipart z uszkodzonymi bajtami obrazu zwraca 400. Załącznik, którego zadeklarowany typ to obraz, ale którego bajty nie dają się zdekodować jako obraz, wcześniej kończył się 500. Teraz jest odrzucany odpowiedzią 400VALIDATION_FAILEDpoderrors.attachments, w tej samej strukturze co każdy inny odrzucony typ załącznika.POST /api/v1/travel-entries/{id}/attachmentsz tym samym uszkodzonym obrazem również zwraca 400. Endpoint załączników wcześniej w tym przypadku również kończył się 500. Teraz żądanie jest odrzucane odpowiedzią 400VALIDATION_FAILEDpoderrors.File, w tej samej strukturze co każdy inny odrzucony typ załącznika.
2026-10-02: usunięcie pojazdu odrzuca pojazd w użyciu, nowy endpoint archiwizacji
Zmiana działania istniejącego endpointu i jeden nowy endpoint; brak zmian w strukturze.
DELETE /api/v1/vehicles/{id}zwraca 409 dla pojazdu w użyciu. Pojazd, który występuje w wydatku delegacji lub ma zapisany koszt, nie jest już archiwizowany zamiast usunięcia. Usunięte delegacje oraz usunięte wydatki i koszty nie są liczone, więc pojazd można usunąć po odpięciu go od wydatków i usunięciu jego kosztów. Żądanie jest odrzucane odpowiedzią 409CONFLICT, a pojazd pozostaje bez zmian. Pojazd bez takich zapisów, zarchiwizowany lub nie, nadal jest usuwany z odpowiedzią 204.POST /api/v1/vehicles/{id}/archive. Archiwizuje pojazd, w użyciu lub nie, i zwraca go zisArchived: true. W ten sposób archiwizuje się pojazd, którego usunięcie jest odrzucane. Archiwizacja zarchiwizowanego pojazdu niczego nie zmienia;POST /api/v1/vehicles/{id}/unarchiveją cofa. Wymaga tego samego uprawnieniaManageCompanyDataco usunięcie.
2026-09-28: wycofane nadpisanie poza oknem nocnym
Przestarzałe pola; brak zmian w strukturze.
nightOffWindowOverrideinightOverrideReasonprzy ryczałtach delegacji. Oba pola pozostają w odpowiedzi, jeden element na noc, ale każdy element to teraz odpowiedniofalseinull. Nadpisanie, które zwracały, zostało wycofane: odpowiedź dotyczącą nocy krótszej niż sześć godzin podaje się przeznightAllocationi żadne nadpisanie nie zmienia kwoty. Przestań je odczytywać; mogą zostać usunięte w jednej z kolejnych wersji.
2026-09-28: dane do wyceny paliwa w wydatkach z tytułu kilometrówki
Dodatkowe pola kontraktu; brak zmian w strukturze.
fuelUnitPriceOverrideimileagePetrolGradeprzy wydatkach. Żądania utworzenia i aktualizacji wydatku przyjmują oba pola, także dla wydatków zagnieżdżonych w żądaniu utworzenia wpisu podróży, a każda odpowiedź z wydatkiem je zwraca, również wewnątrz wpisu podróży.fuelUnitPriceOverrideto cena paliwa za litr (za kWh dla pojazdu elektrycznego) potwierdzona paragonem, w walucie bazowej firmy; w pozycji kilometrówki w CZ lub SK zastępuje średnią cenę ustawową w składniku paliwowym.mileagePetrolGrade(Octane95lubOctane98) wybiera czeską średnią cenę ustawową benzyny Natural 95 lub Natural 98 dla własnego pojazdu benzynowego bez ceny z paragonu. Każde pole jest zapisywane tylko tam, gdzie wpływa na wycenę pozycji, a wszędzie indziej ma wartośćnull. Aktualizacja to pełne zastąpienie: pominięcie pól powoduje przeliczenie pozycji po średniej cenie ustawowej, dla benzyny po cenie Naturalu 95, więc aby zachować cenę z paragonu lub wybór benzyny 98, odeślij wartości zwrócone przez wydatek.
2026-09-16 – miejsca powstawania kosztów przy pracownikach
Dodatkowe pole kontraktu; brak zmian w strukturze.
costCenterIdsprzy pracownikach. Odpowiedź ze szczegółami pracownika oraz lista pracowników zwracają miejsca powstawania kosztów, które pracownik może obciążać, a żądania utworzenia i aktualizacji pracownika je przyjmują. Pusta lista oznacza brak ograniczeń – dostępne są wszystkie aktywne miejsca powstawania kosztów firmy. Przy tworzeniu pominięcie pola jest tym samym co przesłanie pustej listy. Przy aktualizacji pominięcie zachowuje zapisaną listę, pusta lista ją czyści, a lista z wartościami zastępuje ją w całości. Każdy identyfikator musi należeć do Twojej firmy, w przeciwnym razie żądanie zostanie odrzucone z kodem 400. Dodanie do wpisu miejsca powstawania kosztów spoza listy nadal jest odrzucane z kodem 400 – właśnie z powodu tego odrzucenia pole istnieje. Ograniczenie dotyczy wyłącznie dodawania: przypisania już obecne we wpisie nie są usuwane wstecznie, gdy miejsce powstawania kosztów zniknie z listy. Przy zapisie obowiązuje granica bezpieczeństwa 100 różnych miejsc powstawania kosztów na pracownika – duplikaty liczą się raz, a schemat publikuje ją jakomaxItemsw treści obu żądań. Kontroluje rozmiar żądania i nie jest limitem biznesowym: lista może wskazać tylko te miejsca powstawania kosztów, które firma faktycznie ma, więc w praktyce nie będzie ograniczeniem.
2026-09-13 – kwoty diet z planu podróży według czasu urzędowego
Poprawione kwoty w istniejących endpointach diet z planu podróży; brak zmian w strukturze.
- Wyliczanie diet z planu podróży i
from-itinerary. Wartościtimeprzystanków nadal są odczytywane jako UTC, a zwracane przedziały nadal są w UTC. Firmom czeskim i słowackim dni kalendarzowe dzielą się teraz o północy czasu praskiego lub bratysławskiego, a nie o północy UTC. Firmy polskie liczą noce (21:00–07:00), doby i daty rachunków według czasu warszawskiego. To samo żądanie może więc dla tych rynków zwrócić inne godziny i kwoty niż wcześniej.
2026-09-12 – category jest opcjonalne przy aktualizacji pojazdu
Złagodzone pole w istniejącym żądaniu; brak zmian w strukturze.
categoryprzy aktualizacji pojazdu. Pole jest teraz opcjonalne. Jego pominięcie zachowuje zapisaną kategorię; należy je przesłać, aby ją zmienić, w tym wartość0, aby celowo ją wyczyścić. Żądania utworzenia nadal wymagają tego pola.
2026-08-23 – pojemność silnika w pojazdach
Dodatkowe pole kontraktu; brak zmian w strukturze.
engineCapacityCcw pojazdach. Żądania utworzenia i aktualizacji pojazdu akceptują opcjonalną pojemność silnika jako liczbę całkowitą w centymetrach sześciennych, a odpowiedź ze szczegółami oraz lista pojazdów ją zwracają. Przy aktualizacji pominięcie pola zachowuje zapisaną wartość, a0ją czyści.
2026-08-17 – locked raportuje teraz blokady dokumentów
Skorygowana semantyka wartości w istniejącym polu odpowiedzi; brak zmian w strukturze.
lockedw odpowiedziach ze szczegółami i listą wpisów wcześniej raportowało tylko przestarzałą blokadę importu sprzed 2023 roku i miało wartośćfalsedla dokumentów zablokowanych w aplikacji, w tym automatycznej blokady nakładanej przy wypłacie. Obecnie pole to przenosi ten sam pochodny stan blokady, który webhookentry.updatedraportuje już wisLocked:true, gdy dokument jest zamknięty do zapisu. Należy interpretować to jako “ten wpis nie może być modyfikowany”, a nie jako znacznik konkretnego pochodzenia blokady.
2026-07-13 – identyfikatory miejsc, ręczne kursy wymiany walut, nadpisania diet, kierunek kursu wymiany
Dodatkowe, wstecznie kompatybilne pola kontraktu oraz nowy dyskryminator kursu wymiany walut.
- Identyfikatory miejsc we wpisach. Żądania utworzenia i aktualizacji akceptują
departureLocationPlaceIdorazdestinationPlaceId(Google Placesplace_id), a odpowiedź dla wpisu je zwraca. Należy przesłać zapisane wartości ponownie przy pełnej aktualizacji (pełne zastąpienie), aby zachować tożsamość miejsca podczas edycji tekstu docelowego. - Kraj docelowy we wpisach. Żądania akceptują opcjonalny
destinationCountryCode(ISO 3166-1 alpha-2). Po jego podaniu jest on zapisywany bezpośrednio, a zapasowe geokodowanie po stronie serwera jest pomijane. - Ręczne kursy wymiany walut. Żądania dotyczące wydatków i diet akceptują opcjonalny
manualExchangeRate, a żądania dotyczące wpisów akceptująmanualAdvanceExchangeRatedla zaliczki. Każdy z nich jest uwzględniany tylko wtedy, gdy dostawca kursów walut nie publikuje kursu dla daty referencyjnej; podanie go w sytuacji, gdy istnieje oficjalny kurs, skutkuje odrzuceniem żądania z błędemEXCHANGE_RATE_UNAVAILABLE. - Nadpisania diet. Żądanie dotyczące diety akceptuje
overrideAmountorazoverrideReason, a modele odczytu diety je zwracają. Aby zachować istniejące nadpisanie przy pełnej aktualizacji (pełne zastąpienie), należy przesłać te wartości ponownie; ich pominięcie usuwa nadpisanie i przywraca stawkę ustawową wypłaty. - Kierunek kursu wymiany walut.
GET /api/v1/reference/exchange-rateszawiera teraz dyskryminatordirection:ForeignPerBase(HNB / ECB) oznacza, że należy podzielić przez kurs, aby przeliczyć na walutę bazową, aBasePerForeign(CNB) oznacza, że należy pomnożyć.
2026-07-08 – data wypłaty zaliczki, dostawca kursów walut dla CZ/SK
Dwie dodatkowe, wstecznie kompatybilne zmiany.
- Data wypłaty zaliczki we wpisach. Żądania utworzenia i aktualizacji akceptują teraz opcjonalną
advancePaymentDate(yyyy-MM-dd), a odpowiedź dla wpisu ją zwraca. W przypadku pominięcia przy tworzeniu, serwer domyślnie ustawia ją na datę wpisu. Określa ona datę kursu wymiany dla zaliczki oraz, w przypadku organizacji czeskich (tenants), referencyjną datę kursu wymiany dla diety. - Dostawca kursów walut dla CZ/SK.
GET /api/v1/reference/exchange-ratesdokumentuje teraz pełny zestaw dostawców: HNB dla HR, ECB dla SI i SK, CNB dla CZ. Polesourcemoże mieć wartość"CNB", abaseCurrencyto natywna waluta bazowa dostawcy (EUR dla HNB/ECB, CZK dla CNB). Zachowanie pozostaje bez zmian; dokumentacja odpowiada teraz rzeczywistemu działaniu systemu.
2026-06-11 – liczba posiłków, pochodzenie kursu wymiany, kod niedostępności kursu walut
Trzy dodatkowe zmiany w interfejsie. Wszystkie są wstecznie kompatybilne: dotychczasowe payloady działają bez zmian, a nowe pola odpowiedzi to dodatki, które można zignorować, dopóki nie będą potrzebne.
- Liczba posiłków przy tworzeniu/aktualizacji diety. Żądania dotyczące diet akceptują teraz pola
breakfastsProvided,lunchesProvidedorazdinnersProvided(liczba poszczególnych posiłków jako liczba całkowita) oraz opcjonalne dzienne polemealsProvidedAllocation. Stanowią one kanoniczny model zapisu: serwer ponownie oblicza pomniejszenie diety na podstawie tych wartości. Dotychczasowe zagregowane polemealsProvidedz wersji v1 jest nadal akceptowane; w przypadku braku szczegółowych pól posiłków serwer mapuje agregat tak jak dotychczas, dzięki czemu starsi klienci nie odczują zmian. Odpowiedzi nadal zwracają wyliczonemealsProvided(obiad + kolacja, zgodnie z chorwackim Pravilnikiem) obok szczegółowej liczby posiłków, więc ścieżki odczytu pozostają bez zmian. - Pochodzenie kursu wymiany w odpowiedziach. Odpowiedzi dla wydatków i diet otrzymują pole
exchangeRateSource, a odpowiedź dla wpisu otrzymuje poleadvancePaymentExchangeRateSource, rejestrujące pochodzenie zastosowanego kursu: kod dostawcy ("HNB","ECB") dla oficjalnego kursu,"MANUAL"dla kursu podanego przez użytkownika lubnulldla wiersza w tej samej walucie (brak konwersji) bądź historycznego wiersza zapisanego przed wprowadzeniem śledzenia pochodzenia. Pola tylko do odczytu; brak zmian w żądaniach. - Nowy kod błędu
EXCHANGE_RATE_UNAVAILABLE(HTTP 400). Występuje, gdy dostawca kursów walut organizacji nie publikuje kursu dla danej waluty w żądanym dniu i nie istnieje żaden kurs historyczny, którego można użyć jako zapasowego. Jest to błąd z rodziny walidacji ze standardową strukturąerrorskluczowaną polami, co pozwala na precyzyjne odróżnienie przypadku niedostępności kursu i poproszenie o podanie kursu ręcznego. Dodano do katalogu błędów.
2026-05-23 – czasy przebiegu podróży w dietach zapisywane jako rzeczywiste UTC (poprawka)
Czasy diet zapisywane za pomocą POST /api/v1/travel-entries/{id}/per-diems/from-itinerary są teraz przechowywane jako rzeczywiste punkty w czasie UTC. Poprzednio odjazd/przyjazd dla każdego odcinka trasy był zapisywany przy użyciu czasu zegarowego oznaczonego jako UTC bez przesunięcia (odcinek o godzinie 08:00 czasu lokalnego był zapisywany jako 08:00Z zamiast 07:00Z/06:00Z), przez co wiersze wygenerowane na podstawie przebiegu podróży różniły się od wierszy dodanych ręcznie o 1-2 godziny i wyświetlały się z opóźnieniem. Schematy żądań i odpowiedzi pozostają bez zmian, ale wartości departureTime/arrivalTime zwracane przez ten endpoint (oraz zwracane przy późniejszych odczytach tych samych wierszy) odzwierciedlają teraz poprawiony punkt w czasie UTC. Bezstanowy podgląd kalkulatora nadal zwraca czasy zegarowe. Kwoty diet pozostają bez zmian.
2026-05-23 – kalkulator diet + zapis całej podróży
Interfejs obliczania diet został skonsolidowany i zyskał możliwość zapisu całej podróży, analogicznie do aplikacji webowej locco.
- Nowy
POST /api/v1/utilities/per-diems/calculate- bezstanowy kalkulator. Wyślij przebieg podróży (jeden odcinek = przebieg podróży z 2 punktami trasy) i otrzymaj obliczone wiersze z zastosowaną redystrybucją na poziomie przebiegu podróży. Brak kontekstu wpisu, nic nie jest zapisywane. - Nowy
POST /api/v1/travel-entries/{id}/per-diems/from-itinerary- odbuduj diety wpisu na podstawie przebiegu podróży w jednym wywołaniu. Serwer ponownie uruchamia własny silnik dla punktów trasy (przesłane kwoty nigdy nie są traktowane jako zaufane), stosuje posiłki dla poszczególnych odcinków kluczowane przez(countryCode, departureTime)(pary zwracane przez kalkulator), a następnie atomowo zastępuje diety wpisu. Pozwala to na odtworzenie redystrybucji na poziomie przebiegu podróży oraz podwyższeń stawek krajowych, czego nie da się osiągnąć, przesyłając wiersze pojedynczo. - Usunięto
POST /api/v1/travel-entries/{id}/per-diems/computeorazPOST /api/v1/per-diems/calculate-simple. Oba zostały zastąpione przezutilities/per-diems/calculate- pojedynczy odcinek to po prostu przebieg podróży z 2 punktami trasy. Należy przenieść integracje na nowy kalkulator.
2026-05-22 – obsługa rynku słoweńskiego
Wstępna obsługa słoweńskich organizacji (tenants). Zaktualizuj swojego klienta na podstawie odświeżonej migawki OpenAPI pod adresem /api-reference/:
- Słoweńskie gminy - nowy
GET /api/v1/reference/slovenian-municipalitieszwraca listę gmin SURS dla rozwijanych list miejsc na słoweńskich formularzach podróży. Możliwość wywołania z poziomu dowolnej organizacji. - Rezydencja podatkowa pracownika - rekordy pracowników otrzymują pole
residency(Resident/NonResident) na potrzeby raportowania słoweńskich diet i podatku od wynagrodzeń. Domyślna wartość toResident.
2026-04-28 – uruchomienie wersji v1.0
Pierwsze stabilne wydanie partnerskiego API locco. Każdy obszar jest połączony, otypowany i objęty migawką OpenAPI pod adresem /api-reference/:
- Wpisy - pełny CRUD oraz przejścia przepływu pracy (wyślij, zatwierdź, odrzuć, anuluj, zwróć do poprawy), z atomowym tworzeniem, które akceptuje zagnieżdżone wydatki, diety, alokacje miejsc powstawania kosztów oraz załączniki w jednym wywołaniu.
- Załączniki - bezpośrednie przesyłanie do wpisu za pomocą
POST /api/v1/travel-entries/{id}/attachments. Format multipart, do 5 plików na żądanie. - Webhooki - rejestracja subskrypcji z jednorazowym ujawnieniem klucza podpisywania (signing secret), historia dostarczeń dla każdej subskrypcji oraz endpoint ponawiania prób dla nieudanych lub wyczerpanych dostarczeń.
- Wypłaty - lista wpisów gotowych do wypłaty, tworzenie paczek, lista historii, usuwanie paczki.
- Pracownicy, Działy, Pojazdy, Miejsca powstawania kosztów - CRUD + lista, z wartościami pól niestandardowych dla pracowników.
- Dane referencyjne - chorwackie gminy, kursy wymiany walut HNB, tabela stawek diet, listy dozwolonych krajów i walut włączone dla firmy.
- Firma - odczyt profilu.
Wartości enum dla Status, TravelType, PayoutMethod i pozostałych są udokumentowane w schemacie OpenAPI jako listy dozwolonych wartości enum: [...], dzięki czemu wygenerowani klienci opierają się na kanonicznych ciągach znaków ("PendingApproval", "BankTransfer" itp.), a nie na niejasnych wartościach.