API pro čtení analytických dat
HTTP API api.jonot.io/v1/* poskytuje přístup pro čtení k datům o lístcích a frontách vaší organizace. Místo přihlášení do administrace použijte bearer token. Přes API můžete data načítat do datového skladu, nástroje business intelligence nebo vlastního přehledu.
Získání tokenu
Sekce “Získání tokenu”- Otevřete admin.jonot.io/settings/integrations.
- Klikněte na kartu API tokeny.
- Klikněte na Vytvořit token, zadejte název (např. „Power BI“) a potvrďte.
- Zkopírujte token ihned — zobrazí se pouze jednou a nelze jej znovu získat. Pokud jej ztratíte, zrušte jej a vytvořte nový.
Tokeny mají prefix jot_ a samy o sobě nikdy nevyprší; zrušte je na stejné kartě, jakmile je již nepotřebujete.
Autentizace
Sekce “Autentizace”Authorization: Bearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx| Stav | Význam |
|---|---|
401 | Chybějící, chybně formátovaný, neznámý nebo zrušený token. |
402 | Platný token, ale organizace nemá povolenou funkci API. |
429 | Překročen limit počtu požadavků — viz Limity požadavků níže. |
400 | Neplatné parametry dotazu, nebo časové rozmezí delší než 90 dní. |
Endpointy
Sekce “Endpointy”GET /v1/queues
Sekce “GET /v1/queues”Vrátí pobočky a fronty vaší organizace, nefiltrované a nestránkované:
curl https://api.jonot.io/v1/queues \ -H "Authorization: Bearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"{ "locations": [ { "id": "loc_…", "name": "Downtown", "slug": "downtown", "queues": [ { "id": "q_…", "name": "Main Queue", "slug": "main-queue", "status": "ACTIVE" } ] } ]}Vrácené hodnoty id použijte k filtrování /v1/tickets a exportu CSV podle queueId / locationId.
GET /v1/tickets
Sekce “GET /v1/tickets”Stránkované čtení lístků, omezené na vaši organizaci.
| Parametr | Povinný | Opakovatelný | Poznámky |
|---|---|---|---|
from | ano | ne | ISO-8601, včetně dolní hranice na createdAt. |
to | ano | ne | ISO-8601, vyjma horní hranice. Max. rozmezí 90 dní. |
queueId | ne | ano | Parametr opakujte pro filtrování více front. |
locationId | ne | ano | Parametr opakujte pro filtrování více poboček. |
status | ne | ano | Jedna z hodnot WAITING, CALLED, COMPLETED, CANCELED, SKIPPED, NO_SHOW. |
cursor | ne | ne | Neprůhledná hodnota z nextCursor předchozí stránky. |
limit | ne | ne | Výchozí 100, max. 500. |
curl "https://api.jonot.io/v1/tickets?from=2026-06-01T00:00:00Z&to=2026-06-08T00:00:00Z&status=COMPLETED" \ -H "Authorization: Bearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"{ "items": [ { "id": "tkt_…", "number": 42, "queueId": "q_…", "locationId": "loc_…", "status": "COMPLETED", "createdAt": "2026-06-01T09:14:02.000Z", "calledAt": "2026-06-01T09:20:11.000Z", "completedAt": "2026-06-01T09:24:47.000Z", "cancelledAt": null, "skippedAt": null, "noShowAt": null, "calledByDeviceSessionId": "dev_…" } ], "nextCursor": "eyJjcmVhdGVkQXQi…"}Řádky neobsahují bearer hash lístku ani osobní údaje zadané zákazníkem, například jméno, poznámky nebo počet osob. Obsahují jen ID, stav a časová razítka životního cyklu.
Stránkování: Pokud nextCursor není null, předejte ho v dalším požadavku jako cursor a zachovejte stejné hodnoty from, to a filtrů. Hodnota nextCursor rovná null znamená konec rozmezí.
GET /v1/exports/tickets.csv
Sekce “GET /v1/exports/tickets.csv”Endpoint přijímá stejné filtry jako /v1/tickets: from a to jsou povinné a queueId, locationId a status lze opakovat. Nepřijímá cursor ani limit. Celé odpovídající rozmezí odešle jako jednu odpověď CSV, takže se na něj nevztahuje limit 500 řádků na stránku.
Pořadí sloupců je stabilní, ale sloupce parsujte podle názvu hlavičky, ne podle pevné pozice. Řádek s hlavičkou je vždy přítomen a přesně odpovídá tomuto seznamu:
id,number,queueId,locationId,status,createdAt,calledAt,completedAt,cancelledAt,skippedAt,noShowAt,calledByDeviceSessionIdcurl "https://api.jonot.io/v1/exports/tickets.csv?from=2026-06-01T00:00:00Z&to=2026-07-01T00:00:00Z" \ -H "Authorization: Bearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ -o tickets.csvOdpověď používá Transfer-Encoding: chunked. Export za 90 dní se 100 000 řádky tak nemusí zůstat v paměti serveru ani klienta. Odešlete ho přímo do souboru nebo parseru.
Limit rozmezí 90 dní
Sekce “Limit rozmezí 90 dní”Každý koncový bod s parametry from a to odmítne rozmezí delší než 90 dní chybou 400. Delší historii načítejte po kratších úsecích, například po týdnech. Z časových razítek calledAt a completedAt můžete spočítat dobu čekání a obsluhy bez opakovaného načítání stejných řádků.
Limity požadavků
Sekce “Limity požadavků”Každý token umožňuje 60 požadavků za minutu. Limit se neváže k IP adrese. Každá odpověď obsahuje:
X-RateLimit-Remaining: 42X-RateLimit-Reset: 1751328000000Odpověď 429 navíc obsahuje Retry-After (v sekundách). Počkejte a zkuste to znovu po tomto intervalu; naplánovaná synchronizace každých pár minut se pohodlně vejde pod limit.
Demo organizace
Sekce “Demo organizace”Demo organizace má další limit 50 požadavků denně. Platí pro ni také minutový limit. Demo API stačí k otestování výpisu front, načtení lístků a exportu CSV, ale ne k produkčnímu provozu. Po překročení denního limitu API vrátí 429 s tělem, které uvádí příčinu:
{ "error": "demo_quota_exceeded", "limit": 50, "resetAt": "2026-01-02T09:00:00.000Z"}Exporty CSV z demo organizace jsou také označené, aby exportovaný soubor nemohl být zaměněn za produkční data: název souboru má předponu demo-, odpověď obsahuje hlavičku X-Jonot-Demo: 1 a na konec CSV se přidá sloupec demo. Placené exporty zůstávají beze změny — žádný extra sloupec, žádná extra hlavička. Přechod na placený tarif denní limit zruší a tato označení odstraní.
Python + pandas
Sekce “Python + pandas”import requestsimport pandas as pd
TOKEN = "jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"BASE = "https://api.jonot.io/v1"HEADERS = {"Authorization": f"Bearer {TOKEN}"}
def fetch_tickets(frm: str, to: str) -> pd.DataFrame: rows = [] cursor = None while True: params = {"from": frm, "to": to, "limit": 500} if cursor: params["cursor"] = cursor res = requests.get(f"{BASE}/tickets", headers=HEADERS, params=params, timeout=30) res.raise_for_status() body = res.json() rows.extend(body["items"]) cursor = body["nextCursor"] if not cursor: break return pd.DataFrame(rows)
df = fetch_tickets("2026-06-01T00:00:00Z", "2026-07-01T00:00:00Z")df["waitSeconds"] = ( pd.to_datetime(df["calledAt"]) - pd.to_datetime(df["createdAt"])).dt.total_seconds()print(df.groupby("queueId")["waitSeconds"].mean())Nebo přečtěte export CSV přímo — pandas zvládá streamovanou odpověď transparentně:
df = pd.read_csv( f"{BASE}/exports/tickets.csv?from=2026-06-01T00:00:00Z&to=2026-07-01T00:00:00Z", storage_options={"Authorization": f"Bearer {TOKEN}"},)Power BI (webový konektor)
Sekce “Power BI (webový konektor)”- V aplikaci Power BI Desktop: Získat data → Web.
- Zvolte Pokročilé a sestavte URL s vaším časovým rozmezím, např.
https://api.jonot.io/v1/exports/tickets.csv?from=2026-06-01T00:00:00Z&to=2026-07-01T00:00:00Z. - V sekci Parametry hlavičky HTTP požadavku přidejte hlavičku s názvem
Authorizationa hodnotouBearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. - Klikněte na OK — Power BI rozpozná CSV a otevře náhled tabulky.
- Klikněte na Načíst (nebo nejprve na Transformovat data, pokud chcete nastavit typy sloupců —
createdAt/calledAt/atd. se importují jako text; převeďte je naDate/Timev Power Query). - Pokud data stahujete pravidelně, nastavte v Power BI service naplánovanou obnovu; udržujte rozmezí pohodlně pod 90 dny na jednu obnovu.