Seznam změn

2026-10-07: GET /api/v1/payouts/ready vrací stránky

Zpětně nekompatibilní změna struktury existujícího endpointu.

  • Odpověď je standardní stránkovaná obálka. GET /api/v1/payouts/ready vrací { items, page, pageSize, total, totalPages } jako všechny ostatní seznamové endpointy, místo holého pole. Řádky uvnitř items se nemění.
  • Parametry dotazu page a pageSize. Výchozí je page 1 a pageSize 20, maximum 100. Načítejte stránky, dokud neplatí page >= totalPages, abyste přečetli všechny záznamy připravené k výplatě.
  • Před výplatou načtěte všechny stránky. Vyplacené záznamy ze seznamu mizí, takže se zbývající záznamy přesouvají na předchozí stránky. Nejdřív načtěte všechny stránky, odstraňte duplicity podle id a teprve potom vytvořte výplatu přes POST /api/v1/payouts. Při výplatě stránku po stránce některé záznamy přeskočíte.
  • Pořadí se nemění. Naposledy schválené záznamy jsou první.

2026-10-05: vehicleId u výdajů, které nejsou kilometrovné, se ignoruje

Změna chování existujících endpointů; struktura beze změny.

  • Vozidlo si ponechávají jen výdaje na kilometrovné. POST /api/v1/travel-entries/{id}/expenses, PUT /api/v1/travel-entries/{id}/expenses/{expenseId} a expenses v POST /api/v1/travel-entries ukládají výdaj za palivo, mýtné, parkování, ubytování nebo jiný výdaj bez vozidla a každé čtení pro něj vrací vehicle: null. vehicleId odeslané u takového výdaje se dosud ukládalo a vracelo v odpovědi.
  • Stávající hodnoty se mažou. Při aktualizaci se odebere vozidlo uložené u stávajících výdajů, které nejsou kilometrovné, takže i ty vracejí vehicle: null.
  • Vozidlo mimo vaši firmu se odmítá u každého typu výdaje. Pokud vehicleId označuje vozidlo mimo vaši firmu, API vrací 400 VALIDATION_FAILED, i u výdajů kromě kilometrovného. U těchto výdajů endpointy pro jednotlivý výdaj dosud ukládaly vehicleId bez kontroly. Archivované služební vozidlo u výdaje, který není kilometrovné, už POST /api/v1/travel-entries neodmítá; ignoruje se tam jako každé jiné vozidlo.

2026-10-03: vytvoření vozidla odmítne neznámý type

Změna chování u existujícího endpointu; struktura beze změny.

  • POST /api/v1/vehicles s hodnotou type mimo Company a Personal vrací 400. Číselná hodnota jako 2 (odebraný typ pro veřejnou dopravu) se dosud uložila. Nyní ji odmítne odpověď 400 VALIDATION_FAILED pod errors.Type, jak to PUT /api/v1/vehicles/{id} už dělal.

2026-10-03: nové oprávnění ManageVehicles pro změny vozidel

Nová hodnota enumu a změny oprávnění u existujících endpointů pro vozidla; struktura beze změny.

  • ManageVehicles v CompanyPermissions. Nový atomický příznak pro správu firemních vozů: samotná vozidla, jejich náklady, dokumenty, termíny a připomínky e-mailem. Odpovědi s údaji o zaměstnancích i webhookové zprávy ho uvádějí jako každý jiný příznak a každý CompanyAdmin ho nyní má. ManageCompanyData dál pokrývá oddělení, nákladová střediska a směnné kurzy, vozidla už ne.
  • Operace měnící vozidla vyžadují ManageVehicles. POST /api/v1/vehicles, PUT /api/v1/vehicles/{id}, DELETE /api/v1/vehicles/{id}, POST /api/v1/vehicles/{id}/archive a POST /api/v1/vehicles/{id}/unarchive vracejí 403 volajícímu bez něj, bez ohledu na ostatní oprávnění. Každý zaměstnanec, který měl před tímto vydáním ManageCompanyData, dostal ManageVehicles, takže žádný stávající uživatel nepřijde o přístup.
  • Čtení soukromých vozidel ostatních zaměstnanců vyžaduje ManageVehicles. GET /api/v1/vehicles a GET /api/v1/vehicles/{id} vracejí soukromá vozidla ostatních zaměstnanců jen volajícímu s oprávněním ManageVehicles nebo EditAllEntries (dosud ManageCompanyData).
  • Posílejte zpět celý seznam. Klient, který zahodí neznámé názvy příznaků a pak zapíše oprávnění zaměstnance zpět, tomuto zaměstnanci odebere ManageVehicles. Při zpětném odesílání oprávnění neznámé názvy zachovejte.
  • Předvolba FleetManager na vstupu. Zápis oprávnění přijímá FleetManager, který server uloží jako ReadAllEntries a ManageVehicles. Výstupem zůstává seznam atomických příznaků.

