API de analítica de solo lectura
La API HTTP api.jonot.io/v1/* ofrece acceso de solo lectura a los datos de turnos y colas de tu organización. Autentícate con un token bearer en lugar de iniciar sesión como administrador. Usa la API para importar datos en un almacén de datos, una herramienta de inteligencia empresarial o un panel personalizado.
Obtener un token
Sección titulada «Obtener un token»- Abre admin.jonot.io/settings/integrations.
- Haz clic en la pestaña API tokens.
- Haz clic en Create token, dale un nombre (p. ej. «Power BI») y confirma.
- Copia el token de inmediato — se muestra una sola vez y no se puede recuperar. Si lo pierdes, revócalo y crea uno nuevo.
Los tokens llevan el prefijo jot_ y no caducan por sí solos; revócalos desde la misma pestaña cuando ya no los necesites.
Autenticación
Sección titulada «Autenticación»Authorization: Bearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx| Estado | Significado |
|---|---|
401 | Token ausente, mal formado, desconocido o revocado. |
402 | Token válido, pero la organización no tiene activada la función de API. |
429 | Límite de tasa superado — consulta Límites de tasa más abajo. |
400 | Parámetros de consulta inválidos, o un rango de fechas de más de 90 días. |
Endpoints
Sección titulada «Endpoints»GET /v1/queues
Sección titulada «GET /v1/queues»Devuelve las ubicaciones y colas de tu organización, sin filtrar ni paginar:
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" } ] } ]}Usa los valores id devueltos para filtrar /v1/tickets y la exportación CSV por queueId / locationId.
GET /v1/tickets
Sección titulada «GET /v1/tickets»Lectura paginada de turnos, limitada a tu organización.
| Parámetro | Obligatorio | Repetible | Notas |
|---|---|---|---|
from | sí | no | ISO-8601, límite inferior inclusivo sobre createdAt. |
to | sí | no | ISO-8601, límite superior exclusivo. Máximo 90 días de rango. |
queueId | no | sí | Repite el parámetro para filtrar varias colas. |
locationId | no | sí | Repite el parámetro para filtrar varias ubicaciones. |
status | no | sí | Uno de WAITING, CALLED, COMPLETED, CANCELED, SKIPPED, NO_SHOW. |
cursor | no | no | Valor opaco tomado del nextCursor de la página anterior. |
limit | no | no | Por defecto 100, máximo 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…"}Las filas nunca incluyen el hash bearer del turno ni información personal identificable introducida por el cliente, como el nombre, las notas o el tamaño del grupo. Solo incluyen los identificadores, el estado y las marcas de tiempo del ciclo de vida.
Paginación: si nextCursor no es null, envíalo como cursor en la siguiente solicitud. Mantén los mismos valores de from, to y los filtros. Si nextCursor es null, has llegado al final del rango.
GET /v1/exports/tickets.csv
Sección titulada «GET /v1/exports/tickets.csv»Este endpoint acepta los mismos filtros que /v1/tickets: from y to son obligatorios, y queueId, locationId y status se pueden repetir. No acepta cursor ni limit. El rango completo se transmite como una sola respuesta CSV, por lo que no se aplica el límite de 500 filas por página.
El orden de las columnas es estable, pero analiza las columnas por nombre de encabezado, no por posición fija. La fila de encabezado siempre está presente y coincide exactamente con esta lista:
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 respuesta utiliza Transfer-Encoding: chunked. Una exportación de 90 días con 100 000 filas no necesita permanecer en memoria ni en el servidor ni en el cliente. Envíala directamente a un archivo o analizador.
Límite de 90 días por rango
Sección titulada «Límite de 90 días por rango»Todo endpoint que acepta from/to rechaza con 400 un rango de más de 90 días. Extrae los datos de forma incremental (p. ej. una llamada por semana) si necesitas un historial más largo — las marcas de tiempo del ciclo de vida del turno (calledAt, completedAt, …) permiten reconstruir la duración de espera/atención sin volver a extraer las mismas filas dos veces.
Límites de tasa
Sección titulada «Límites de tasa»Cada token permite 60 solicitudes por minuto. El límite se aplica al token, no a la dirección IP. Cada respuesta incluye:
X-RateLimit-Remaining: 42X-RateLimit-Reset: 1751328000000Un 429 incluye además Retry-After (en segundos). Espera esa ventana antes de reintentar; una sincronización programada cada pocos minutos se mantiene cómodamente por debajo del límite.
Organizaciones de demostración
Sección titulada «Organizaciones de demostración»Una organización de demostración tiene un límite adicional de 50 solicitudes al día. También se aplica el límite por minuto. Puedes probar una integración completa: listar colas, obtener turnos y crear una exportación CSV. El límite diario no permite usarla en producción. Si lo superas, la API devuelve 429 y el cuerpo identifica la causa:
{ "error": "demo_quota_exceeded", "limit": 50, "resetAt": "2026-01-02T09:00:00.000Z"}Las exportaciones CSV de demostración también quedan marcadas, de modo que un archivo exportado no pueda confundirse con datos de producción: el nombre de archivo lleva el prefijo demo-, la respuesta incluye el encabezado X-Jonot-Demo: 1, y se añade una columna demo al final del CSV. Las exportaciones de pago no cambian — sin columna ni encabezado adicionales. Suscribirse a un plan de pago elimina la cuota diaria y quita el marcado.
Python + pandas
Sección titulada «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())O lee directamente la exportación CSV — pandas gestiona la respuesta en flujo de forma 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 (conector web)
Sección titulada «Power BI (conector web)»- En Power BI Desktop: Get Data → Web.
- Elige Advanced y construye la URL con tu rango de fechas, p. ej.
https://api.jonot.io/v1/exports/tickets.csv?from=2026-06-01T00:00:00Z&to=2026-07-01T00:00:00Z. - En HTTP request header parameters, añade un encabezado llamado
Authorizationcon el valorBearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. - Haz clic en OK — Power BI detecta el CSV y abre la vista previa de la tabla.
- Haz clic en Load (o antes en Transform Data si quieres fijar los tipos de columna —
createdAt/calledAt/etc. se importan como texto; conviértelos aDate/Timeen Power Query). - Configura una actualización programada en el servicio Power BI si extraes datos de forma periódica; mantén el rango cómodamente por debajo de 90 días por actualización.