API dokumentace
Napojte Docházka.net na své systémy přes REST API
Úvod
API Docházka.net umožňuje programový přístup k docházkovým datům vaší firmy.
Base URL
https://dochazka.net/api/v1
Cesty endpointů níže uvádíme relativně k této adrese (např. GET /users = https://dochazka.net/api/v1/users).
Formát dat
Odpovědi jsou ve formátu JSON (výjimky u některých chyb viz Chyby → Jiný formát chyb).
Požadavek s tělem (POST) musí mít hlavičku:
Content-Type: application/json
Datum a čas
- Data v parametrech zadávejte ve formátu
YYYY-MM-DD. - Časy docházky a směn (
timestamp,arrival_time,start_timeapod.) jsou v místním čase (Česká republika) ve formátu ISO 8601 bez časové zóny, např.2026-09-01T08:00:00. Stejně je i posílejte; čas se zónou (Z,+02:00) API převede na místní čas. - Pole
created_atu uživatelů,processed_atu docházkových záznamů a poletimestampv chybových odpovědích a u veřejných endpointů jsou v UTC (bez označení zóny).
Autentizace
API používá autentizaci pomocí API klíčů. Klíč je vázaný na vaši firmu a vrací jen její data. Klíče vydává podpora — napište nám na podpora@dochazka.net.
- Klíč začíná
atc_. Předáme vám ho jednou; my ukládáme jen jeho otisk, takže ho později znovu zobrazit nejde — uložte si ho bezpečně. Ztracený klíč nahradíme novým. - Firma může mít víc klíčů (např. pro různé systémy). Klíč, který už nepotřebujete nebo mohl uniknout, na vaši žádost zrušíme — přestane fungovat okamžitě.
- Klíč se předává jen v hlavičce
X-API-Key; jiný způsob (parametr v URL,Authorization: Bearer) API nepřijímá. API nepoužívá cookies ani CSRF tokeny.
Použití API klíče
API klíč předávejte v hlavičce každého požadavku (kromě veřejných endpointů):
X-API-Key: VÁŠ_API_KLÍČ
Příklad požadavku
curl https://dochazka.net/api/v1/users \
-H "X-API-Key: VÁŠ_API_KLÍČ"
Kdy požadavek neprojde
401— chybí hlavičkaX-API-Key, klíč je neplatný, zrušený nebo mu vypršela platnost, případně je účet firmy neaktivní (detail:Tenant inactive) — to platí i pro čtení po uplynutí 14denní ochranné lhůty po konci předplatného nebo u pozastaveného účtu.403— váš tarif API nezahrnuje (např. zkušební verze).403u zápisu (POST) — předplatné skončilo nebo je platba po splatnosti a účet je jen pro čtení. Čtení (GET) během 14denní ochranné lhůty funguje dál; zápis se obnoví po zaplacení předplatného. Stejně tak403vrátí zápis do ukázkové (demo) firmy.
Endpointy
Všechny endpointy v této části vyžadují hlavičku X-API-Key.
U endpointů GET /users a GET /attendance vede neznámý
parametr v URL k chybě 400, ostatní endpointy neznámé parametry ignorují.
Číselné parametry v URL (user_id, limit, offset, days)
musí být celá čísla: user_id od 1, limit od 1 (vyšší než 1000 se sníží na 1000),
offset od 0, days 1–90.
Jiná hodnota (např. ?user_id=abc) vrátí 400 — filtr se nikdy tiše
nevynechá. Nečíselné ID přímo v cestě (např. /analytics/productivity/abc) vrátí 404. user_id, který nepatří vaší firmě, vrátí prázdný seznam.
Uživatelé
GET /users - Seznam uživatelů
Vrací uživatele vaší firmy (ve výchozím stavu jen aktivní) seřazené podle id vzestupně, takže stránkování přes limit/offset je stabilní.
Parametry:
active_only(volitelné) -true= jen aktivní uživatelé, jiná hodnota = všichni (výchozí:true)limit(volitelné) - Počet záznamů (výchozí: 100, max: 1000; vyšší hodnota se omezí na 1000)offset(volitelné) - Kolik záznamů přeskočit (výchozí: 0)
Odpověď 200:
{
"users": [
{
"id": 123,
"username": "jnovak",
"full_name": "Jan Novák",
"email_caption": "Jan Novák",
"work_hours_per_day": 8.0,
"is_admin": false,
"created_at": "2026-01-05T09:12:44.123456"
}
]
}
email_caption- jméno, pod kterým zaměstnanec vystupuje v e-mailech z Jablotronuwork_hours_per_day- denní úvazek v hodinách
Docházka
GET /attendance - Seznam záznamů
Vrací docházkové záznamy (příchody a odchody) seřazené od nejnovějšího.
Parametry:
user_id(volitelné) - ID uživatelestart_date(volitelné) - Datum od včetně (YYYY-MM-DD)end_date(volitelné) - Datum do včetně (YYYY-MM-DD)limit(volitelné) - Počet záznamů (výchozí: 100, max: 1000; vyšší hodnota se omezí na 1000)offset(volitelné) - Kolik záznamů přeskočit (výchozí: 0)
Odpověď 200:
{
"records": [
{
"id": 456,
"user_id": 123,
"username": "jnovak",
"timestamp": "2026-09-01T08:00:00",
"type": "arrival",
"is_manual": false,
"processed_at": "2026-09-01T06:02:13.512834"
}
],
"count": 1
}
type-arrival(příchod) nebodeparture(odchod)is_manual-trueu záznamů vzniklých v aplikaci (včetně tlačítek Přijít/Odejít na webu a ručních úprav) nebo přes API;falseu záznamů načtených z e-mailu (Jablotron)count- počet záznamů v této odpovědi (ne celkový počet)processed_at- kdy záznam vznikl v systému (UTC); čas docházky je vtimestamp
POST /attendance - Přidání záznamu
Vytvoří nový docházkový záznam a přepočítá směny daného dne.
Tělo požadavku:
{
"user_id": 123,
"timestamp": "2026-09-01T08:00:00",
"type": "arrival"
}
user_id(povinné) - ID uživatele vaší firmytimestamp(povinné) - časYYYY-MM-DDTHH:MM:SS. Bez časové zóny se bere jako místní čas (Europe/Prague). S časovou zónou (2026-09-01T06:00:00Z,2026-09-01T08:00:00+02:00) se převede na místní čas, v kterém se záznam uloží i vrátí. Když pošlete jen datumYYYY-MM-DD, použije se toto datum s aktuálním místním časem dne.type(povinné) -arrivalnebodepartureexit_reason(volitelné, jen udeparture) - důvod odchodu:break,doctor,vacationnebounpaid_leave;nullnebonormal= běžný odchod
Jiná pole než tato čtyři API odmítne chybou 400 (stejně jako důvod odchodu
break/doctor/vacation/unpaid_leave u příchodu).
Záznam nelze vložit do období, které je uzavřené uzávěrkou pro mzdy (také 400).
Když je účet jen pro čtení (skončené předplatné), vrátí se 403.
Odpověď 201 (záznam vytvořen):
{
"status": "success",
"message": "Attendance record created successfully",
"record": {
"id": 457,
"user_id": 123,
"username": "jnovak",
"timestamp": "2026-09-01T08:00:00",
"type": "arrival",
"exit_reason": null,
"is_manual": true
},
"shifts_updated": 1,
"created": true
}
Odpověď 200 (duplicita):
Pokud má uživatel ve stejný den záznam stejného typu v intervalu pro detekci duplicit (výchozí 5 minut), nový záznam se nevytvoří:
{
"status": "duplicate",
"message": "Použit existující záznam z 08:00 (rozdíl: 1min)",
"created": false,
"timestamp": "2026-09-01T08:01:00"
}
Směny
GET /shifts - Seznam směn
Vrací směny vypočítané z docházkových záznamů, seřazené od nejnovějšího dne. Odpověď obsahuje nejvýše 500 směn; stránkování tento endpoint nemá, starší data získáte zúžením období.
Parametry:
user_id(volitelné) - ID uživatelestart_date(volitelné) - Datum od včetně (YYYY-MM-DD)end_date(volitelné) - Datum do včetně (YYYY-MM-DD)complete_only(volitelné) -true= jen uzavřené směny (s příchodem i odchodem)
Odpověď 200:
{
"shifts": [
{
"id": 789,
"user_id": 123,
"username": "jnovak",
"date": "2026-09-01",
"arrival_time": "2026-09-01T08:00:00",
"departure_time": "2026-09-01T16:30:00",
"hours_worked": 8.5,
"is_complete": true,
"notes": null,
"shift_type": "work",
"is_paid": true,
"approval_status": "approved"
}
],
"count": 1
}
- Seznam obsahuje všechny úseky dne — práci, přestávky i absence. Rozliší je
shift_type:work(práce),break(přestávka),doctor(lékař),vacation(dovolená),unpaid_leave(neplacené volno),sick_leave(nemoc),sick_day,comp_time(náhradní volno) a případně další druhy absencí. Pro odpracovaný čas filtrujteshift_type == "work". is_paid- zda se úsek počítá jako placený;approval_status- u žádostí o absencipending,approvedneborejected(úseky z docházky jsouapproved).- U neuzavřené směny je
departure_timenullahours_worked0.0.
Pracovní dny
GET /workdays - Seznam pracovních dnů
Vrací pracovní dny s agregovanými daty a jednotlivými úseky (práce, přestávky,
absence), seřazené od nejnovějšího. Odpověď obsahuje nejvýše 500 dnů
a souhrn summary se počítá jen z vrácených dnů.
Parametry:
user_id(volitelné) - ID uživatelestart_date(volitelné) - Datum od včetně (YYYY-MM-DD)end_date(volitelné) - Datum do včetně (YYYY-MM-DD)
Odpověď 200:
{
"workdays": [
{
"id": 456,
"user_id": 123,
"username": "jnovak",
"date": "2026-09-01",
"total_hours_worked": 8.0,
"work_time_minutes": 480,
"total_break_minutes": 30,
"paid_absence_minutes": 0,
"unpaid_absence_minutes": 0,
"is_complete": true,
"shifts": [
{
"id": 789,
"start_time": "2026-09-01T08:00:00",
"end_time": "2026-09-01T12:00:00",
"duration_minutes": 240,
"shift_type": "work",
"sequence_number": 1
},
{
"id": 790,
"start_time": "2026-09-01T12:00:00",
"end_time": "2026-09-01T12:30:00",
"duration_minutes": 30,
"shift_type": "break",
"sequence_number": 2
},
{
"id": 791,
"start_time": "2026-09-01T12:30:00",
"end_time": "2026-09-01T16:30:00",
"duration_minutes": 240,
"shift_type": "work",
"sequence_number": 3
}
]
}
],
"summary": {
"total_hours": 8.0,
"total_days": 1,
"average_hours_per_day": 8.0,
"total_work_time_hours": 8.0,
"total_break_hours": 0.5,
"total_paid_absence_hours": 0.0,
"total_unpaid_absence_hours": 0.0
},
"count": 1
}
shift_type- druh úseku, např.work(práce),break(přestávka),doctor(lékař),vacation(dovolená),unpaid_leave(neplacené volno)total_days- počet vrácených dnů s odpracovanými hodinami;count- počet vrácených dnů celkem
Analytika
GET /analytics/productivity/<user_id> - Přehled produktivity uživatele
Vyhodnotí uzavřené pracovní dny uživatele za posledních N dní: období je od data „dnes minus N dní" do dneška včetně (tedy N+1 kalendářních dní), „dnes" je dnešní datum podle českého času (Europe/Prague).
Parametry:
user_id(v cestě) - ID uživatele vaší firmydays(volitelné) - Počet dní zpět (výchozí: 30, max: 90)
Odpověď 200:
{
"period_days": 30,
"total_shifts": 20,
"avg_hours_per_day": 8.2,
"patterns": {
"weekday_stats": {
"0": {
"avg_hours": 8.3,
"avg_start": "07:55",
"count": 4,
"work_time": 8.3,
"paid_absence": 0.0
}
},
"most_productive_day": 0,
"consistency": "high",
"hours_variance": 0.4,
"trend": "stable",
"total_break_hours": 10.0,
"total_paid_absence_hours": 0.0,
"total_unpaid_absence_hours": 0.0
},
"recommendations": ["…"],
"productivity_score": 85
}
- Dny v týdnu jsou čísla
0(pondělí) až6(neděle). consistency-high,mediumnebolow;trend-improving,stablenebodeclining.total_shifts- počet uzavřených pracovních dnů v období;productivity_score- skóre 0–100.- Když v období žádný uzavřený den není, vrátí se
404(detailvysvětlí, že chybí data k analýze). - Neexistující uživatel vrací
404,daysmimo 1–90 vrací400(standardní formát chyby, viz Chyby).
GET /analytics/team-comparison - Porovnání týmu
Porovná aktivní uživatele za aktuální kalendářní měsíc (od 1. dne do dneška podle českého času). Započítávají se uzavřené pracovní dny; uživatelé bez nich v přehledu nejsou. Endpoint nemá parametry.
Odpověď 200:
{
"user_stats": [
{
"user_id": 123,
"username": "jnovak",
"full_name": "Jan Novák",
"total_hours": 150.5,
"avg_hours": 8.36,
"completion": 94.1,
"shifts_count": 18,
"target_hours": 160.0
}
],
"team_averages": {
"completion": 94.1,
"avg_hours": 8.36
},
"top_performer": {
"user_id": 123,
"username": "jnovak",
"completion": 94.1
},
"period": "01.09. - 29.09.2026"
}
target_hours- pracovní dny období (bez víkendů a svátků) × denní úvazekcompletion- odpracované hodiny v procentech ztarget_hourstop_performer- uživatel s nejvyššímcompletion, nebonull
Veřejné endpointy
Tyto endpointy nevyžadují API klíč.
GET /health - Stav API
{
"status": "ok",
"timestamp": "2026-09-01T06:00:00.000000",
"version": "1.0.0"
}
GET /pricing - Aktuální ceník
Vrací ceny nabízeného tarifu v Kč. Konkrétní tarif lze načíst přes GET /pricing/<tarif>
(např. /pricing/starter); tarif mimo nabídku vrací 400.
{
"status": "success",
"pricing": {
"starter": {
"base_fee": 0,
"included_users": 0,
"min_monthly": 290,
"per_user": 39
}
},
"annual_months_charged": 10,
"larger_installations": "Individuální nabídka — kontaktujte podpora@dochazka.net",
"timestamp": "2026-09-01T06:00:00.000000"
}
Chyby
| Kód | Význam | Popis |
|---|---|---|
200 |
OK | Požadavek byl úspěšně zpracován (u POST /attendance i nalezená duplicita) |
201 |
Created | Záznam byl vytvořen |
400 |
Bad Request | Neplatný požadavek: neznámý nebo chybný parametr, chybné datum, chybějící či nepovolené pole v těle, uzavřené období |
401 |
Unauthorized | Chybí nebo je neplatný API klíč, případně je účet firmy neaktivní |
403 |
Forbidden | Tarif nezahrnuje přístup k API, nebo zápis do účtu, který je jen pro čtení (skončené předplatné, platba po splatnosti, ukázková firma) |
404 |
Not Found | Neexistující endpoint nebo uživatel, případně chybějící data pro analytiku (u POST /attendance vrací neexistující uživatel 400) |
429 |
Too Many Requests | Překročen limit požadavků (viz Limity) |
500 |
Server Error | Interní chyba serveru |
Formát chybové odpovědi
Většina chyb vrací objekt s těmito poli:
{
"type": "https://dochazka.net/errors/validation",
"title": "Validation Error",
"status": 400,
"detail": "Unexpected query parameters: page",
"instance": "/api/v1/users",
"timestamp": "2026-09-01T06:00:00.000000",
"api_version": "v1",
"validation_details": {
"unexpected_parameters": ["page"]
}
}
statusodpovídá HTTP kódu,detailpopisuje konkrétní problém.validation_detailsje jen u některých chyb400(klíčeunexpected_parameters,missing_fieldsnebounexpected_fields). U chybného pole v tělePOSTmůže být navíc klíčfield(např."timestamp"nebo"exit_reason").- Chyby, které nevznikají v samotném endpointu (neexistující adresa, překročený limit), mají
stejná pole
type,title,status,detail,instanceatimestamp,titleje česky a místoapi_versionobsahujíerror_id. - Neočekávané chyby serveru (
500) většinou obsahujíerror_id— ten nám prosím uveďte (případně čas požadavku), když řešíte chybu s podporou na podpora@dochazka.net.
Jiný formát chyb
Endpointy s API klíčem vracejí chyby ve formátu výše. Výjimkou jsou veřejné endpointy ceníku,
které při chybě vracejí {"status": "error", "message": "…", "timestamp": "…"},
a chyby 405 (nepodporovaná metoda) a 413 (požadavek větší než 16 MB),
které vracejí HTML stránku serveru místo JSON.
Limity
Rate limiting
- 1000 požadavků za hodinu z jedné IP adresy, počítáno zvlášť pro každý endpoint.
- Po překročení limitu API vrací
429. - Odpověď neobsahuje hlavičky se stavem limitu (
X-RateLimit-*) aniRetry-After.
Další omezení
- Maximální velikost požadavku: 16 MB
GET /usersaGET /attendance: nejvýše 1000 záznamů na požadavek (parametrlimit)GET /shiftsaGET /workdays: nejvýše 500 nejnovějších položek, bez stránkováníGET /analytics/productivity/<user_id>: nejvýše 90 dní zpět
Potřebujete API přístup?
API je součástí jednotného tarifu — pro vydání klíče napište na podpora@dochazka.net
Zobrazit plány