2026-10-03: výkon motoru u vozidel

Aditivní pole kontraktu; beze změny struktury.

  • enginePowerKw u vozidel. Požadavky na vytvoření a úpravu vozidla přijímají volitelný maximální výkon motoru jako celé číslo v kilowattech (pole P.2 osvědčení o registraci vozidla, 1 až 2000) a vracejí jej jak odpověď s detailem vozidla, tak seznam vozidel. Při úpravě vynechání uloženou hodnotu zachová a 0 ji smaže.

2026-10-03: poškozené bajty obrázku u multipart příloh vracejí 400

Změna chování dvou existujících endpointů; struktura beze změny.

  • POST /api/v1/travel-entries multipart příloha s poškozenými bajty obrázku vrací 400. Příloha, jejíž deklarovaný typ je obrázek, ale jejíž bajty se nedají dekódovat jako obrázek, dříve skončila s 500. Nyní je odmítnuta odpovědí 400 VALIDATION_FAILED pod errors.attachments, ve stejné struktuře jako jakýkoli jiný odmítnutý typ přílohy.
  • POST /api/v1/travel-entries/{id}/attachments se stejným poškozeným obrázkem také vrací 400. Endpoint pro přílohy dříve v tomto případě stejně skončil s 500. Nyní je požadavek odmítnut odpovědí 400 VALIDATION_FAILED pod errors.File, ve stejné struktuře jako jakýkoli jiný odmítnutý typ přílohy.

2026-10-02: smazání vozidla odmítne používané vozidlo, nový endpoint pro archivaci

Změna chování existujícího endpointu a jeden nový endpoint; beze změny struktury.

  • DELETE /api/v1/vehicles/{id} vrací 409 pro používané vozidlo. Vozidlo, které je na náhradě cestovního příkazu nebo má zadaný náklad, se již místo smazání nearchivuje. Smazané cestovní příkazy a odebrané náhrady či náklady se nepočítají, takže vozidlo lze smazat, jakmile ho odeberete z náhrad a smažete jeho náklady. Požadavek je odmítnut odpovědí 409 CONFLICT a vozidlo zůstane beze změny. Vozidlo bez takových záznamů, archivované či ne, se nadále smaže s odpovědí 204.
  • POST /api/v1/vehicles/{id}/archive. Archivuje vozidlo, používané či ne, a vrátí ho s isArchived: true. Takto se archivuje vozidlo, jehož smazání je odmítnuto. Archivace archivovaného vozidla nic nemění; POST /api/v1/vehicles/{id}/unarchive ji vrací zpět. Vyžaduje stejné oprávnění ManageCompanyData jako smazání.

2026-09-28: zastaralé přepsání mimo noční okno

Zastaralá pole; beze změny struktury.

  • nightOffWindowOverride a nightOverrideReason u paušálů cestovního příkazu. Obě pole v odpovědi zůstávají, jeden prvek na noc, ale každý prvek je nyní false, resp. null. Přepsání, které vykazovala, je zrušeno: odpověď pro noc kratší než šest hodin se zadává přes nightAllocation a žádné přepsání nemění částku. Přestaňte je číst; v některé z příštích verzí mohou být odstraněna.

2026-09-28: vstupy pro cenu pohonné hmoty u náhrad za použití vozidla

Přidaná pole kontraktu; beze změny struktury.

  • fuelUnitPriceOverride a mileagePetrolGrade u výdajů. Požadavky na vytvoření i úpravu výdaje přijímají obě pole, včetně výdajů vnořených do požadavku na vytvoření cestovního příkazu, a každá odpověď s výdajem je vrací, i uvnitř cestovního příkazu. fuelUnitPriceOverride je cena pohonné hmoty za litr (za kWh u elektromobilu) doložená dokladem, v základní měně společnosti; na řádku náhrady za použití vozidla v CZ nebo SK nahrazuje průměrnou cenu podle vyhlášky ve složce za pohonné hmoty. mileagePetrolGrade (Octane95 nebo Octane98) vybírá průměrnou cenu benzinu Natural 95 nebo Natural 98 podle české vyhlášky pro vlastní vozidlo na benzin bez ceny z dokladu. Každé pole se ukládá jen tam, kde ovlivňuje ocenění řádku, jinde je null. Úprava je úplné nahrazení: když je vynecháte, řádek se přepočítá průměrnou cenou podle vyhlášky, u benzinu cenou Naturalu 95, proto pošlete hodnoty, které výdaj vrátil, abyste zachovali cenu z dokladu nebo benzin 98.

