Alleen-lezen analytics-API
De HTTP-API api.jonot.io/v1/* biedt alleen-lezentoegang tot de ticket- en wachtrijgegevens van je organisatie — geen admin-login vereist, alleen een bearer-token. Gebruik het om gegevens naar een datawarehouse, een BI-tool of een aangepast dashboard te halen.
Een token verkrijgen
Section titled “Een token verkrijgen”- Open admin.jonot.io/settings/integrations.
- Klik op het tabblad API tokens.
- Klik op Create token, geef het een naam (bijv. “Power BI”) en bevestig.
- Kopieer het token onmiddellijk — het wordt slechts één keer getoond en kan niet worden hersteld. Als je het kwijtraakt, trek je het in en maak je een nieuwe aan.
Tokens beginnen met het voorvoegsel jot_ en verlopen niet vanzelf; trek ze in vanaf hetzelfde tabblad wanneer ze niet meer nodig zijn.
Authenticatie
Section titled “Authenticatie”Authorization: Bearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx| Status | Betekenis |
|---|---|
401 | Ontbrekend, misvormd, onbekend of ingetrokken token. |
402 | Geldig token, maar de organisatie heeft de API-functie niet ingeschakeld. |
429 | Snelheidslimiet overschreden — zie Snelheidslimieten hieronder. |
400 | Ongeldige queryparameters, of een datumbereik van meer dan 90 dagen. |
Eindpunten
Section titled “Eindpunten”GET /v1/queues
Section titled “GET /v1/queues”Geeft de locaties en wachtrijen van je organisatie terug, ongefilterd en niet gepagineerd:
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" } ] } ]}Gebruik de teruggegeven id-waarden om /v1/tickets en de CSV-export te filteren op queueId / locationId.
GET /v1/tickets
Section titled “GET /v1/tickets”Gepagineerde ticketlezing, beperkt tot je organisatie.
| Parameter | Verplicht | Herhaalbaar | Opmerkingen |
|---|---|---|---|
from | ja | nee | ISO-8601, inclusieve ondergrens op createdAt. |
to | ja | nee | ISO-8601, exclusieve bovengrens. Maximaal 90 dagen bereik. |
queueId | nee | ja | Herhaal de parameter om meerdere wachtrijen te filteren. |
locationId | nee | ja | Herhaal de parameter om meerdere locaties te filteren. |
status | nee | ja | Een van WAITING, CALLED, COMPLETED, CANCELED, SKIPPED, NO_SHOW. |
cursor | nee | nee | Ondoorzichtige waarde uit nextCursor van de vorige pagina. |
limit | nee | nee | Standaard 100, maximaal 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…"}Rijen bevatten nooit de bearer-hash van het ticket of door de klant ingevoerde persoonsgegevens (naam, notities, groepsgrootte) — alleen id’s, status en de tijdstempels van de levenscyclus.
Paginering: wanneer nextCursor niet null is, geef je deze door als cursor bij het volgende verzoek om verder te gaan waar je gebleven was (dezelfde from/to/filters). Een nextCursor van null betekent dat je het einde van het bereik hebt bereikt.
GET /v1/exports/tickets.csv
Section titled “GET /v1/exports/tickets.csv”Dezelfde filters als /v1/tickets (from/to verplicht, queueId/locationId/status herhaalbaar) minus cursor/limit — het volledige overeenkomende bereik wordt gestreamd als één CSV-respons, dus er is geen limiet van 500 rijen per pagina om omheen te werken bij een bulkuittreksel.
De kolomvolgorde is stabiel, maar parse kolommen op headernaam in plaats van vaste positie. De headerrij is altijd aanwezig en komt exact overeen met deze lijst:
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.csvDe respons wordt gestreamd (Transfer-Encoding: chunked), zodat een export van 90 dagen/100k rijen aan geen van beide kanten in het geheugen hoeft te worden gebufferd — sluis het rechtstreeks naar een bestand of een parser.
Limiet van 90 dagen bereik
Section titled “Limiet van 90 dagen bereik”Elk eindpunt dat from/to gebruikt, weigert een bereik van meer dan 90 dagen met 400. Haal gegevens incrementeel op (bijv. één aanroep per week) als je een langere geschiedenis nodig hebt — de tijdstempels van de ticketlevenscyclus (calledAt, completedAt, …) laten je wacht-/servicetijden reconstrueren zonder dezelfde rijen twee keer op te halen.
Snelheidslimieten
Section titled “Snelheidslimieten”60 verzoeken/minuut per token (niet per IP — het budget reist mee met het token). Elke respons draagt:
X-RateLimit-Remaining: 42X-RateLimit-Reset: 1751328000000Een 429 draagt daarnaast Retry-After (seconden). Wacht en probeer het opnieuw na dat venster; een geplande synchronisatie elke paar minuten blijft ruim onder de limiet.
Python + pandas
Section titled “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())Of lees de CSV-export rechtstreeks — pandas handelt de streaming-respons transparant af:
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 (webconnector)
Section titled “Power BI (webconnector)”- In Power BI Desktop: Get Data → Web.
- Kies Advanced en bouw de URL met je datumbereik, bijv.
https://api.jonot.io/v1/exports/tickets.csv?from=2026-06-01T00:00:00Z&to=2026-07-01T00:00:00Z. - Voeg onder HTTP request header parameters een header toe met de naam
Authorizationen de waardeBearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. - Klik op OK — Power BI detecteert de CSV en opent de tabelvoorbeeldweergave.
- Klik op Load (of eerst op Transform Data als je kolomtypen wilt instellen —
createdAt/calledAt/enz. worden geïmporteerd als tekst; converteer ze in Power Query naarDate/Time). - Stel een geplande vernieuwing in bij de Power BI-service als je op een vast ritme ophaalt; houd het bereik per vernieuwing ruim onder de 90 dagen.