Data Hub pro agentury a vývojáře
Co Data Hub obsahuje, jak číst identifikátory, stavy, čas, cache, verze a licence – s příklady volání.
Co je Data Hub
Data Hub je ověřený zdroj pravdy o lyžařském resortu SkiResort ČERNÁ HORA – PEC: areály, lanovky a vleky, sjezdovky, běžecké tratě, služby a místa, skibusy, produkty (skipasy), věkové kategorie, ceníky a glosář pojmů. Slouží webu a e-shopu (agenturám), vlastním kanálům resortu (TV panorama, displeje, aplikace) i AI asistentům.
Každý údaj je claim se zdrojem (URL, doslovný úryvek, čas stažení, důvěra). Pravidla priority zdrojů vyberou publikovanou hodnotu a rozpory se nerozhodují potichu (_conflicts, přehled kvality). Publikuje se neměnný release – API, fact pages, llms-full.txt i MCP čtou tentýž release, takže říkají totéž.
| Kanál | Adresa | Pro koho |
|---|---|---|
| API v2 (JSON) | https://data.skiresort.cz/api/v2 | web, e-shop, aplikace, integrace |
| OpenAPI 3.1 | https://data.skiresort.cz/openapi.json · YAML | generování klientů, function calling |
| Fact pages (HTML/Markdown) | https://data.skiresort.cz/ | vyhledávače, AI vyhledávače, lidé |
| llms.txt / llms-full.txt | https://data.skiresort.cz/llms.txt | coding a prohlížečoví agenti |
| MCP (read-only) | https://data.skiresort.cz/mcp | AI asistenti (Claude, ChatGPT…) |
Rychlý start
Čtení je bez autentizace, CORS je *, odpovědi jsou cacheovatelné. První volání:
curl -s 'https://data.skiresort.cz/api/v2/lifts?area=cerna-hora&lang=cs'
curl -s 'https://data.skiresort.cz/api/v2/status?area=pec'
curl -s -D - -o /dev/null -H 'If-None-Match: "<ETag z předchozí odpovědi>"' 'https://data.skiresort.cz/api/v2/lifts' # → 304
curl -s -H 'Accept: application/ld+json' 'https://data.skiresort.cz/api/v2/lifts/lift:cerna-hora:a1' # JSON-LD (schema.org)
curl -s 'https://data.skiresort.cz/lifts/cerna-hora/a1.md' # Markdown fact page
// Prohlížeč nebo Node.js – podmíněný požadavek s ETag
let etag;
async function refreshLifts() {
const r = await fetch("https://data.skiresort.cz/api/v2/lifts?area=cerna-hora", { headers: etag ? { "If-None-Match": etag } : {} });
if (r.status === 304) return null; // beze změny
etag = r.headers.get("ETag");
const { data, meta } = await r.json();
return { lifts: data, release: meta.release, attribution: meta.attribution };
}
import json, urllib.request
req = urllib.request.Request("https://data.skiresort.cz/api/v2/age-categories", headers={"Accept": "application/json", "User-Agent": "agentura-xy/1.0 (+kontakt)"})
print(json.load(urllib.request.urlopen(req))["data"])Co je co: typy entit a kolekce
Data mají vrstvy: M master (místa, zařízení), O provoz (živé stavy, rozvrhy, pozorování), C obchod (produkty, věk, ceny), K obsah (glosář, FAQ, texty), G governance (zdroje, kvalita). Každý typ entity má jednu kolekci /api/v2/{kolekce} a detail /api/v2/{kolekce}/{id}; atributy popisuje datový slovník.
| Kolekce | Typ | Vrstva | Počet v releasu |
|---|---|---|---|
areas | Areál | M | 6 |
lifts | Lanovka / vlek | M | 63 |
slopes | Sjezdovka | M | 70 |
snowparks | Snowpark | M | 2 |
crosscountry-trails | Běžecká trať | M | 15 |
skitour-routes | Skialpová / turistická trasa | M | 0 |
sled-runs | Sáňkařská dráha | M | 1 |
parkings | Parkoviště | M | 12 |
pois | Místo / služba na místě | M | 121 |
services | Služba | M | 23 |
attractions | Atrakce | M | 7 |
summer-attractions | Letní atrakce | M | 8 |
skibus-lines | Linka skibusu | M | 17 |
routes | Trasa (léto) | M | 46 |
bus-stops | Zastávka (skibus / výletní bus) | M | 5 |
webcams | Webkamera | M | 15 |
weather-stations | Meteostanice | M | 0 |
organizations | Organizace | M | 16 |
contacts | Kontakt | K | 18 |
seasons | Sezóna | O | 3 |
season-periods | Cenové období sezóny | C | 8 |
products | Produkt | C | 79 |
offers | Nabídka / cena | C | 781 |
age-categories | Věková kategorie | C | 22 |
age-category-sets | Sada věkových kategorií | C | 0 |
price-lists | Ceník | C | 0 |
price-tiers | Cenová hladina | C | 4 |
sales-channels | Prodejní kanál | C | 4 |
discounts | Sleva / pravidlo | C | 9 |
programs | Program / aktivita | C | 8 |
glossary | Pojem glosáře | K | 69 |
faq | Častá otázka | K | 61 |
guides | Průvodce | K | 5 |
policies | Pravidlo / podmínka | K | 39 |
documents | Dokument | K | 8 |
news | Novinka | K | 8 |
events | Akce | K | 27 |
Souhrnné pohledy: /status (živý provoz), /weather (teploty z kamer), /prices (ceník sezóny), /age-categories (věkové sady s kontrolou pokrytí), /search?q=, /releases/latest, /quality.
Identifikátory
- Kanonické ID má tvar
{typ}:{areál}:{označení}(lift:cerna-hora:a1,slope:pec:7), u entit celého resortu{typ}:{označení}(product:flexiskipas,season:2026-27). Je neměnné a nikdy se nerecykluje; jako klíč používejte ID, ne název. - Areály:
area:cerna-hora,area:pec,area:velka-upa,area:cerny-dul,area:svobodaa partnerskáarea:mala-upa(membership: partner). - Staré klíče a cizí ID jsou aliasy:
/api/v2/entities/lift:chora:A1(klíč v1),lift-cerna-hora-a1(mapa webu),chora/loc_lifts/A1(Holidayinfo) →301na kanonické ID. Cizí identifikátory jsou vexternalIds(osm, wikidata, eshop…). - Přejmenování = nový alias; sloučení =
replacedBy+301; zrušení = tombstone +410. - URI identity pro propojená data:
https://data.skiresort.cz/id/{typ}/{…}(JSON-LD@id) – zatím jen stabilní identifikátory (nedereferencují se); pro data použijte fact page nebo API.
Stav ≠ schopnost ≠ rozvrh
- Stav (
operations.sessions[]):open | partial | hold | scheduled | closed | unknownpro relaciday,evening,nightnebosummer-day(provoz mimo zimní sezónu – pěší, kola), vždy sobservedAt(kdy zdroj stav zjistil) avalidUntil(do kdy platí bez nového potvrzení). - Po
validUntilbez potvrzení vrací APIstatus: unknown,stale: truealastKnown.unknownneznamená zavřeno. - Mimo zimní sezónu se stav lyžování nepublikuje: sjezdovky a tratě jsou
closedsreason: off-season, původní stav zdroje je vsourceStatus; souhrnná věta to říká výslovně. - Schopnost (
nightSkiingCapable,snowmakingCapable) je vlastnost sjezdovky (osvětlení, zasněžování), ne dnešní provoz. Dnešní večerní lyžování = relaceeveningve/status. - Rozvrh (
operatingHours,operatingScheduleRule, vzorpattern: sat-sun) popisuje plán, ne skutečnost. - Booleany jsou tří-stavové (
true | false | null);nullmá důvod vunknownReasons.
Čas, jazyk, formáty
- Časy RFC 3339 s offsetem Europe/Prague (
2026-10-17T09:32:38+02:00), dataYYYY-MM-DD;meta.timezone = "Europe/Prague". - Jazyk
?lang=cs|en|de|plneboAccept-Language; chybějící překlad spadne na češtinu (meta.notes,Content-Language). - Formáty: JSON (výchozí); detail entity také
Accept: application/ld+json(schema.org) aAccept: text/markdown; fact pages/lifts/cerna-hora/a1(HTML) a/lifts/cerna-hora/a1.md; nepodporovanýAccept→406. - Kolekce se stránkují:
limit(výchozí 100, max 500) acursorzlinks.next.
Cache, čerstvost a slušné chování
| Třída | Příklady | Cache-Control |
|---|---|---|
| živé | /status, /weather, /quality, /releases/latest | public, max-age=30, s-maxage=60, stale-while-revalidate=60, stale-if-error=3600 |
| master | entity, kolekce, /prices, fact pages, OpenAPI | public, max-age=60, s-maxage=300, stale-while-revalidate=600, stale-if-error=86400 |
| hledání | /search | public, max-age=60, stale-if-error=3600 |
- Posílejte
If-None-Matchs ETag (→304bez těla). ETag se mění s novým releasem i s vypršením živého stavu. /statuspollujte nejvýš 1× za 30 s, master data 1× za 5 min. UvádějteUser-Agents kontaktem.meta.stale: true= release nebo živé údaje jsou starší než cíl čerstvosti; zobrazte časobservedAt.
Verze a kompatibilita
- Major verze je v URL (
/api/v2),meta.schemaVersionje semver datového kontraktu (aktuálně2.1.0). - Klient musí ignorovat neznámá pole a tolerovat nové hodnoty enumů – registr roste aditivně (nový atribut = minor).
- Rušení pole nebo parametru:
deprecatedv OpenAPI + changelog, souběh ≥ 6 měsíců, hlavičkyDeprecation/Sunset. - API v1 (
/api/v1/*) zůstává beze změny chování do ukončení (plán: 30. 6. 2027), viz migrace v1 → v2.
Chyby
Chyby jsou application/problem+json (RFC 9457) s akční radou: invalid-parameter (400, errors[] s povolenými hodnotami), invalid-id (400), not-found (404, suggestions[]), method-not-allowed (405), not-acceptable (406, supported[]), gone / cursor-expired (410), uri-too-long (414), release-unavailable (503, Retry-After).
Licence a atribuce
Zobrazujte meta.attributions (atribuce Data Hubu a zdrojů použitých v odpovědi: sourceId, text, licence, url). Podrobnosti a stav licencí: Licence a atribuce.
Kontroly kvality dat
Kontroly běží při stavbě každého releasu (výsledek je součástí releasu) a v okamžiku požadavku (čerstvost živých dat). Přehled: /api/v2/quality (checks[]: id, severity, result, stage, action, gate, count, affected, detail, data). Kontrola s gate: true a výsledkem fail release nepublikuje – API dál vrací předchozí release a živé stavy po validUntil přejdou na unknown.
| ID | Kontrola | Závažnost | Kdy | Při selhání |
|---|---|---|---|---|
QC-PUB-03 | Zakázané vzory (přístupové kódy, známá tajemství, URL kamer, tokeny) | block | stavba releasu | release se nepublikuje (brána) |
QC-O-02 | Žádné „open“ lyžování mimo zimní sezónu | block | stavba releasu | release se nepublikuje (brána) |
QC-O-03 | Žádné „open“ mimo dnešní provozní dobu | block | stavba releasu | release se nepublikuje (brána) |
QC-O-04 | Žádný publikovaný stav zjištěný před dnešním provozním dnem (stav ze včerejška = unknown) | block | stavba releasu | release se nepublikuje (brána) |
QC-O-05 | Dnešní doba: oficiální rozvrh × Holidayinfo v rozporu (platí oficiální rozvrh) | warn | stavba releasu | publikuje se s označením |
QC-C-01 | Věkové kategorie pokrývají roky narození bez děr a překryvů | block | stavba releasu | release se nepublikuje (brána) |
QC-X-03 | Počet lanovek jádra = počet lanovek s kódem Holidayinfo; lanovka s kódem Holidayinfo není „planned“ | block | stavba releasu | release se nepublikuje (brána) |
QC-PUB-01 | Hodnoty releasu odpovídají schématu registru | quarantine | stavba releasu | hodnota se nepublikuje |
QC-RES-03 | Povinné atributy podle registru | warn | stavba releasu | publikuje se s označením |
QC-RES-01 | Konflikty zdrojů nad tolerancí (vysoká závažnost) | warn | stavba releasu | publikuje se s označením |
QC-X-01 | Souhrny km (sjezdovky, běžky) proti tvrzení oficiálního webu | warn | stavba releasu | jen hlášení |
QC-X-02 | Počty areálů, lanovek a sjezdovek proti tvrzení oficiálního webu | warn | stavba releasu | jen hlášení |
QC-REF-01 | Odkazy na neexistující entity | warn | stavba releasu | jen hlášení |
QC-O-01 | Živé stavy mají observedAt a validUntil | warn | stavba releasu | publikuje se s označením |
QC-PUB-02 | Počty entit podle typu proti předchozímu releasu (pokles > 10 %) | warn | stavba releasu | jen hlášení |
QC-PUB-05 | ID z předchozího releasu zůstávají (tombstone místo zmizení) | warn | stavba releasu | jen hlášení |
QC-PUB-04 | Velikost dokumentů releasu (≤ 1 MB na entitu) | warn | stavba releasu | jen hlášení |
QC-K-02 | Hygiena textů (neviditelné znaky, HTML, pokyny pro jazykové modely) | warn | stavba releasu | jen hlášení |
QC-K-03 | Český název není cizojazyčný (claims z /de/, /en/, /pl/ stránek nesmí být cs) | warn | stavba releasu | jen hlášení |
QC-RES-02 | Publikační minimum: vítěz s nízkou důvěrou ze zdroje s prioritou ≤ 30 | info | stavba releasu | jen hlášení |
QC-SLO-01 | Stáří releasu (SLO bety ≤ 30 min) | warn | požadavek | jen hlášení |
QC-PUB-06 | Publikované URL Data Hubu bez privátní IP a bez http:// (blokující, je-li nastaven PUBLIC_BASE_URL) | block | požadavek | publikuje se s označením |
QC-SLO-02 | Živé stavy potvrzené v době platnosti (žádné stale) | warn | požadavek | publikuje se s označením |
QC-SLO-03 | Stáří posledního potvrzení stavů zdrojem (v sezóně ≤ 30 min, jinak ≤ 45 min) | warn | požadavek | jen hlášení |
QC-SLO-04 | Teploty z kamer per areál (SLO ≤ 60 min, nepublikují se po 3 h) | warn | požadavek | jen hlášení |
Kontakt a nahlášení chyby v datech
Chybný údaj nahlaste s ID entity a URL fact page (každá stránka má sekci „Jak tato data vznikají“). Kontaktní adresa Data Hubu pro agentury se zřizuje; do té doby přes kontakt provozovatele na www.skiresort.cz.