2026-09-16 — nákladová střediska u zaměstnanců

Přidané pole kontraktu; beze změny struktury.

  • costCenterIds u zaměstnanců. Odpověď s detailem zaměstnance i seznam zaměstnanců vracejí nákladová střediska, na která zaměstnanec smí účtovat, a požadavky na vytvoření i úpravu zaměstnance je přijímají. Prázdný seznam znamená bez omezení — k dispozici jsou všechna aktivní nákladová střediska firmy. Při vytváření je vynechání pole totéž jako poslání prázdného seznamu. Při úpravě vynechání zachová uložený seznam, prázdný seznam jej vymaže a seznam s hodnotami jej celý nahradí. Každé id musí patřit vaší firmě, jinak je požadavek odmítnut s 400. Přidání nákladového střediska mimo seznam na cestovní příkaz je nadále odmítnuto s 400 — právě kvůli tomuto odmítnutí pole existuje. Omezení platí jen pro přidávání: již přiřazená nákladová střediska se zpětně neodebírají, když středisko ze seznamu zmizí. Pro zápis platí bezpečnostní mez 100 různých nákladových středisek na zaměstnance — duplicity se počítají jednou a schéma tuto mez publikuje jako maxItems u obou těl požadavku. Hlídá velikost požadavku, není to obchodní limit: seznam může uvést jen nákladová střediska, která firma skutečně má, takže vás v praxi neomezí.

2026-09-13 — částky stravného podle itineráře v zákonném čase

Opravené částky na existujících endpointech stravného podle itineráře; beze změny struktury.

  • Výpočet stravného podle itineráře a from-itinerary. Hodnoty time u zastávek se nadále čtou jako UTC a vrácená okna jsou nadále v UTC. Českým a slovenským firmám se kalendářní dny nyní dělí o půlnoci pražského, respektive bratislavského času, nikoli o půlnoci UTC. Polské firmy počítají noci (21:00–07:00), doby a data účtů podle varšavského času. Stejný požadavek proto může pro tyto trhy vrátit jiné hodiny a částky než dříve.

2026-09-12 — category je při úpravě vozidla volitelný

Uvolněné pole v existujícím požadavku; beze změny struktury.

  • category při úpravě vozidla. Pole je nyní volitelné. Když jej vynecháte, uložená kategorie zůstane beze změny; pošlete jej, když ji chcete změnit, včetně 0 pro záměrné vymazání. Při vytváření zůstává pole povinné.

2026-08-23 — objem motoru u vozidel

Aditivní pole kontraktu; beze změny struktury.

  • engineCapacityCc u vozidel. Požadavky na vytvoření a úpravu vozidla přijímají volitelný objem motoru jako celé číslo v cm³ a vracejí jej jak odpověď s detailem vozidla, tak seznam vozidel. Při úpravě vynechání uloženou hodnotu zachová a 0 ji smaže.

2026-08-17 — locked nyní hlásí zámky dokumentů

Opravená sémantika hodnoty existujícího pole odpovědi; bez změny struktury.

  • locked v odpovědích na detail a seznam cestovních příkazů dříve hlásilo pouze starší zámek z importu před rokem 2023 a zůstávalo false u dokumentů zamčených v aplikaci, včetně automatického zámku uplatněného při výplatě. Nyní nese stejný odvozený stav zámku, jaký už hlásí webhook entry.updated v isLocked: true vždy, když je dokument uzavřen pro zápis. Chápejte to jako “tento záznam nelze upravit”, ne jako označení konkrétního původu zámku.

2026-07-13 — place id, ruční kurzy, přepsání stravného, směr kurzu

