Dokumentace API

Autentizace

API klíč

Každý požadavek na /api/v1/* musí nést hlavičku:

Authorization: Bearer sk_live_...

Klíče jsou GLOBÁLNÍ (spravuje je centrála pro celou síť, ne jednotlivý subjekt) a zakládají se výhradně v portálu (sekce API) - žádný veřejný endpoint klíč nevytváří. Neplatný nebo chybějící klíč vrátí 401 s { error: "invalid-key" }.

"Globální" znamená globální v rámci VAŠÍ franšízy (licence), ne napříč celým onDuty - každá franšíza má vlastní izolovaný prostor dat. Klíč tak vidí a mutuje výhradně zaměstnance, prodejny, směny a další záznamy VLASTNÍ franšízy; cizí ID (i platné, jen patřící jiné franšíze) se chová stejně jako neexistující - { error: "not-found" } (404), nikdy 403, aby se existence cizích záznamů nijak neprozradila.

Scopes

Klíč má jeden nebo oba scopy:

  • read - GET endpointy.
  • write - POST/PATCH/DELETE.

Chybějící scope vrátí 403 s { error: "missing-scope" }.

Klíč se autorizuje NEZÁVISLE na portálové matici rolí a oprávnění (sekce Oprávnění) - v1 API se chová jako centrála se VŠEMI oprávněními katalogu, omezenou jen scopem klíče (read/write) výš. Vlastní role a jejich matice ovlivňují jen portál a mobilní appku, nikdy volání s API klíčem.

Rate limit

300 požadavků za minutu na klíč. Nad limitem přijde 429 s hlavičkou Retry-After.

Idempotence mutací

POST/PATCH/DELETE volání podpoř hlavičkou Idempotency-Key (libovolný unikátní řetězec, např. UUID). Zopakuješ-li stejný požadavek se stejným klíčem do 24 hodin, dostaneš zpátky ULOŽENOU odpověď z prvního pokusu - žádná duplicitní směna, pípnutí ani žádost o volno, i když síť odpověď prvního volání ztratí a klient volání zopakuje. Výjimka: POST /api/v1/webhooks a POST /api/v1/employees hlavičku vědomě ignorují (odpověď nese jednorázové tajemství - webhook secret, resp. pozvánkový odkaz - a nesmí se ukládat do cache); opakované volání tam založí nový záznam.

curl -X POST https://www.onduty.cz/api/v1/punches \
  -H "Authorization: Bearer sk_live_..." \
  -H "Idempotency-Key: 5f1e2a3b-9c4d-4e2a-8f1b-1234567890ab" \
  -H "Content-Type: application/json" \
  -d '{"employee_id":"us_...","store_id":"st_...","direction":"in"}'

Stránkování

Seznamové endpointy podporují ?cursor=&limit= (výchozí 50, max 200). Odpověď nese next_cursor - pošli ho jako cursor v dalším volání, dokud nevrátí null (poslední stránka).