API d'analytique en lecture seule
L’API HTTP api.jonot.io/v1/* donne un accès en lecture seule aux données de tickets et de files d’attente de votre organisation — aucune connexion Admin requise, juste un jeton porteur. Utilisez-la pour récupérer des données dans un entrepôt de données, un outil de BI, ou un tableau de bord personnalisé.
Obtenir un jeton
Section intitulée « Obtenir un jeton »- Ouvrez admin.jonot.io/settings/integrations.
- Cliquez sur l’onglet API tokens.
- Cliquez sur Create token, donnez-lui un nom (par ex. « Power BI »), et confirmez.
- Copiez le jeton immédiatement — il n’est affiché qu’une seule fois et ne peut pas être récupéré. Si vous le perdez, révoquez-le et créez-en un nouveau.
Les jetons ont le préfixe jot_ et n’expirent jamais d’eux-mêmes ; révoquez-les depuis le même onglet lorsqu’ils ne sont plus nécessaires.
Authentification
Section intitulée « Authentification »Authorization: Bearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx| Statut | Signification |
|---|---|
401 | Jeton manquant, malformé, inconnu, ou révoqué. |
402 | Jeton valide, mais l’organisation n’a pas la fonctionnalité API activée. |
429 | Limite de fréquence dépassée — voir Limites de fréquence ci-dessous. |
400 | Paramètres de requête invalides, ou plage de dates supérieure à 90 jours. |
Points de terminaison
Section intitulée « Points de terminaison »GET /v1/queues
Section intitulée « GET /v1/queues »Retourne les établissements et files d’attente de votre organisation, non filtrés et non paginés :
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" } ] } ]}Utilisez les valeurs id retournées pour filtrer /v1/tickets et l’export CSV par queueId / locationId.
GET /v1/tickets
Section intitulée « GET /v1/tickets »Lecture paginée des tickets, limitée à votre organisation.
| Paramètre | Requis | Répétable | Remarques |
|---|---|---|---|
from | oui | non | ISO-8601, borne inférieure incluse sur createdAt. |
to | oui | non | ISO-8601, borne supérieure exclue. Plage maximale de 90 jours. |
queueId | non | oui | Répétez le paramètre pour filtrer plusieurs files d’attente. |
locationId | non | oui | Répétez le paramètre pour filtrer plusieurs établissements. |
status | non | oui | L’une de WAITING, CALLED, COMPLETED, CANCELED, SKIPPED, NO_SHOW. |
cursor | non | non | Valeur opaque provenant du nextCursor de la page précédente. |
limit | non | non | Par défaut 100, maximum 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…"}Les lignes n’incluent jamais le hash porteur du ticket ni aucune donnée personnelle saisie par le client (nom, notes, taille du groupe) — seulement les identifiants, le statut, et les horodatages de cycle de vie.
Pagination : lorsque nextCursor n’est pas nul, passez-le comme cursor dans la requête suivante pour continuer là où vous vous étiez arrêté (mêmes from/to/filtres). Un nextCursor null signifie que vous avez atteint la fin de la plage.
GET /v1/exports/tickets.csv
Section intitulée « GET /v1/exports/tickets.csv »Mêmes filtres que /v1/tickets (from/to requis, queueId/locationId/status répétables) sans cursor/limit — toute la plage correspondante est diffusée en une seule réponse CSV, il n’y a donc pas de limite de 500 lignes par page à contourner pour une extraction en masse.
L’ordre des colonnes est stable, mais analysez les colonnes par nom d’en-tête plutôt que par position fixe. La ligne d’en-tête est toujours présente et correspond exactement à cette 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.csvLa réponse est diffusée (Transfer-Encoding: chunked) afin qu’un export de 90 jours/100 000 lignes n’ait besoin d’être mis en mémoire tampon d’aucun côté — redirigez-le directement vers un fichier ou un analyseur.
Plafond de plage de 90 jours
Section intitulée « Plafond de plage de 90 jours »Chaque point de terminaison prenant from/to rejette une plage supérieure à 90 jours avec 400. Récupérez les données de manière incrémentale (par ex. un appel par semaine) si vous avez besoin d’un historique plus long — les horodatages de cycle de vie du ticket (calledAt, completedAt, …) vous permettent de reconstituer les durées d’attente/de service sans récupérer deux fois les mêmes lignes.
Limites de fréquence
Section intitulée « Limites de fréquence »60 requêtes/minute par jeton (pas par IP — le budget voyage avec le jeton). Chaque réponse porte :
X-RateLimit-Remaining: 42X-RateLimit-Reset: 1751328000000Un 429 porte en plus Retry-After (secondes). Patientez et réessayez après cette fenêtre ; une synchronisation planifiée toutes les quelques minutes reste confortablement sous la limite.
Python + pandas
Section intitulée « 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())Ou lisez directement l’export CSV — pandas gère la réponse diffusée de manière transparente :
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 (connecteur Web)
Section intitulée « Power BI (connecteur Web) »- Dans Power BI Desktop : Get Data → Web.
- Choisissez Advanced, et construisez l’URL avec votre plage de dates, par ex.
https://api.jonot.io/v1/exports/tickets.csv?from=2026-06-01T00:00:00Z&to=2026-07-01T00:00:00Z. - Sous HTTP request header parameters, ajoutez un en-tête nommé
Authorizationavec la valeurBearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. - Cliquez sur OK — Power BI détecte le CSV et ouvre l’aperçu du tableau.
- Cliquez sur Load (ou Transform Data d’abord si vous voulez définir les types de colonnes —
createdAt/calledAt/etc. s’importent en texte ; convertissez-les enDate/Timedans Power Query). - Configurez une actualisation planifiée dans le service Power BI si vous récupérez les données à intervalles réguliers ; gardez la plage confortablement sous 90 jours par actualisation.