Aditivní, zpětně kompatibilní pole kontraktu a nový diskriminátor kurzu.

  • Place id na cestovních příkazech. Požadavky na vytvoření a aktualizaci přijímají departureLocationPlaceId a destinationPlaceId (Google Places place_id) a odpověď cestovního příkazu je vrací. Pošlete uložené hodnoty zpět při aktualizaci s úplnou náhradou, abyste zachovali identitu místa při úpravě textu cíle.
  • Cílová země na cestovních příkazech. Požadavky přijímají nepovinný destinationCountryCode (ISO 3166-1 alpha-2). Když je zadán, uloží se přímo a serverová záloha geocoding se přeskočí.
  • Ruční kurzy. Požadavky na výdaje a stravné přijímají nepovinný manualExchangeRate a požadavky cestovního příkazu manualAdvanceExchangeRate pro zálohu. Každý se respektuje pouze tehdy, když poskytovatel kurzu nezveřejní kurz pro referenční datum; odeslání, když existuje oficiální kurz, se odmítne s EXCHANGE_RATE_UNAVAILABLE.
  • Přepsání stravného. Požadavek na stravné přijímá overrideAmount a overrideReason a čtecí modely stravného je vracejí. Pro zachování existujícího přepsání při aktualizaci s úplnou náhradou pošlete hodnoty zpět; jejich vynechání vymaže přepsání a vrátí se k zákonné výplatě.
  • Směr kurzu. GET /api/v1/reference/exchange-rates nyní nese diskriminátor direction: ForeignPerBase (HNB / ECB) znamená kurz dělit pro převod na základní měnu, BasePerForeign (CNB) znamená násobit.

2026-07-08 — datum zálohy, poskytovatel kurzu pro CZ/SK

Dvě aditivní, zpětně kompatibilní změny.

  • Datum zálohy na cestovních příkazech. Požadavky na vytvoření a aktualizaci nyní přijímají nepovinný advancePaymentDate (yyyy-MM-dd) a odpověď cestovního příkazu jej vrací. Pokud je při vytvoření vynechán, server použije datum záznamu. Určuje datum kurzu pro zálohu a u českých tenantů referenční datum kurzu pro stravné.
  • Poskytovatel kurzu pro CZ/SK. GET /api/v1/reference/exchange-rates nyní dokumentuje úplnou sadu poskytovatelů: HNB pro HR, ECB pro SI a SK, CNB pro CZ. Pole source může být "CNB" a baseCurrency je nativní měna poskytovatele (EUR pro HNB/ECB, CZK pro CNB). Chování se nemění; dokumentace nyní odpovídá běhu.

2026-06-11 — počty jednotlivých jídel, původ FX, kód nedostupného směnného kurzu

Tři doplňkové změny rozhraní. Všechny jsou zpětně kompatibilní: stávající payloady fungují beze změny a nová pole v odpovědích jsou pouze doplňky, které můžete ignorovat, dokud je nebudete potřebovat.

  • Počty jednotlivých jídel při vytváření/aktualizaci diet. Požadavky na diety nyní přijímají breakfastsProvided, lunchesProvided a dinnersProvided (celočíselné počty jednotlivých jídel) plus volitelné denní mealsProvidedAllocation. Představují kanonický model pro zápis: server z těchto počtů přepočítává srážky. Stávající agregát v1 mealsProvided je stále přijímán; pokud pole pro jednotlivá jídla chybí, server mapuje agregát jako dříve, takže starší klienti nejsou ovlivněni. Odpovědi nadále vracejí odvozené mealsProvided (oběd + večeře, formát podle HR Pravilnik) vedle počtů jednotlivých jídel, takže cesty pro čtení zůstávají beze změny.
  • Původ FX v odpovědích. Odpovědi pro výdaje a diety získávají exchangeRateSource a odpověď pro cestovní záznam získává advancePaymentExchangeRateSource, které zaznamenávají, odkud pochází použitý kurz: kód poskytovatele ("HNB", "ECB") pro oficiální kurz, "MANUAL" pro kurz zadaný uživatelem, nebo null pro řádek ve stejné měně (bez převodu) či starší řádek uložený před sledováním původu. Pouze pro čtení; žádná změna v požadavku.
  • Nový chybový kód EXCHANGE_RATE_UNAVAILABLE (HTTP 400). Spustí se, když poskytovatel FX pro daného tenanta nezveřejní žádný kurz pro danou měnu v požadovaném datu a neexistuje žádný historický kurz, na který by se dalo přejít. Jedná se o selhání z rodiny validací se standardním tělem errors klíčovaným podle polí, takže můžete specificky rozlišit případ nedostupného FX a vyzvat k ručnímu zadání kurzu. Přidáno do katalogu chyb.

2026-05-23 — časy itineráře diet ukládány jako skutečné UTC (oprava)

