Ir al contenido

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 — sin necesidad de iniciar sesión como administrador, solo un token bearer. Úsala para llevar datos a un data warehouse, una herramienta de BI o un panel personalizado.

  1. Abre admin.jonot.io/settings/integrations.
  2. Haz clic en la pestaña API tokens.
  3. Haz clic en Create token, dale un nombre (p. ej. «Power BI») y confirma.
  4. 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.

Authorization: Bearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
EstadoSignificado
401Token ausente, mal formado, desconocido o revocado.
402Token válido, pero la organización no tiene activada la función de API.
429Límite de tasa superado — consulta Límites de tasa más abajo.
400Parámetros de consulta inválidos, o un rango de fechas de más de 90 días.

Devuelve las ubicaciones y colas de tu organización, sin filtrar ni paginar:

Ventana de terminal
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.

Lectura paginada de turnos, limitada a tu organización.

ParámetroObligatorioRepetibleNotas
fromnoISO-8601, límite inferior inclusivo sobre createdAt.
tonoISO-8601, límite superior exclusivo. Máximo 90 días de rango.
queueIdnoRepite el parámetro para filtrar varias colas.
locationIdnoRepite el parámetro para filtrar varias ubicaciones.
statusnoUno de WAITING, CALLED, COMPLETED, CANCELED, SKIPPED, NO_SHOW.
cursornonoValor opaco tomado del nextCursor de la página anterior.
limitnonoPor defecto 100, máximo 500.
Ventana de terminal
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 datos personales introducidos por el cliente (nombre, notas, tamaño del grupo) — solo ids, estado y las marcas de tiempo del ciclo de vida.

Paginación: cuando nextCursor no es nulo, pásalo como cursor en la siguiente solicitud para continuar donde lo dejaste (mismos from/to/filtros). Un nextCursor con valor null significa que has llegado al final del rango.

Los mismos filtros que /v1/tickets (from/to obligatorios, queueId/locationId/status repetibles) sin cursor/limit — todo el rango coincidente se transmite como una única respuesta CSV, así que no hay que sortear un límite de 500 filas por página en una extracción masiva.

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,calledByDeviceSessionId
Ventana de terminal
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

La respuesta se transmite en flujo (Transfer-Encoding: chunked), de modo que una exportación de 90 días / 100 000 filas no necesita almacenarse en memoria en ninguno de los dos extremos — pásala directamente a un archivo o a un analizador.

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.

60 solicitudes por minuto y por token (no por IP — el presupuesto viaja con el token). Cada respuesta incluye:

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

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

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

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}"},
)
  1. En Power BI Desktop: Get Data → Web.
  2. 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.
  3. En HTTP request header parameters, añade un encabezado llamado Authorization con el valor Bearer jot_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
  4. Haz clic en OK — Power BI detecta el CSV y abre la vista previa de la tabla.
  5. 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 a Date/Time en Power Query).
  6. 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.