Pro vývojáře
Barberyo API
Napojte si rezervace na vlastní web, pokladnu nebo aplikaci. Stejná pravidla jako v našem formuláři — otevírací doba, uzavírky, předstih i rezervační okno platí i přes API.
Začátek za pět minut
- 1
Zapněte API
V administraci pod Nastavení → API a widget přepněte veřejné API.
- 2
Vydejte klíč
Pojmenujte ho podle toho, kde poběží, a dejte mu jen rozsahy, které opravdu potřebuje.
- 3
Zkopírujte klíč
Uvidíte ho jedinkrát. V databázi zůstane jen otisk, takže vám ho nikdo nepřečte — ani my.
- 4
Zavolejte /shop
Když se vrátí profil podniku, je hotovo a můžete stavět.
curl https://barberyo.onrender.com/api/v1/shop \
-H "X-Api-Key: bko_vas_klic"Ověření
Klíč se posílá v hlavičce X-Api-Key. Kdo umí jen
Authorization, může použít
Bearer — funguje obojí.
Klíč nese podnik, takže se v cestách nikde neuvádí, kterého podniku se týkají. Jedním klíčem se nedá dostat k datům jiného podniku.
X-Api-Key: bko_vas_klic
Authorization: Bearer bko_vas_klicCatalogRead,
AvailabilityRead a BookingWrite.
Klíč se čtením zákazníků do prohlížeče nepatří nikdy.
Oprávnění
Každý klíč má vyjmenované rozsahy. Dělí se podle toho, co špatně použitý klíč způsobí — čtení ceníku je neškodné, zápis rezervace zabírá čas v rozvrhu a čtení zákazníků vydá osobní údaje.
| Rozsah | Co dovolí | Citlivost |
|---|---|---|
CatalogRead |
Podnik, služby, barbeři, otevírací doba. | nízká |
AvailabilityRead |
Volné termíny na den i po dnech v měsíci. | nízká |
BookingWrite |
Zakládání a rušení rezervací. | střední |
BookingRead |
Výpis rezervací podniku i se jmény zákazníků. | střední |
ReviewRead |
Veřejná hodnocení. Soukromá zpětná vazba se nevrací nikdy. | nízká |
CustomerRead |
Zákazníci, kontakty, útrata. | vysoká |
Cesty
Vše je pod /api/v1. Odpovědi jsou JSON
v kódování UTF-8, časy v místním čase podniku bez zóny
(2026-09-12T09:30).
Chyby
Chyba má vždycky stejný tvar: strojově čitelný kód a věta pro člověka. Tu druhou jde zákazníkovi ukázat tak, jak je.
{
"error": {
"code": "insufficient_scope",
"message": "Klíč nemá oprávnění BookingWrite."
}
}| Kód | HTTP | Kdy nastane |
|---|---|---|
missing_key |
401 | Chybí hlavička s klíčem. |
invalid_key |
401 | Klíč neplatí, byl zneplatněn, nebo má podnik vypnuté API. |
origin_not_allowed |
403 | Klíč má omezené domény a volání přišlo odjinud. |
insufficient_scope |
403 | Klíč nemá potřebný rozsah. |
rate_limited |
429 | Vyčerpaný limit za minutu. |
invalid_date |
400 | Datum není ve tvaru YYYY-MM-DD. |
not_found |
404 | Zdroj nepatří podniku z klíče, nebo neexistuje. |
booking_failed |
422 | Termín je obsazený, zavřeno, nebo mimo rezervační okno. |
Limity
Každý klíč má vlastní limit požadavků za minutu (výchozí 60, nastavitelný
10–600). Po jeho překročení přijde 429
a hlavička Retry-After říká, za kolik sekund
to zkusit znovu.
Stav limitu posílá API u každé odpovědi, takže na 429 nemusíte
čekat — podle X-RateLimit-Remaining poznáte,
jak blízko jste, a podle X-RateLimit-Reset,
za kolik sekund se okno obnoví.
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57
X-RateLimit-Reset: 43Vypnutí API v administraci zneplatní všechny klíče podniku okamžitě — není to jen přepínač widgetu.
Volání z prohlížeče
API se dá volat přímo ze stránky podniku. U klíče si vyplňte
povolené domény — pak se s ním dá volat jen odtud a nikdo
ho nezneužije na cizím webu. Prohlížeč se nejdřív zeptá metodou
OPTIONS; na tu API odpoví samo.
Z nepovolené domény vrátí 403
origin_not_allowed a odpověď schválně nedostane hlavičku
pro prohlížeč — cizí stránka se tak nedozví ani to, jestli je
klíč platný. V síťovém panelu ten stav uvidíte.
Klíč je ale ve stránce vidět každému návštěvníkovi. Do prohlížeče proto
patří jen klíč se čtením katalogu a volných termínů; zakládání rezervací
nechte na svém serveru, ať se k němu nikdo cizí nedostane. Volání ze
serveru hlavičku Origin neposílá, takže ho
seznam domén neomezuje.
Webhooky
Místo opakovaného dotazování si nechte poslat zprávu, když se něco stane.
Adresa musí být https — zpráva nese jména
a časy zákazníků.
BookingCreatedBookingConfirmedBookingCancelledBookingRescheduledBookingCompletedReviewCreated
Každá zpráva nese hlavičky X-Barberyo-Event,
X-Barberyo-Delivery a podpis
X-Barberyo-Signature. Podpis je
HMAC-SHA256 z těla zprávy s tajemstvím odběru — ověřte ho, adresa
webhooku bývá veřejně dosažitelná.
const crypto = require('crypto');
function overit(telo, podpis, tajemstvi) {
const ocekavany = 'sha256=' + crypto
.createHmac('sha256', tajemstvi)
.update(telo)
.digest('hex');
// Porovnání v konstantním čase — obyčejné === prozradí délku shody.
return crypto.timingSafeEqual(
Buffer.from(ocekavany),
Buffer.from(podpis));
}Odpovězte kódem 2xx. Neúspěch se opakuje pětkrát s rostoucím odstupem (1, 4, 9 a 16 minut). Odběr, který selže dvacetkrát po sobě, se vypne.
Widget na vlastní web
Nejrychlejší cesta, jak se napojit — jeden řádek a lidé se objednají přímo na vašem webu. Rezervace i tak spadne do Barberya.
<!-- kam se má tlačítko vložit (nepovinné) -->
<div data-barberyo-button></div>
<script src="https://barberyo.onrender.com/widget/v1/barberyo.js"
data-shop="gentleman-barber-praha"
data-key="bko_vas_klic"
data-label="Objednat se"
defer></script>
Tlačítko se vloží tam, kde je značka
data-barberyo-button, jinak hned za skript.
Okno jde otevřít i z vlastního kódu přes
Barberyo.open().
window.addEventListener('barberyo:booked', function (e) {
console.log('Rezervace číslo', e.detail.id);
// sem patří měření konverze
});Kuchařka
Tři nejčastější úlohy celé.
const hlavicky = { 'X-Api-Key': 'bko_vas_klic' };
const odpoved = await fetch(
'https://barberyo.onrender.com/api/v1/availability/month' +
'?serviceId=1&month=2026-10',
{ headers: hlavicky });
const { days } = await odpoved.json();
// days: [{ date: "2026-10-01", freeSlots: 12 }, ...]
days.filter(d => d.freeSlots > 0).forEach(d => zvyraznit(d.date));curl -X POST https://barberyo.onrender.com/api/v1/bookings \
-H "X-Api-Key: bko_vas_klic" \
-H "Content-Type: application/json" \
-d '{
"barberId": 3,
"serviceId": 1,
"start": "2026-10-14T09:30",
"customerName": "Jan Novák",
"customerEmail": "[email protected]",
"customerPhone": "+420777123456"
}'app.post('/barberyo', express.raw({ type: 'application/json' }), (req, res) => {
const podpis = req.header('X-Barberyo-Signature');
if (!overit(req.body, podpis, process.env.BARBERYO_SECRET)) {
return res.sendStatus(401);
}
const udalost = req.header('X-Barberyo-Event');
const data = JSON.parse(req.body);
if (udalost === 'BookingCancelled') { uvolnitVKalendari(data.id); }
// Odpovězte hned. Vlastní práci nechte na frontě — čekáme deset vteřin.
res.sendStatus(200);
});Změny
Verze je v cestě. Do v1 přibývají jen nová
pole a nové cesty — nic, co už funguje, se v ní nezmění. Zásah, který by
něco rozbil, dostane v2 a
v1 poběží dál.
GET /api/v1/bookings/{id}— detail jedné rezervace. Na tuhle adresu odkazovala hlavičkaLocationpo založení rezervace, ale samotná cesta chyběla.-
Stav limitu v hlavičkách
X-RateLimit-Limit,X-RateLimit-RemainingaX-RateLimit-Resetu každé odpovědi. - Volání z prohlížeče (CORS) podle povolených domén u klíče.