Časy diet ukládané přes POST /api/v1/travel-entries/{id}/per-diems/from-itinerary se nyní ukládají jako skutečné UTC okamžiky. Dříve byl odjezd/příjezd každého úseku zapsán pomocí hodnoty místního času (wall-clock) označené jako UTC bez posunu (místní úsek v 08:00 byl uložen jako 08:00Z místo 07:00Z/06:00Z), takže řádky vygenerované z itineráře se neshodovaly s ručně přidanými řádky o 1–2 hodiny a zobrazovaly se opožděně. Schémata požadavku a odpovědi se nemění, ale hodnoty departureTime/arrivalTime, které tento endpoint vrací (a které vrací i pozdější čtení stejných řádků), nyní odrážejí opravený UTC okamžik. Náhled bezstavové kalkulačky stále vrací místní časy. Částky diet nejsou ovlivněny.

2026-05-23 — kalkulačka diet + uložení celé cesty

Rozhraní pro výpočet diet je sjednoceno a získává paritu ukládání celé cesty s webovou aplikací locco.

  • Nový POST /api/v1/utilities/per-diems/calculate — bezstavová kalkulačka. Odešlete itinerář (jeden úsek = itinerář se 2 zastávkami) a získáte zpět vypočítané řádky s aplikovaným přerozdělením na úrovni itineráře. Žádný kontext záznamu, nic se neukládá.
  • Nový POST /api/v1/travel-entries/{id}/per-diems/from-itinerary — přebudování diet cestovního záznamu z itineráře v jednom volání. Server znovu spustí svůj vlastní engine nad zastávkami (odeslaným částkám se nikdy nedůvěřuje), aplikuje jídla pro jednotlivé úseky klíčovaná podle (countryCode, departureTime) (dvojice, které vrací kalkulačka), a poté atomicky nahradí diety záznamu. Tím se reprodukuje přerozdělení na úrovni itineráře a upgrady vnitrostátních jednotek, což odesílání řádků po jednom nedokáže.
  • Odstraněno POST /api/v1/travel-entries/{id}/per-diems/compute a POST /api/v1/per-diems/calculate-simple. Oba jsou nahrazeny pomocí utilities/per-diems/calculate — jeden úsek je prostě itinerář se 2 zastávkami. Převeďte integrace na novou kalkulačku.

2026-05-22 — podpora slovinského trhu

Počáteční podpora pro slovinské tenanty. Aktualizujte svého klienta z obnoveného OpenAPI snapshotu na /api-reference/:

  • Slovinské obce — nový GET /api/v1/reference/slovenian-municipalities vrací seznam obcí SURS pro rozbalovací nabídky míst ve slovinských cestovních formulářích. Volatelné z jakéhokoli tenanta.
  • Daňová rezidence zaměstnance — záznamy zaměstnanců získávají pole residency (Resident / NonResident) pro vykazování slovinských diet a daní ze mzdy. Výchozí hodnota je Resident.

2026-04-28 — spuštění v1.0

První stabilní vydání locco partner API. Každé rozhraní je propojeno, otypováno a pokryto OpenAPI snapshotem na /api-reference/:

  • Cestovní záznamy — plný CRUD plus přechody workflow (odeslat, schválit, zamítnout, zrušit, vyžádat změny), s atomickým vytvářením, které v jednom volání přijímá vnořené výdaje, diety, alokace na nákladová střediska a přílohy.
  • Přílohy — přímé nahrávání k cestovnímu záznamu přes POST /api/v1/travel-entries/{id}/attachments. Multipart, až 5 souborů na požadavek.
  • Webhooks — registrace odběru s jednorázovým zobrazením signing-secret, historie doručování pro každý odběr a endpoint pro opakování neúspěšných nebo vyčerpaných doručení.
  • Výplaty — výpis záznamů připravených k výplatě, vytváření dávek, výpis historie, smazání dávky.
  • Zaměstnanci, Oddělení, Vozidla, Nákladová střediska — CRUD + výpis, s hodnotami vlastních polí u zaměstnanců.
  • Reference — chorvatské obce, směnné kurzy HNB, tabulka sazeb diet, seznamy povolených zemí a povolených měn společnosti.
  • Společnost — čtení profilu.

Hodnoty výčtů pro Status, TravelType, PayoutMethod a další jsou zdokumentovány v OpenAPI schématu jako seznamy povolených hodnot enum: [...], takže generovaní klienti se vážou na kanonické řetězce ("PendingApproval", "BankTransfer" atd.) spíše než na neprůhledné hodnoty.