Přejít na obsah

Pro vývojáře

API a webhooky. Data tam, kde je potřebujete.

Přeneste rezervace do účetnictví, doplňte je do vlastního CRM nebo si postavte rozhraní na míru. Čtete přes REST API a o každé změně se dozvíte webhookem - bez ptaní dokola.

Strojově čitelná specifikace: openapi.yaml

1. Za pět minut k prvnímu dotazu

API je součástí tarifu Firma. Klíč si vydáte sami v dashboardu v sekci API a webhooky - nikoho o přístup žádat nemusíte.

Plnou hodnotu klíče ukážeme jen jednou, hned po vytvoření. Dál si z ní držíme pouze otisk, takže ji nedokážeme obnovit ani my. Když se klíč ztratí, vydáte nový a starý odvoláte.

Klíč posíláte v hlavičce Authorization a patří vždy jednomu pracovnímu prostoru - odpovědi jsou automaticky omezené na jeho data:

curl https://api.eazo.eu/public/v1/me \
  -H "Authorization: Bearer eazo_sk_..."

Odpověď řekne, ke kterému prostoru klíč patří a co smí. Je to nejrychlejší způsob, jak ověřit, že máte vše nastavené správně.

Oprávnění klíče

Při vydání volíte mezi dvěma úrovněmi:

  • Jen čtení - přečte služby, pracovníky, zákazníky, rezervace a volné termíny. Účetnictví nic víc nepotřebuje.
  • Čtení i zápis - navíc zakládá rezervace, přesouvá je a mění jejich stav. Pro CRM, které má do kalendáře i psát.

Oprávnění se u vydaného klíče nemění. Kdo potřebuje víc, vydá nový klíč - ten starý mezitím dál funguje, takže se dá vyměnit bez výpadku.

2. Co API umí

Vše běží na adrese https://api.eazo.eu/public/v1 a odpovídá JSONem.

  • GET /me - ověření klíče a informace o prostoru
  • GET /services, GET /services/{id} - katalog služeb
  • GET /staff, GET /staff/{id} - pracovníci
  • GET /customers, GET /customers/{id} - adresář zákazníků
  • GET /availability - volné termíny služby
  • GET /bookings, GET /bookings/{id} - rezervace
  • POST /bookings - založení rezervace
  • PATCH /bookings/{id} - přesun termínu, interní poznámka, odkaz na videohovor
  • POST /bookings/{id}/confirm, /reject, /cancel - změna stavu

Stránkování a přírůstky

Seznamy vracejí data v obálce s počtem záznamů. Listuje se parametry limit (nejvýš 100) a offset:

{
  "data": [ … ],
  "meta": { "total": 248, "limit": 50, "offset": 0 }
}

Pro pravidelnou synchronizaci se hodí parametr updatedSince - vrátí jen záznamy změněné od zadaného okamžiku, takže si nemusíte pokaždé stahovat celou historii:

curl "https://api.eazo.eu/public/v1/bookings?updatedSince=2026-09-01T00:00:00%2B02:00&status=confirmed" \
  -H "Authorization: Bearer eazo_sk_..."

Časy chodí i se přijímají v ISO 8601 s offsetem pásma vašeho prostoru. Identifikátory jsou vždy UUID.

Založení rezervace

Rezervace přes API vzniká jménem provozovatele - rovnou jako potvrzená, se stejnými e-maily a zápisem do propojeného kalendáře, jako byste ji naklikali v dashboardu:

curl -X POST https://api.eazo.eu/public/v1/bookings \
  -H "Authorization: Bearer eazo_sk_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: objednavka-2026-4711" \
  -d '{
    "serviceId": "9f1c…",
    "date": "2026-09-15",
    "time": "14:30",
    "name": "Jana Nováková",
    "email": "[email protected]",
    "phone": "734156239"
  }'

Hlavička Idempotency-Key je nepovinná, ale vyplatí se. Když vám při odesílání spadne spojení, nevíte, jestli rezervace vznikla. Se stejným klíčem vám opakovaný požadavek do 24 hodin vrátí tutéž odpověď místo druhé rezervace - poznáte to podle hlavičky Idempotent-Replay: true.

Když je termín mezitím obsazený, vrátí se 409 s kódem SLOT_UNAVAILABLE. Volné časy si předem ověříte přes GET /availability - počítají se podle stejných pravidel, jaká vidí zákazník ve widgetu, včetně otevírací doby, svátků, dovolené a propojeného kalendáře.

3. Webhooky místo ptaní dokola

Stahovat každých pár minut seznam rezervací funguje, ale je to plýtvání na obou stranách. Zadejte místo toho adresu svého systému jako webhook a my na ni pošleme každou vybranou událost hned, jak nastane.

Nastavíte to v dashboardu v sekci API a webhooky → Přidat webhook. Vyberete adresu a události, které chcete dostávat:

  • booking.created - vznikla rezervace (z widgetu, z rezervační stránky i přes API)
  • booking.confirmed - čekající rezervaci někdo potvrdil
  • booking.rejected - čekající rezervace byla zamítnuta
  • booking.cancelled - potvrzená rezervace byla zrušena
  • booking.rescheduled - termín se přesunul
  • booking.no_show - zákazník na termín nedorazil

Tělo požadavku má vždy stejnou obálku; v data je objekt ve stejném tvaru, jaký vrací REST API - nemusíte tedy udržovat dvě různá mapování:

{
  "id": "3f2b…",
  "type": "booking.confirmed",
  "createdAt": "2026-09-06T11:24:03+02:00",
  "workspaceId": "a71c…",
  "data": { "booking": { … } }
}

