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.
Skaffa en token
Section titled “Skaffa en token”- Öppna admin.jonot.io/settings/integrations.
- Klicka på fliken API-tokens.
- Klicka på Skapa token, ge den ett namn (t.ex. “Power BI”) och bekräfta.
- 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.
Autentisering
Section titled “Autentisering”Authorization: Bearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx| Status | Betydelse |
|---|---|
401 | Token saknas, är felaktig, okänd eller återkallad. |
402 | Giltig token, men organisationen har inte API-funktionen aktiverad. |
429 | Hastighetsgräns överskriden — se Hastighetsgränser nedan. |
400 | Ogiltiga frågeparametrar, eller ett datumintervall över 90 dagar. |
Slutpunkter
Section titled “Slutpunkter”GET /v1/queues
Section titled “GET /v1/queues”Returnerar organisationens platser och köer utan filter eller sidindelning:
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.
GET /v1/tickets
Section titled “GET /v1/tickets”Hämtar kölappar med sidindelning inom din organisation.
| Parameter | Krävs | Kan upprepas | Anmärkningar |
|---|---|---|---|
from | ja | nej | ISO-8601, inkluderande nedre gräns på createdAt. |
to | ja | nej | ISO-8601, exkluderande övre gräns. Max 90 dagars intervall. |
queueId | nej | ja | Upprepa parametern för att filtrera flera köer. |
locationId | nej | ja | Upprepa parametern för att filtrera flera platser. |
status | nej | ja | En av WAITING, CALLED, COMPLETED, CANCELED, SKIPPED, NO_SHOW. |
cursor | nej | nej | Ogenomskinligt värde från föregående sidas nextCursor. |
limit | nej | nej | Standard 100, max 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…"}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.
GET /v1/exports/tickets.csv
Section titled “GET /v1/exports/tickets.csv”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,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 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.
90-dagars intervallgräns
Section titled “90-dagars intervallgräns”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.
Hastighetsgränser
Section titled “Hastighetsgränser”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: 42X-RateLimit-Reset: 1751328000000Ett 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.
Demoorganisationer
Section titled “Demoorganisationer”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.
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())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}"},)Power BI (webbanslutning)
Section titled “Power BI (webbanslutning)”- I Power BI Desktop: Get Data → Web.
- 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. - Under HTTP request header parameters, lägg till ett huvud
som heter
Authorizationmed värdetBearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. - Klicka på OK — Power BI identifierar CSV:n och öppnar tabellförhandsvisningen.
- Klicka på Load (eller Transform Data först om du vill sätta
kolumntyper —
createdAt/calledAt/osv. importeras som text; konvertera dem tillDate/Timei Power Query). - 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.