Na čo je API
API má dva druhy tokenu. Každý vydáva niekto iný a každý smie niečo iné.
- Klientsky token vydáva klient vo svojom účte a koná len za neho: voľné termíny, založenie, zoznam, prečítanie, presun a zrušenie jeho vlastných rezervácií — podľa rovnakých pravidiel ako v aplikácii, vrátane lehoty na zrušenie, ktorú nastavuje firma. Je zadarmo a modul API firmy ho nevypína.
- Firemný token vydáva firma v administrácii a koná za firmu: zakladá klientov firmy, napríklad pri prevode z iného systému. K rezerváciám ani k voľným termínom prístup nemá — tie vždy patria konkrétnemu človeku.
Čo API zatiaľ nevie: vypísať služby, platby, webhooky, hromadné operácie a mazanie rezervácií (zrušená rezervácia v systéme zostáva).
Ako získať token
Firemný token
- Prihláste sa do administrácie ako správca podniku.
- V menu Klienti otvorte Firemní přístup přes API (firemný prístup cez API).
- Do poľa Popis napíšte, na čo bude token (napríklad „Prevod klientov z Excelu“), a kliknite na Vydat.
- Token sa ukáže len raz, hneď po vydaní. Skopírujte si ho: ukladáme len jeho odtlačok a znova ho zobraziť nejde.
V zozname pod formulárom potom vidíte popis, začiatok tokenu a kedy bol naposledy použitý. Tlačidlo Zneplatnit token okamžite zastaví; nový vydáte rovnako ako prvý.
Stránka je dostupná, kým má firma zapnutý modul API (v predvolenom stave zapnutý je). Vypnutý modul zastaví všetky firemné tokeny, klientske nie.
Otvoriť správu tokenov v administrácii
Klientsky token
Klient si token vydá sám: Účet → Prístup cez API → Vydať token. Platí to isté: zobrazí sa raz a zneplatniť ho ide kedykoľvek.
Autentifikácia
Každá požiadavka nesie token v hlavičke Authorization so slovom Bearer. Token začína rzv_live_.
Authorization: Bearer rzv_live_…
Volajte vždy cez https. Základná adresa rozhrania:
https://reservuj.cz/api/v1
Chýbajúci, neplatný alebo zneplatnený token vracia 401 unauthorized. Klientsky token prestane platiť aj vo chvíli, keď firma klientovi zablokuje účet.
Prvé volanie
Začnite koncovým bodom GET /me. Nič nemení, len povie, komu token patrí: typ, firmu, rozsahy a limity. Funguje s oboma druhmi tokenu.
curl -s "https://reservuj.cz/api/v1/me" \
-H "Authorization: Bearer $RESERVUJ_TOKEN"
const response = await fetch('https://reservuj.cz/api/v1/me', {
headers: { Authorization: `Bearer ${process.env.RESERVUJ_TOKEN}` },
});
const body = await response.json();
if (!response.ok) {
throw new Error(`${response.status} ${body.error.code}: ${body.error.message}`);
}
console.log(body.data.type, body.data.scopes);
Odpoveď pre firemný token:
{
"data": {
"type": "company",
"organization_id": 42,
"client_id": null,
"scopes": [
"clients"
],
"rate_limit": {
"limit_per_minute": 60,
"availability_cost": 5
}
}
}
Firemný token: založenie klienta
POST /clients s telom application/json. Povinný je e-mail a priezvisko, voliteľné meno, telefón a poznámka (e-mail, meno aj priezvisko najviac 50 znakov, telefón 20, poznámka 255).
curl -s -X POST "https://reservuj.cz/api/v1/clients" \
-H "Authorization: Bearer $RESERVUJ_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: import-2026-jana-novakova" \
-d '{"email":"jana.novakova@example.com","surname":"Nováková","name":"Jana","phone":"+420777123456"}'
import { randomUUID } from 'node:crypto';
const idempotencyKey = randomUUID();
const response = await fetch('https://reservuj.cz/api/v1/clients', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.RESERVUJ_TOKEN}`,
'Content-Type': 'application/json',
'Idempotency-Key': idempotencyKey,
},
body: JSON.stringify({ email: 'jana.novakova@example.com', surname: 'Nováková', name: 'Jana' }),
});
const body = await response.json();
console.log(response.status, body);
Odpoveď 201. Známy e-mail nezaloží druhého klienta, len doplní chýbajúce údaje; pole created povie, čo sa stalo.
{
"data": {
"email": "jana.novakova@example.com",
"created": true
}
}
Založený klient nedostane žiadny e-mail. Dajte svojim klientom vopred vedieť, že ich údaje prenášate do nového systému.
Klientsky token: voľné termíny a rezervácie
Voľné termíny hľadáte pre jednu službu, najviac 31 dní naraz. ID služby (service_id) je ID riadku cenníka: firma ho vidí v administrácii v Cenníku v stĺpci ID a klientovi ho odovzdá. Zoznam služieb API zatiaľ nevydáva.
curl -s "https://reservuj.cz/api/v1/availability?service_id=123&date_from=2026-11-16&date_to=2026-11-22" \
-H "Authorization: Bearer $RESERVUJ_TOKEN"
{
"data": [
{
"start": "2026-11-17T10:00:00+01:00",
"end": "2026-11-17T11:00:00+01:00",
"service_id": 123,
"provider_id": 7,
"branch_id": 3
}
]
}
Rezerváciu založíte na začiatok z odpovede. S provider_id a branch_id z voľného termínu vznikne presne u toho pracovníka a na tej pobočke; bez nich firma priradí kohokoľvek voľného.
curl -s -X POST "https://reservuj.cz/api/v1/reservations" \
-H "Authorization: Bearer $RESERVUJ_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 8d0c6a52-5d0e-4f4e-9a49-2f6b0c3e7a11" \
-d '{"service_id":123,"start":"2026-11-17T10:00:00+01:00","provider_id":7,"branch_id":3,"note":"Poprvé"}'
Časy sú vo formáte ISO 8601 s časovým posunom; čas s iným posunom sa prevedie na čas servera (Europe/Prague). Medzi dotazom na voľné termíny a založením môže termín zmiznúť — vtedy príde 409.
Stránkovanie
GET /reservations vracia vlastné rezervácie klienta zoradené podľa začiatku, po stránkach. Parameter limit je 1 až 200 (predvolené 50). Ak je v odpovedi next_cursor, pošlite ho v parametri cursor ďalšieho dotazu s rovnakým filtrom (from, to, status); null znamená poslednú stránku. Kurzor z iného filtra vráti 400 invalid_cursor.
let cursor = null;
do {
const url = new URL('https://reservuj.cz/api/v1/reservations');
url.searchParams.set('from', '2026-11-16T00:00:00Z');
url.searchParams.set('limit', '200');
if (cursor) {
url.searchParams.set('cursor', cursor);
}
const response = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.RESERVUJ_TOKEN}` },
});
const page = await response.json();
for (const reservation of page.data) {
console.log(reservation.id, reservation.status, reservation.start);
}
cursor = page.next_cursor;
} while (cursor);
Čítanie rezervácií vracia hlavičku ETag. Pošlite ju späť v If-None-Match a nezmenené dáta prídu ako 304 bez tela.
Chyby a kódy
Chyba má vždy rovnaký tvar. Na kód (error.code) sa dá spoľahnúť, text (error.message) je pre človeka a môže sa zmeniť. Kód, ktorý nepoznáte, posúďte podľa HTTP stavu.
{
"error": {
"code": "conflict",
"message": "Služba se platí zálohou online; objednejte ji v rezervačním portálu."
}
}
| Kód | HTTP | Kedy príde |
|---|---|---|
unauthorized |
401 | Chýba token, je neplatný alebo zneplatnený, nemá na túto operáciu rozsah, alebo firma vypla modul API (firemný token). |
bad_request |
400 | Chybný alebo chýbajúci parameter, zlý tvar Idempotency-Key. |
invalid_json |
400 | Telo zápisu chýba, nie je platný JSON alebo to nie je objekt. |
invalid_cursor |
400 | Kurzor je neplatný alebo patrí k inému filtru. |
idempotency_key_required |
400 | Presun rezervácie bez hlavičky Idempotency-Key. |
not_found |
404 | Záznam neexistuje alebo k nemu token nemá prístup; neznáma cesta. |
conflict |
409 | Termín je obsadený, na zrušenie alebo presun je neskoro, rezerváciu nejde presunúť, firma je pozastavená alebo zatiaľ neprijíma rezervácie, služba sa platí zálohou online. |
idempotency_in_progress |
409 | Požiadavka s rovnakým Idempotency-Key sa ešte spracúva. |
unsupported_media_type |
415 | Telo zápisu nie je application/json. |
unprocessable |
422 | Vstup je v poriadku, ale nedá sa prijať: služba nie je pre klienta v ponuke, termín je mimo prevádzkovej doby, príliš skoro alebo sa pri presune neponúka, pracovník či pobočka k službe nepatrí. |
idempotency_key_reused |
422 | Rovnaký Idempotency-Key s iným telom požiadavky. |
rate_limited |
429 | Prekročený limit požiadaviek. |
method_not_allowed |
405 | Cesta túto metódu nepozná. |
server_error |
500 | Chyba na našej strane; v error.details.incident je značka pre podporu. |
409 pri službe so zálohou. Službu, ktorú firma účtuje zálohou online, API objednať nevie: odpovie 409 conflict a nič nezapíše. Pošlite klienta do rezervačného portálu firmy, kde zálohu zaplatí.
409 vracia aj obsadený termín (medzitým ho vzal niekto iný — načítajte voľné termíny znova), neskoré zrušenie alebo presun, pozastavená firma a firma, ktorá zatiaľ neprijíma rezervácie.
Cudzí záznam odpovedá ako neexistujúci (404), nie 403 — z odpovede nejde poznať, čo existuje.
Pri 500 server_error uveďte podpore značku z error.details.incident. Zápis môžete zopakovať s rovnakým Idempotency-Key; ak už prebehol, druhýkrát sa nezapíše.
Limity požiadaviek
Každý token má 60 bodov za kĺzavú minútu. Bežná požiadavka stojí jeden bod, hľadanie voľných termínov 5 bodov, pretože je výpočtovo náročné.
Každá odpoveď nesie RateLimit-Limit, RateLimit-Remaining a RateLimit-Reset. Po prekročení príde 429 rate_limited s hlavičkou Retry-After: počkajte uvedený počet sekúnd a potom pokračujte.
HTTP/1.1 429 Too Many Requests
RateLimit-Limit: 60
RateLimit-Remaining: 0
RateLimit-Reset: 17
Retry-After: 17
Požiadavky bez platného tokenu sa počítajú podľa IP adresy, aby skúšanie tokenov nebolo zadarmo.
Bezpečné opakovanie (Idempotency-Key)
Zápisy (POST a DELETE) môžete poslať s hlavičkou Idempotency-Key — jedinečnou hodnotou pre jednu operáciu, napríklad UUID. Keď spojenie spadne a neviete, či zápis prešiel, pošlite rovnakú požiadavku znova s rovnakým kľúčom: dostanete uloženú odpoveď s hlavičkou Idempotency-Replayed: true a nič sa nezapíše dvakrát.
- Kľúč má 1 až 100 viditeľných znakov ASCII, rozlišuje veľké a malé písmená a platí 24 hodín, len pre ten istý token.
- Rovnaký kľúč s iným telom vráti 422 idempotency_key_reused, opakovanie počas spracovania 409 idempotency_in_progress.
- Pri presune rezervácie (POST /reservations/{id}/move) je hlavička povinná, bez nej príde 400 idempotency_key_required.
- Uloží sa úspech a odmietnutie 409 alebo 422. Chybný vstup ani odmietnutie pre momentálny stav firmy sa neukladá, takže opravený alebo neskorší pokus prejde.
Verzie a zmeny
Verzia rozhrania je v adrese (/api/v1). Nové pole, hodnota výčtu alebo koncový bod pribúdajú bez novej verzie v adrese, preto neznáme polia a hodnoty ignorujte a neznámy stav rezervácie berte ako ukončenú rezerváciu, ktorá sa nekonala. Odobratie alebo zmena významu by znamenala /api/v2.
Bezpečnosť
- Token nepatrí do prehliadača. Kód webovej stránky alebo aplikácie si prečíta každý, kto ju otvorí, a s tokenom potom koná vaším menom. API preto ani neposiela hlavičky CORS a volanie z cudzej webovej stránky prehliadač zablokuje. Volajte ho zo svojho servera.
- Token uložte ako tajný údaj (premenná prostredia, trezor hesiel), nie do zdrojového kódu ani do repozitára.
- Pre každú integráciu vydajte vlastný token s výstižným popisom; pri úniku zneplatníte len ten jeden.
- Pri podozrení na únik token hneď zneplatnite. Zneplatnenie platí okamžite.
- Firemný token nedávajte klientom — tí si vydávajú vlastný token vo svojom účte.