Gå til indhold

Skrivebeskyttet analytics-API

HTTP-API’et api.jonot.io/v1/* giver skrivebeskyttet adgang til organisationens kølap- og kødata. Brug et bearer-token i stedet for et Admin-login. API’et kan hente data til et datalager, BI-værktøj eller tilpasset dashboard.

  1. Åbn admin.jonot.io/settings/integrations.
  2. Klik på fanen API tokens.
  3. Klik på Create token, giv det et navn (f.eks. “Power BI”), og bekræft.
  4. 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 begynder med jot_ og udløber ikke automatisk. Tilbagekald et token fra samme fane, når du ikke længere bruger det.

Authorization: Bearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
StatusBetydning
401Token mangler, er ugyldigt, ukendt eller er blevet tilbagekaldt.
402Gyldigt token, men organisationen har ikke aktiveret API-funktionen.
429Ratelimit overskredet — se Ratelimits nedenfor.
400Ugyldige forespørgselsparametre, eller et tidsrum på over 90 dage.

Returnerer din organisations lokationer og køer, ufiltreret og upagineret:

Terminal window
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.

Pagineret kølap-læsning, afgrænset til din organisation.

ParameterPåkrævetGentageligBemærkninger
fromjanejISO-8601, inklusiv nedre grænse for createdAt.
tojanejISO-8601, eksklusiv øvre grænse. Maks. 90 dages tidsrum.
queueIdnejjaGentag parameteren for at filtrere flere køer.
locationIdnejjaGentag parameteren for at filtrere flere lokationer.
statusnejjaEn af WAITING, CALLED, COMPLETED, CANCELED, SKIPPED, NO_SHOW.
cursornejnejUigennemsigtig værdi fra forrige sides nextCursor.
limitnejnejStandard 100, maks. 500.
Terminal window
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 ikke kølappens bearer-hash eller personoplysninger, som kunden har indtastet, for eksempel navn, noter eller gruppestørrelse. De indeholder kun id’er, status og tidsstempler fra livscyklussen.

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 nextCursornull betyder, at du har nået slutningen af tidsrummet.

Brug de samme filtre som til /v1/tickets: from og to er påkrævet, og queueId, locationId og status kan gentages. cursor og limit bruges ikke. Hele det valgte tidsrum sendes som ét CSV-svar uden grænsen på 500 rækker pr. side.

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,calledByDeviceSessionId
Terminal window
curl "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.csv

Svaret streames (Transfer-Encoding: chunked), så en 90-dages eksport med 100.000 rækker ikke skal gemmes samlet i hukommelsen. Send den direkte til en fil eller parser.

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 — kølappens livscyklus-tidsstempler (calledAt, completedAt, …) lader dig rekonstruere vente-/betjeningstider uden at hente de samme rækker to gange.

Hvert token kan sende 60 forespørgsler pr. minut. Grænsen følger tokenet og ikke IP-adressen. Hvert svar indeholder:

X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1751328000000

Et 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.

En demoorganisation bruger samme API med en ekstra grænse på 50 anmodninger om dagen. Det er nok til at afprøve en integration ved at liste køer, hente kølapper og lave en CSV-eksport, men ikke til produktion. Hvis grænsen overskrides, returnerer API’et 429 med årsagen:

{
"error": "demo_quota_exceeded",
"limit": 50,
"resetAt": "2026-01-02T09:00:00.000Z"
}

CSV-eksporter fra demoer er også markeret, så en eksporteret fil ikke kan forveksles med produktionsdata: filnavnet har præfikset demo-, svaret indeholder X-Jonot-Demo: 1, og en ekstra demo-kolonne tilføjes til sidst i CSV-filen. Betalte eksporter er uændrede — ingen ekstra kolonne, ingen ekstra header. Et betalt abonnement ophæver den daglige kvote og fjerner markeringerne.

import requests
import 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())

Du kan også læse CSV-eksporten direkte. pandas håndterer det streamede svar:

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}"},
)
  1. I Power BI Desktop: Get Data → Web.
  2. 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.
  3. Under HTTP request header parameters skal du tilføje en header ved navn Authorization med værdien Bearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
  4. Klik på OK — Power BI registrerer CSV-filen og åbner tabelforhåndsvisningen.
  5. Klik på Load (eller først Transform Data, hvis du vil angive kolonnetyper — createdAt/calledAt/osv. importeres som tekst; konvertér dem til Date/Time i Power Query).
  6. Angiv en planlagt opdatering i Power BI-tjenesten, hvis du henter data løbende; hold intervallet komfortabelt under 90 dage pr. opdatering.