Skrivebeskyttet analytics-API
HTTP-API’et api.jonot.io/v1/* giver skrivebeskyttet adgang til din
organisations billet- og kødata — ingen admin-login er nødvendig, kun et
bearer-token. Brug det til at hente data ind i et data warehouse, et
BI-værktøj eller et selvbygget dashboard.
Sådan får du et token
Sektion kaldt “Sådan får du et token”- Åbn admin.jonot.io/settings/integrations.
- Klik på fanen API tokens.
- Klik på Create token, giv det et navn (f.eks. “Power BI”), og bekræft.
- Kopiér tokenet med det samme — det vises kun én gang og kan ikke gendannes. Mister du det, skal du tilbagekalde det og oprette et nyt.
Tokens har præfikset jot_ og udløber aldrig af sig selv; tilbagekald dem
fra samme fane, når de ikke længere er nødvendige.
Godkendelse
Sektion kaldt “Godkendelse”Authorization: Bearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx| Status | Betydning |
|---|---|
401 | Token mangler, er ugyldigt, ukendt eller er blevet tilbagekaldt. |
402 | Gyldigt token, men organisationen har ikke aktiveret API-funktionen. |
429 | Ratelimit overskredet — se Ratelimits nedenfor. |
400 | Ugyldige forespørgselsparametre, eller et tidsrum på over 90 dage. |
Endpoints
Sektion kaldt “Endpoints”GET /v1/queues
Sektion kaldt “GET /v1/queues”Returnerer din organisations lokationer og køer, ufiltreret og upagineret:
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" } ] } ]}Brug de returnerede id-værdier til at filtrere /v1/tickets og
CSV-eksporten efter queueId / locationId.
GET /v1/tickets
Sektion kaldt “GET /v1/tickets”Pagineret billet-læsning, afgrænset til din organisation.
| Parameter | Påkrævet | Gentagelig | Bemærkninger |
|---|---|---|---|
from | ja | nej | ISO-8601, inklusiv nedre grænse for createdAt. |
to | ja | nej | ISO-8601, eksklusiv øvre grænse. Maks. 90 dages tidsrum. |
queueId | nej | ja | Gentag parameteren for at filtrere flere køer. |
locationId | nej | ja | Gentag parameteren for at filtrere flere lokationer. |
status | nej | ja | En af WAITING, CALLED, COMPLETED, CANCELED, SKIPPED, NO_SHOW. |
cursor | nej | nej | Uigennemsigtig værdi fra forrige sides nextCursor. |
limit | nej | nej | Standard 100, maks. 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…"}Rækkerne indeholder aldrig billettens bearer-hash eller kundeindtastede personoplysninger (navn, noter, gruppestørrelse) — kun id’er, status og livscyklus-tidsstempler.
Paginering: når nextCursor ikke er null, skal du sende den som cursor
i næste forespørgsel for at fortsætte, hvor du slap (samme from/to/filtre).
Et nextCursor på null betyder, at du har nået slutningen af tidsrummet.
GET /v1/exports/tickets.csv
Sektion kaldt “GET /v1/exports/tickets.csv”Samme filtre som /v1/tickets (from/to påkrævet, queueId/locationId/status gentagelige) minus cursor/limit — hele det matchende tidsrum streames som ét CSV-svar, så der ikke er nogen 500-rækkers sidegrænse at omgå ved et massehentet træk.
Kolonnerækkefølgen er stabil, men fortolk kolonner ud fra overskriftsnavnet og ikke en fast position. Overskriftsrækken er altid til stede og matcher nøjagtigt denne liste:
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.csvSvaret streames (Transfer-Encoding: chunked), så en eksport over 90
dage/100.000 rækker ikke behøver at blive bufret i hukommelsen i nogen ende —
led den direkte til en fil eller en parser.
90-dages grænse for tidsrum
Sektion kaldt “90-dages grænse for tidsrum”Alle endpoints, der tager from/to, afviser et tidsrum på over 90 dage med
400. Hent data trinvist (f.eks. ét kald pr. uge), hvis du har brug for en
længere historik — billettens livscyklus-tidsstempler (calledAt,
completedAt, …) lader dig rekonstruere vente-/betjeningstider uden at
hente de samme rækker to gange.
Ratelimits
Sektion kaldt “Ratelimits”60 forespørgsler i minuttet pr. token (ikke pr. IP — kontingentet følger tokenet). Hvert svar indeholder:
X-RateLimit-Remaining: 42X-RateLimit-Reset: 1751328000000Et 429-svar indeholder desuden Retry-After (sekunder). Vent den
tidsperiode, før du prøver igen; en planlagt synkronisering hvert par
minutter holder sig komfortabelt under grænsen.
Python + pandas
Sektion kaldt “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())Eller læs CSV-eksporten direkte — pandas håndterer det streamede svar gennemsigtigt:
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 (webforbindelse)
Sektion kaldt “Power BI (webforbindelse)”- I Power BI Desktop: Get Data → Web.
- Vælg Advanced, og byg URL’en med dit datointerval, f.eks.
https://api.jonot.io/v1/exports/tickets.csv?from=2026-06-01T00:00:00Z&to=2026-07-01T00:00:00Z. - Under HTTP request header parameters skal du tilføje en header ved navn
Authorizationmed værdienBearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. - Klik på OK — Power BI registrerer CSV-filen og åbner tabelforhåndsvisningen.
- Klik på Load (eller først Transform Data, hvis du vil angive kolonnetyper —
createdAt/calledAt/osv. importeres som tekst; konvertér dem tilDate/Timei Power Query). - Angiv en planlagt opdatering i Power BI-tjenesten, hvis du henter data løbende; hold intervallet komfortabelt under 90 dage pr. opdatering.