Hodnotu id posíláme i v hlavičce Eazo-Event-Id. Poslouží vám k rozpoznání opakovaného doručení - stejné id znamená stejnou událost, i když dorazí podruhé.

Když váš server neodpovídá

Za úspěch považujeme jakoukoli odpověď 2xx. Když nepřijde, zkoušíme doručení celkem šestkrát s narůstající prodlevou. Odpovídejte proto rychle - přijetí potvrďte a zpracování si odložte na pozadí.

Když adresa neodpovídá dlouhodobě (patnáctkrát po sobě), webhook vypneme a pošleme vám e-mail. Nebušíme donekonečna do adresy, kterou už nikdo neposlouchá. Každý pokus i s odpovědí vašeho serveru najdete v dashboardu a nedoručenou událost odtud pošlete znovu - se stejným tělem, jaké mělo dorazit poprvé.

Historii doručení držíme 30 dní. Události nesou kontakt na zákazníka, takže je nechceme skladovat déle, než je k čemu.

4. Ověření podpisu

Adresa webhooku je typicky veřejná, takže na ni může poslat požadavek kdokoli. Proto každý požadavek podepisujeme hlavičkou:

Eazo-Signature: t=1757155443,v1=9c8f2b…

t je čas odeslání (unixové razítko) a v1 je HMAC-SHA256 z řetězce "{t}.{tělo požadavku}", podepsaný vaším tajemstvím. Tajemství dostanete při vytvoření webhooku - stejně jako klíč jen jednou.

Ověření v PHP vypadá takhle:

function overitPodpis(string $telo, string $hlavicka, string $tajemstvi): bool
{
    // t=…,v1=… rozebereme na dvojice
    parse_str(str_replace(',', '&', $hlavicka), $casti);

    // Staré razítko odmítneme, ať nejde požadavek přehrát později
    if (abs(time() - (int) $casti['t']) > 300) {
        return false;
    }

    $ocekavany = hash_hmac('sha256', $casti['t'] . '.' . $telo, $tajemstvi);

    // Konstantní porovnání - obyčejné === prozradí časem, kam se shoda dostala
    return hash_equals($ocekavany, $casti['v1']);
}

Podpis počítejte vždy z nezpracovaného těla požadavku. Když ho nejdřív přeložíte na objekt a zase zpět na JSON, může se změnit pořadí klíčů nebo mezery - a podpis pak nesedí, i když je v pořádku.

Tajemství jde kdykoli vyměnit v dashboardu. Staré tím okamžitě přestane platit, takže ho vyměňte i u sebe.

5. Limity a chyby

Na klíč platí limit 120 požadavků za minutu. Kolik vám zbývá, říkají hlavičky X-RateLimit-RemainingX-RateLimit-Reset; po překročení přijde 429 s hlavičkou Retry-After.

Chyby mají vždy stejný tvar - strojově čitelný kód a vysvětlení pro člověka:

{
  "error": "VALIDATION_ERROR",
  "message": "Některé údaje jsou neplatné.",
  "fields": { "email": "Zadejte platný e-mail." }
}

S čím se potkáte nejčastěji:

  • UNAUTHORIZED (401) - chybí nebo neplatí klíč
  • PLAN_REQUIRED (403) - prostor nemá tarif Firma
  • INSUFFICIENT_SCOPE (403) - klíč umí jen číst
  • RESOURCE_NOT_FOUND (404) - zdroj v prostoru klíče neexistuje
  • SLOT_UNAVAILABLE (409) - termín je obsazený
  • INVALID_STATE (409) - rezervace není ve stavu, který operaci dovoluje
  • RATE_LIMITED (429) - vyčerpaný limit požadavků

Že klíč sahá na cizí pracovní prostor, poznáte jako 404, ne jako 403. Kdyby se to lišilo, dalo by se přes API zjišťovat, co má v systému konkurence.

6. Strojově čitelná specifikace

Celé rozhraní popisuje soubor openapi.yaml ve formátu OpenAPI 3.1. Vygenerujete si z něj klienta ve svém jazyce, naimportujete ho do Postmanu nebo si podle něj postavíte testy.

Kontrakt rozšiřujeme, neměníme: klíče v odpovědích ani názvy událostí nepřejmenováváme a neodebíráme, jen přidáváme nové. Integrace, která dnes funguje, tak nepřestane fungovat po našem nasazení.

Časté dotazy

V jakém tarifu je API dostupné?

V tarifu Firma. Klíč si vydáte sami v dashboardu v sekci API a webhooky - schvalování ani žádost o přístup nejsou potřeba.

Musím se ptát dokola, jestli přibyla rezervace?

Ne. Zadejte adresu svého systému jako webhook a Eazo na ni pošle každou vybranou událost hned, jak nastane. Pravidelné dotazování je pak zbytečné.

Jak poznám, že webhook přišel opravdu od Eazo?

Každý požadavek nese hlavičku Eazo-Signature s časovým razítkem a podpisem HMAC-SHA256 z těla zprávy a vašeho tajemství. Spočítáte totéž a porovnáte - ukázka je o kus výš.

Co se stane, když můj server zrovna neodpovídá?

Doručení opakujeme šestkrát s narůstající prodlevou. Když adresa neodpovídá dlouhodobě, webhook vypneme a pošleme vám e-mail. Každý pokus i s odpovědí serveru najdete v dashboardu a událost jde poslat znovu.

Můžu přes API i zakládat rezervace?

Ano, pokud klíči dáte oprávnění k zápisu. Rezervace založená přes API se chová stejně jako naklikaná v dashboardu - odejdou e-maily, zapíše se do propojeného kalendáře a spustí webhooky.