Integrace do sjednavače
Dokument pro vývojáře sjednavače. Popisuje, co je hotové, co máte udělat a co udělat nesmíte.
K napojení vám stačí tahle stránka a API klíč. Zdrojový kód mít nemusíte — je užitečný jen tehdy, když chcete převzít hotovou React komponentu místo psaní vlastního UI (sekce 3).
| API | https://adresy.evidentum.cz |
| tahle příručka | https://adresy.evidentum.cz/ |
| interaktivní popis endpointů | https://adresy.evidentum.cz/docs |
| stav služby | https://adresy.evidentum.cz/api/health |
Na /docs je Swagger — dá se z něj volat rovnou v prohlížeči (vložte klíč
přes tlačítko Authorize) a je vždy generovaný z běžícího kódu.
1. K čemu to je
Pojišťovna vyžaduje v payloadu kód adresního místa RÚIAN. Tahle služba ho dodá: uživatel vybere adresu z našeptávače, vy dostanete kód.
uživatel píše ──> našeptávač ──> vybere adresu ──> resolve ──> kód RÚIAN ──> payload
Nemusíte řešit RÚIAN, ČÚZK, ani normalizaci adres. Voláte jedno API.
1b. Přístup — API klíč
Produkční služba běží na https://adresy.evidentum.cz.
Každý partner (každá pronajatá instance sjednavače) má vlastní API klíč.
Posílá se v hlavičce u každého volání kromě /api/health a /api/stats:
X-Api-Key: ruian_xxxxxxxxxxxxxxxxxxxxxxxx
Ke klíči je vedený seznam povolených originů. Volání z jiného originu skončí
403, chybějící nebo neplatný klíč 401.
Co klíč je a co není. Cestuje v prohlížeči, takže ho jde najít ve zdroji stránky — není to tajemství a nespoléhejte na něj jako na ochranu. Slouží k tomu, aby šla spotřeba kreditů přiřadit partnerovi, aby šel partner odpojit bez dopadu na ostatní a aby měl rate limit co počítat.
Nový partner nebo nová doména = jeden řádek v registru na serveru. Žádný redeploy, žádný restart — projeví se to samo.
2. Co dostanete
| API | čtyři endpointy (adresy + parcely), běží na naší straně |
| React komponenta | AddressAutocomplete a ParcelPicker — hotová pole včetně dropdownu, výběru kandidátů a chybových stavů |
Zapojit to jde dvěma způsoby:
- Volat API sami (sekce 4) — funguje z čehokoli, žádná závislost.
- Převzít naši komponentu (sekce 3) — ušetří práci, ale je pro React a musíme vám na ni dát přístup do repozitáře. Řekněte si o něj.
3. Varianta A — React komponenta
Hotové pole, které si řeší dropdown, ovládání klávesnicí, výběr u
nejednoznačné adresy i chybové stavy. Soubory (AddressAutocomplete.tsx,
types.ts, styles.css) jsou v našem repozitáři — pokud tuhle variantu
chcete, řekněte si o přístup. Bez něj použijte variantu B, API je stejné.
import { AddressAutocomplete } from "./AddressAutocomplete";
const [ruian, setRuian] = useState<number | null>(null);
<AddressAutocomplete
apiBase="https://adresy.evidentum.cz"
apiKey="ruian_vas_klic"
onResolved={(a) => setRuian(a.ruianAddressPointCode)}
onCleared={() => setRuian(null)}
/>
<button disabled={!ruian} onClick={odeslat}>Odeslat na pojišťovnu</button>
Props
| prop | povinný | popis |
|---|---|---|
apiBase |
ano | https://adresy.evidentum.cz |
apiKey |
ano | partnerský klíč, viz sekce 1b |
onResolved |
ano | adresa je potvrzená a má kód RÚIAN |
onCleared |
ano | adresa už neplatí — zahoďte uložený kód |
houseNumberType |
ne | popisne / evidencni — odstraní nejednoznačnost, viz níže |
label |
ne | popisek pole, výchozí „Adresa" |
placeholder |
ne | výchozí „Začněte psát ulici a číslo…" |
debounceMs |
ne | prodleva před dotazem, výchozí 300 |
minChars |
ne | od kolika znaků se našeptává, výchozí 3 |
onResolved vám předá celý objekt adresy — strukturované části i kód:
{
"street": "Krakovská",
"houseNumber": 1363,
"orientationNumber": 12,
"orientationLetter": null,
"cityPart": "Nové Město",
"city": "Praha",
"postalCode": "11000",
"countryCode": "CZ",
"displayAddress": "Krakovská 1363/12, Praha 1 - Nové Město, 110 00",
"ruianAddressPointCode": 21711470,
"normalizedAddress": "Krakovská 1363/12, Nové Město, 11000 Praha 1",
"codes": {
"obecKod": 554782, "obecNazev": "Praha",
"castObceKod": 490148, "castObceNazev": "Nové Město",
"momcKod": 500054, "momcNazev": "Praha 1",
"stavebniObjektKod": 21658544, "parcelaId": 2071976101
},
"sourceAutocomplete": "mapy_com",
"sourceResolver": "cuzk_ruian",
"resolvedAt": "2026-08-03T18:42:11+00:00"
}
Komponenta si sama řeší dropdown, klávesnici, loading, výběr kandidátů u nejednoznačné adresy i chybové hlášky. Vy řešíte jen kód a blokaci odeslání.
Parcela — ParcelPicker
Pro nemovitost bez čísla popisného. Pole kopírují formulář sjednavače: katastrální území (našeptávané), parcelní číslo, typ parcely.
import { ParcelPicker } from "./ParcelPicker";
<ParcelPicker
apiBase="https://adresy.evidentum.cz"
onResolved={(p) => setParcelId(p.ruianParcelId)}
onCleared={() => setParcelId(null)}
/>
Stejný kontrakt jako u adresy — onCleared je stejně povinný a ze stejného
důvodu. Přepínání mezi režimem „číslo popisné" a „bez čísla" musí zahodit
předchozí výsledek; v demu (App.tsx) je to vidět ve funkci switchMode.
4. Varianta B — vlastní UI
GET /api/address/autocomplete?query=<text>&limit=<n>
Volejte při psaní, s debounce (viz sekce 7 — kredity).
{
"suggestions": [
{
"displayAddress": "Sokolovská 694/100a, Karlín, 18600 Praha 8",
"street": "Sokolovská",
"houseNumber": 694,
"orientationNumber": 100,
"orientationLetter": "a",
"cityPart": "Karlín",
"city": "Praha 8",
"postalCode": "18600",
"countryCode": "CZ",
"sourceRef": "cuzk:1153888"
}
],
"sourceAutocomplete": "mapy_com"
}
Endpoint nikdy nevrací chybu — když je zdroj nedostupný, přijde prázdný seznam. Našeptávač, který hodí chybu, by zablokoval psaní.
sourceRef nepřekládejte ani neupravujte, jen ho přiložte k resolve.
POST /api/address/resolve-ruian
Volejte až po výběru konkrétní položky, ne při psaní. Jako tělo pošlete vybraný návrh beze změny.
{
"resolveStatus": "success",
"ruianAddressPointCode": 78506778,
"normalizedAddress": "Sokolovská 694/100a, Karlín, 18600 Praha 8",
"latitude": 50.0784286,
"longitude": 14.4282364,
"codes": {
"obecKod": 554782, "obecNazev": "Praha",
"castObceKod": 490148, "castObceNazev": "Nové Město",
"momcKod": 500054, "momcNazev": "Praha 1",
"stavebniObjektKod": 21658544,
"parcelaId": 2071976101
},
"candidates": [],
"sourceResolver": "cuzk_ruian",
"resolvedAt": "2026-08-03T18:42:11+00:00",
"fromCache": false
}
Souřadnice
latitude a longitude jsou ve WGS84 (běžné GPS, stejné jako Google Maps)
a patří samotnému adresnímu bodu — ne středu ulice ani obce.
RÚIAN je vede v S-JTSK; převod dělá ČÚZK na své straně, takže nic nepřepočítáváte ani vy, ani my.
Územní kódy (codes)
| pole | co to je |
|---|---|
obecKod / obecNazev |
obec |
castObceKod / castObceNazev |
část obce |
momcKod / momcNazev |
městský obvod / městská část |
stavebniObjektKod |
stavební objekt, na kterém adresní místo leží |
parcelaId |
parcela, na které stavební objekt stojí |
momcKod je null mimo Prahu a statutární města — městské části jinde
neexistují. Nevalidujte ho jako povinný.
Blok codes je vyplněný jen u success. U ambiguous ho kandidáti
nenesou — viz níže.
Doresolvování podle kódu
Když uživatel vybere z candidates, nemáte územní kódy. Doptejte se přes
sourceRef:
POST /api/address/resolve-ruian
{ "sourceRef": "ruian:78506778" }
Vrátí totéž co success včetně codes. Naše komponenta to dělá sama.
Použijte to i pro přeověření adresy uložené v DB — stačí vám kód.
Číslo popisné vs. evidenční — řeší se v nabídce
Našeptávač obě varianty rozlišuje už jako dva samostatné řádky:
Labuť 3, Staré Sedliště - Labuť, 348 01 houseNumberType: "popisne"
Labuť ev. č. 3, Staré Sedliště - Labuť, 348 01 houseNumberType: "evidencni"
Každý návrh nese houseNumberType. Když ho přepošlete beze změny do
resolve (což je doporučený postup — poslat celý objekt návrhu), vrátí se
rovnou success se správným kódem:
| vybraný řádek | výsledek |
|---|---|
Labuť 3 |
success, kód 15636844 |
Labuť ev. č. 3 |
success, kód 15637344 |
Uživatel vybírá jednou. Žádný druhý select, žádné ambiguous.
Pokud si stavíte tělo požadavku sami, nezapomeňte houseNumberType přiložit —
bez něj se obě varianty vyřeší stejně a vrátí se ambiguous s kandidáty,
tedy druhý výběr navíc.
Typ čísla ve vašem formuláři
Pokud máte typ čísla jako samostatné pole ve formuláři (popisné / evidenční / bez čísla), můžete ho poslat taky — přebije to, co přišlo z našeptávače:
| Typ čísla | co poslat |
|---|---|
| popisné | houseNumberType: "popisne" |
| evidenční | houseNumberType: "evidencni" |
| bez čísla | režim parcely, viz sekce 4b |
Když pole „Typ čísla" nemáte, nic se neděje — hodnota z našeptávače stačí.
Čtyři stavy, které musíte obsloužit
resolveStatus |
co to znamená | co udělat |
|---|---|---|
success |
kód je v ruianAddressPointCode |
uložit, odemknout odeslání |
ambiguous |
adresa sedí na víc míst, seznam je v candidates |
nechat uživatele vybrat, pak použít kód vybraného kandidáta |
not-found |
v RÚIAN taková adresa není | nechat upravit zadání a vybrat znovu |
error |
služba je dočasně nedostupná, důvod v message |
zobrazit hlášku, neodesílat |
U ambiguous vypadá candidates takhle. Kód adresního místa v nich je,
ale územní kódy ne — po výběru se doptejte přes sourceRef, viz výše:
"candidates": [
{ "ruianAddressPointCode": 15636844, "normalizedAddress": "Labuť 3, 34801 Staré Sedliště" },
{ "ruianAddressPointCode": 15637344, "normalizedAddress": "Labuť č.ev. 3, 34801 Staré Sedliště" }
]
Provozní endpointy
GET /api/health — stav a jestli je nakonfigurovaný klíč k Mapy.com.
GET /api/stats — počty podle statusu, podíl z cache, průměrná doba.
4b. Parcely
Parcela není adresa a nehledá se jako adresa. Nemá ulici ani číslo popisné. Identifikuje ji katastrální území plus parcelní číslo — a číslo samo o sobě nestačí.
Proč nestačí číslo
V katastrálním území Přimda existuje parcelní číslo 233 dvakrát:
| id RÚIAN | výměra | |
|---|---|---|
St. 233 — stavební parcela |
675238410 | 180 m² |
233 — pozemková parcela |
675655410 | 324 m² |
Dva různé pozemky. A není to výjimka: v tom jediném katastrálním území je do čísla 300 celkem 79 stavebních a 172 pozemkových parcel, řada se překrývá.
Proto je numberingType součást identity parcely, ne filtr. Formulář,
který ho neumožní zadat, parcelu ve většině republiky neurčí. V uživatelském
rozhraní je to prostě přepínač „St." před polem s číslem.
Praha je výjimka — čísluje v jedné řadě a stavební parcely tam nejsou vůbec.
GET /api/parcel/cadastral-areas?query=<text>
Našeptávání katastrálních území. Dotazuje jen ČÚZK, takže nestojí kredity.
[
{ "kod": 727181, "nazev": "Nové Město", "obecKod": 554782, "obecNazev": "Praha" },
{ "kod": 706418, "nazev": "Nové Město na Moravě", "obecKod": 595462, "obecNazev": "Nové Město na Moravě" }
]
Katastrálních území stejného jména je víc — proto se v nabídce zobrazuje obec.
POST /api/parcel/resolve-ruian
{
"cadastralAreaCode": 736112,
"parcelNumber": "1375/42",
"numberingType": "building"
}
| pole | popis |
|---|---|
cadastralAreaCode |
kód KÚ z našeptávače. Preferujte ho. |
cadastralAreaName + municipality |
alternativa, když kód nemáte |
parcelNumber |
celé číslo tak, jak ho uživatel napsal — 1375/42, 233, St. 233 |
numberingType |
building (St.) nebo land. Výchozí land. |
stemNumber + subdivisionNumber |
alternativa k parcelNumber, když už máte číslo rozložené |
parcelNumber je jedno textové pole, protože přesně tak to má formulář
sjednavače. Rozložení na kmenové číslo a podlomení řešíme my. Prefix St.
v textu přebije hodnotu v numberingType — kdo napíše St. 233, chce
stavební parcelu, ať je v selectu cokoli.
{
"resolveStatus": "success",
"ruianParcelId": 675238410,
"parcelNumber": "233",
"numberingType": "building",
"cadastralAreaCode": 736112,
"cadastralAreaName": "Přimda",
"obecKod": 561151,
"obecNazev": "Přimda",
"areaSquareMetres": 180.0,
"latitude": 49.6759536,
"longitude": 12.6732778,
"postalCode": "34806",
"postalCodeSource": "odvozeno z 41 z 41 adresnich mist do 150 m"
}
PSČ u parcely je odvozené, ne z registru
Pojišťovny PSČ u pozemků vyžadují, ale RÚIAN vazbu parcela → PSČ nemá. PSČ je vlastnost adresního místa a pozemek žádné mít nemusí — u pole nebo lesa prostě neexistuje.
Bereme proto PSČ, které převládá mezi adresními místy nejblíž parcele. Hledá se v okruhu 150 m, a když tam není nic, postupně 500 m a 2 km.
postalCodeSource popisuje, jak hodnota vznikla:
"odvozeno z 13 z 13 adresnich mist do 150 m" ← jednomyslné
"odvozeno z 46 z 50 adresnich mist do 150 m" ← převažující
Ukládejte postalCodeSource spolu s PSČ. Odvozený údaj musí jít odlišit od
údaje z registru — kód parcely a souřadnice jsou z RÚIAN, PSČ ne. U reklamace
je to rozdíl, na kterém záleží.
Když se PSČ odvodit nepodaří, přijde null — parcela se tím nezneplatní,
identifikátor je ruianParcelId.
Souřadnice parcely
latitude / longitude ve WGS84 ukazují na definiční bod parcely
(vnitřní bod plochy), ne na její roh ani na budovu.
Stavy jsou stejné čtyři jako u adres. ambiguous tu znamená i nejednoznačné
katastrální území — pak je vyplněné message a uživatel musí upřesnit obec.
ruianParcelId je pro parcelu totéž, co kód adresního místa pro adresu.
subdivisionNumber: nullznamená parcelu bez podlomení. Číslo233a233/7jsou různé pozemky, resolver je nezaměňuje.
5. Pravidla, která musíte dodržet
Bez kódu se neodesílá. Formulář nesmí jít odeslat, dokud nemáte
ruianAddressPointCode. Platí i pro ambiguous — kandidáti nejsou výsledek,
dokud uživatel nevybere.
Při změně pole zahoďte kód. Když uživatel po potvrzení adresu upraví, starý
kód musí okamžitě zmizet. Tohle dělá onCleared. Když to neuděláte, odejde na
pojišťovnu kód patřící k jiné adrese — a nikde to nebude vidět, protože adresa
i kód budou samy o sobě vypadat platně. Nejhorší možná chyba v celé
integraci.
Kód nikdy neskládejte ani neodvozujte na frontendu. Vždy jen ten, co přišel z resolve. Neukládejte si mapování „adresa → kód" u sebe.
Ukládejte i normalizovanou adresu. normalizedAddress je tvar z registru.
Když bude reklamace, dohledá se podle něj, co přesně uživatel vybral.
Resolve nevolejte při psaní. Jen po výběru položky.
6. Co je čí
| kdo | |
|---|---|
| našeptávání, překlad adresy na kód RÚIAN, fallback stavy | my |
| uložení adresy a kódu do vaší DB | vy |
| blokace odeslání formuláře | vy |
| složení payloadu pro webovou službu pojišťovny | vy |
| validace ostatních polí formuláře | vy |
7. Kredity a limity
Našeptávač jede přes Mapy.com. Basic tarif = 250 000 kreditů měsíčně zdarma, jeden dotaz stojí 4 kredity → 62 500 dotazů měsíčně.
Při debounce 300 ms vychází jedna vyplněná adresa zhruba na 4 dotazy, tedy ~15 000 vyplnění měsíčně. Resolve proti ČÚZK je zdarma a bez limitu, platí se jen za psaní.
Proto: nesnižujte debounceMs a nevolajte našeptávač od prvního znaku.
Každý ušetřený keystroke je ušetřený kredit.
8. Na co si dát pozor
Číslo popisné vs. evidenční. „Labuť 3" a „Labuť č.ev. 3" jsou dvě různé
adresy se dvěma různými kódy. Proto u nich přijde ambiguous. Nevybírejte
první — nechte vybrat uživatele.
Adresy bez ulice. Na vesnicích ulice neexistuje a street je null.
Nevalidujte ho jako povinné pole; povinný je houseNumber, city,
postalCode a kód RÚIAN.
Městská část jen ve velkých městech. momcKod je null všude mimo Prahu
a statutární města.
Stavební vs. pozemková parcela. Bez numberingType parcelu neurčíte —
viz sekce 4b.
Psaní bez diakritiky a malými písmeny funguje. ČÚZK porovnává názvy
case-sensitive a bez tolerance diakritiky, takže slan ani nove m by samy
o sobě nenašly nic — řešíme to na naší straně. Vy nemusíte nic normalizovat.
Diakritika v payloadu. Adresy chodí v UTF-8 s diakritikou. Ověřte si, že ji vaše serializace do payloadu pro pojišťovnu přenese beze změny.
Latence. Resolve trvá 200–900 ms podle toho, jestli je adresa v cache. Počítejte s tím v UI, komponenta na to má spinner.
9. Jak si to vyzkoušet hned
Nemusíte nic instalovat. Nejrychlejší je Swagger na https://adresy.evidentum.cz/docs — vložte klíč přes tlačítko Authorize a volejte přímo z prohlížeče.
Nebo z příkazové řádky:
curl -H "X-Api-Key: VAS_KLIC" "https://adresy.evidentum.cz/api/address/autocomplete?query=Sokolovsk%C3%A1%20694"
curl -X POST -H "X-Api-Key: VAS_KLIC" -H "Content-Type: application/json" -d '{"street":"Krakovská","houseNumber":1363,"orientationNumber":12,"city":"Praha","postalCode":"110 00"}' https://adresy.evidentum.cz/api/address/resolve-ruian
Vstupy, na kterých se dá chování osahat:
| vstup | co se stane |
|---|---|
Krakovská 1363/12 |
success, kód 21711470 |
Sokolovská 694/100a |
success — pozor na písmeno, 694/100 je jiná adresa |
Labuť 3 |
ambiguous — č.p. vs č.ev., viz houseNumberType |
KÚ Přimda, 233, stavební vs pozemková |
dvě různé parcely se stejným číslem |
Stav služby kdykoli na https://adresy.evidentum.cz/api/health.
Hlídejte status — hodnota jiná než "ok" znamená, že našeptávač jede
z náhradního zdroje a je horší, i když odpovídá.
10. Stav služby
Služba je nasazená na produkci, běží na HTTPS a našeptávání zajišťuje Mapy.com. Po každém nasazení projíždí kontrola 13 bodů proti živým datům: adresy, územní kódy, obě parcely s kolidujícím číslem a ověření, že API bez klíče odmítne.
Kdyby něco nefungovalo, pošlete nám prosím:
- co jste poslali (celé tělo požadavku)
- co se vrátilo (
resolveStatusamessage) X-Api-Key, který jste použili — jen jeho prvních 12 znaků
Nejčastější dva stavy: 401 znamená chybějící nebo neplatný klíč, 403
znamená, že doména, ze které voláte, není u klíče povolená — v tom případě
nám tu doménu napište a přidáme ji.