Hoppa till innehåll

Analytics-API med skrivskyddad åtkomst

HTTP-API:et api.jonot.io/v1/* ger skrivskyddad åtkomst till organisationens kölapps- och ködata. Autentisera med en bearer-token i stället för en Admin-inloggning. Använd API:et för att importera data till ett datalager, ett BI-verktyg eller en egen instrumentpanel.

  1. Öppna admin.jonot.io/settings/integrations.
  2. Klicka på fliken API-tokens.
  3. Klicka på Skapa token, ge den ett namn (t.ex. “Power BI”) och bekräfta.
  4. Kopiera token direkt — den visas bara en gång och kan inte återställas. Om du tappar bort den, återkalla den och skapa en ny.

Tokens har prefixet jot_ och löper aldrig ut av sig själva; återkalla dem från samma flik när de inte längre behövs.

Authorization: Bearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
StatusBetydelse
401Token saknas, är felaktig, okänd eller återkallad.
402Giltig token, men organisationen har inte API-funktionen aktiverad.
429Hastighetsgräns överskriden — se Hastighetsgränser nedan.
400Ogiltiga frågeparametrar, eller ett datumintervall över 90 dagar.

Returnerar organisationens platser och köer utan filter eller sidindelning:

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"
}
]
}
]
}

Använd de returnerade id-värdena för att filtrera /v1/tickets och CSV-exporten med queueId / locationId.

Hämtar kölappar med sidindelning inom din organisation.

ParameterKrävsKan upprepasAnmärkningar
fromjanejISO-8601, inkluderande nedre gräns på createdAt.
tojanejISO-8601, exkluderande övre gräns. Max 90 dagars intervall.
queueIdnejjaUpprepa parametern för att filtrera flera köer.
locationIdnejjaUpprepa parametern för att filtrera flera platser.
statusnejjaEn av WAITING, CALLED, COMPLETED, CANCELED, SKIPPED, NO_SHOW.
cursornejnejOgenomskinligt värde från föregående sidas nextCursor.
limitnejnejStandard 100, max 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…"
}

Rader innehåller aldrig kölappens bearer-hash eller kundinmatade personuppgifter (namn, anteckningar, antal personer) — bara id:n, status och livscykelns tidsstämplar.

Sidindelning: När nextCursor inte är null skickar du värdet som cursor i nästa förfrågan. Behåll samma from, to och filter. Ett nextCursor-värde på null betyder att du har nått slutet av intervallet.

Slutpunkten använder samma filter som /v1/tickets. from och to krävs, medan queueId, locationId och status kan upprepas. Den accepterar inte cursor eller limit. Hela det matchande intervallet skickas som ett CSV-svar, så sidgränsen på 500 rader gäller inte.

Kolumnordningen är stabil, men tolka kolumner efter rubriknamn i stället för fast position. Rubrikraden finns alltid med och matchar exakt den här listan:

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 använder Transfer-Encoding: chunked. En 90-dagarsexport med 100 000 rader behöver därför inte lagras i minnet hos klienten eller servern. Skicka den direkt till en fil eller parser.

Varje slutpunkt som tar from/to avvisar ett intervall över 90 dagar med 400. Hämta data stegvis (t.ex. ett anrop per vecka) om du behöver längre historik — kölappens livscykel-tidsstämplar (calledAt, completedAt, …) låter dig återskapa vänte-/betjäningstider utan att hämta samma rader två gånger.

Varje token tillåter 60 förfrågningar per minut. Gränsen gäller token, inte IP-adressen. Varje svar innehåller:

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

Ett 429-svar innehåller också Retry-After i sekunder. Vänta den angivna tiden innan du försöker igen. En schemalagd synkronisering med några minuters mellanrum håller sig under gränsen.

En demoorganisation har tillgång till samma API, med ytterligare 50 förfrågningar per dag utöver gränsen per minut. Det räcker för att verifiera en integration från början till slut — lista dina köer, hämta några kölappar, göra en CSV-export — och är medvetet inte tillräckligt för att köra en i produktion. Överskrids kvoten, svarar API:et med en 429 vars innehåll anger orsaken, i stället för det vanliga hastighetsgränssvaret utan närmare förklaring:

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

Demo-CSV-exporter märks också, så att en exporterad fil inte kan förväxlas med produktionsdata: filnamnet får prefixet demo-, svaret bär med sig X-Jonot-Demo: 1, och en avslutande kolumn demo läggs till i CSV-filen. Betalda exporter är oförändrade — ingen extra kolumn, ingen extra header. Att teckna en betald plan tar bort den dagliga kvoten och märkningarna.

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

Eller läs CSV-exporten direkt — pandas hanterar det strömmade svaret transparent:

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älj Advanced och bygg URL:en med ditt datumintervall, t.ex. 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, lägg till ett huvud som heter Authorization med värdet Bearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
  4. Klicka på OK — Power BI identifierar CSV:n och öppnar tabellförhandsvisningen.
  5. Klicka på Load (eller Transform Data först om du vill sätta kolumntyper — createdAt/calledAt/osv. importeras som text; konvertera dem till Date/Time i Power Query).
  6. Ställ in en schemalagd uppdatering i Power BI-tjänsten om du hämtar data regelbundet; håll intervallet bekvämt under 90 dagar per uppdatering.