Analityczne API tylko do odczytu
HTTP API api.jonot.io/v1/* zapewnia dostęp tylko do odczytu do danych biletów i kolejek Twojej organizacji — bez konieczności logowania administratora, wystarczy token uwierzytelniający (bearer token). Użyj go, aby pobierać dane do hurtowni danych, narzędzia BI lub własnego panelu.
Uzyskiwanie tokena
Dział zatytułowany „Uzyskiwanie tokena”- Otwórz admin.jonot.io/settings/integrations.
- Kliknij zakładkę API tokens.
- Kliknij Create token, nadaj mu nazwę (np. „Power BI”) i potwierdź.
- Skopiuj token natychmiast — jest pokazywany tylko raz i nie można go odzyskać. Jeśli go zgubisz, odwołaj go i utwórz nowy.
Tokeny mają prefiks jot_ i nigdy nie wygasają same z siebie; odwołuj je w tej samej zakładce, gdy nie są już potrzebne.
Uwierzytelnianie
Dział zatytułowany „Uwierzytelnianie”Authorization: Bearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx| Status | Znaczenie |
|---|---|
401 | Token brakujący, nieprawidłowy, nieznany lub odwołany. |
402 | Token prawidłowy, ale organizacja nie ma włączonej funkcji API. |
429 | Przekroczono limit zapytań — zobacz Limity zapytań poniżej. |
400 | Nieprawidłowe parametry zapytania lub zakres dat dłuższy niż 90 dni. |
Punkty końcowe
Dział zatytułowany „Punkty końcowe”GET /v1/queues
Dział zatytułowany „GET /v1/queues”Zwraca lokalizacje i kolejki Twojej organizacji, bez filtrowania i bez paginacji:
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" } ] } ]}Użyj zwróconych wartości id, aby filtrować /v1/tickets oraz eksport CSV według queueId / locationId.
GET /v1/tickets
Dział zatytułowany „GET /v1/tickets”Paginowany odczyt biletów, ograniczony do Twojej organizacji.
| Parametr | Wymagany | Powtarzalny | Uwagi |
|---|---|---|---|
from | tak | nie | ISO-8601, dolna granica dla createdAt, włącznie. |
to | tak | nie | ISO-8601, górna granica, wyłącznie. Maksymalnie 90 dni zakresu. |
queueId | nie | tak | Powtórz parametr, aby filtrować wiele kolejek. |
locationId | nie | tak | Powtórz parametr, aby filtrować wiele lokalizacji. |
status | nie | tak | Jedna z wartości WAITING, CALLED, COMPLETED, CANCELED, SKIPPED, NO_SHOW. |
cursor | nie | nie | Nieprzejrzysta wartość z pola nextCursor poprzedniej strony. |
limit | nie | nie | Domyślnie 100, maksymalnie 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…"}Wiersze nigdy nie zawierają hasha uwierzytelniającego biletu ani żadnych danych osobowych wprowadzonych przez klienta (imię i nazwisko, notatki, liczba osób) — wyłącznie identyfikatory, status i znaczniki czasu cyklu życia.
Paginacja: gdy nextCursor jest różne od null, przekaż je jako cursor w kolejnym zapytaniu, aby kontynuować od miejsca, w którym skończyłeś (te same from/to/filtry). Wartość null w nextCursor oznacza, że osiągnięto koniec zakresu.
GET /v1/exports/tickets.csv
Dział zatytułowany „GET /v1/exports/tickets.csv”Te same filtry co w /v1/tickets (from/to wymagane, queueId/locationId/status powtarzalne) bez cursor/limit — cały pasujący zakres jest przesyłany strumieniowo jako jedna odpowiedź CSV, więc przy pobieraniu masowym nie trzeba obchodzić limitu 500 wierszy na stronę.
Kolejność kolumn jest stała, ale odczytuj kolumny według nazwy nagłówka, a nie stałej pozycji. Wiersz nagłówka jest zawsze obecny i dokładnie odpowiada tej liście:
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.csvOdpowiedź jest przesyłana strumieniowo (Transfer-Encoding: chunked), więc eksport obejmujący 90 dni / 100 tys. wierszy nie wymaga buforowania w pamięci po żadnej ze stron — przekieruj go bezpośrednio do pliku lub parsera.
Limit zakresu 90 dni
Dział zatytułowany „Limit zakresu 90 dni”Każdy punkt końcowy przyjmujący from/to odrzuca z kodem 400 zakres przekraczający 90 dni. Pobieraj dane przyrostowo (np. jedno zapytanie na tydzień), jeśli potrzebujesz dłuższej historii — znaczniki czasu cyklu życia biletu (calledAt, completedAt, …) pozwalają odtworzyć czasy oczekiwania/obsługi bez dwukrotnego pobierania tych samych wierszy.
Limity zapytań
Dział zatytułowany „Limity zapytań”60 zapytań na minutę na token (nie na adres IP — limit jest powiązany z tokenem). Każda odpowiedź zawiera:
X-RateLimit-Remaining: 42X-RateLimit-Reset: 1751328000000Odpowiedź 429 dodatkowo zawiera nagłówek Retry-After (w sekundach). Odczekaj ten czas przed ponowną próbą; synchronizacja zaplanowana co kilka minut z zapasem mieści się w limicie.
Python + pandas
Dział zatytułowany „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())Albo odczytaj eksport CSV bezpośrednio — pandas obsługuje przesyłaną strumieniowo odpowiedź w sposób przezroczysty:
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 (łącznik Web)
Dział zatytułowany „Power BI (łącznik Web)”- W Power BI Desktop: Get Data → Web.
- Wybierz Advanced i zbuduj adres URL z żądanym zakresem dat, np.
https://api.jonot.io/v1/exports/tickets.csv?from=2026-06-01T00:00:00Z&to=2026-07-01T00:00:00Z. - W sekcji HTTP request header parameters dodaj nagłówek o nazwie
Authorizationz wartościąBearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. - Kliknij OK — Power BI wykryje plik CSV i otworzy podgląd tabeli.
- Kliknij Load (lub najpierw Transform Data, jeśli chcesz ustawić typy kolumn —
createdAt/calledAtitd. są importowane jako tekst; przekształć je w Power Query na typDate/Time). - Ustaw w usłudze Power BI zaplanowane odświeżanie, jeśli pobierasz dane cyklicznie; utrzymuj zakres z zapasem poniżej 90 dni na odświeżenie.