Skip to Content

BI / Power BI

Objetivo: llevar los datos de control horario a tu data warehouse o directamente a Power BI / Looker / Metabase mediante sincronización incremental.

Scopes recomendados (solo lectura): org:fichajes:read, org:ausencias:read, org:saldos:read, org:estructura:read.

Para BI usa una key dedicada de solo lectura. Así puedes revocarla o rotarla sin afectar a integraciones de escritura.

Patrón: polling incremental con updated_since

Todos los listados aceptan updated_since=<ISO8601> y devuelven solo lo modificado desde ese instante. El patrón:

Carga inicial (backfill)

Recorre cada recurso paginando por cursor hasta has_more=false. Guarda el instante de inicio como marca de agua (watermark).

Cargas incrementales

En cada ejecución programada, pide ?updated_since=<watermark> y actualiza tu marca de agua al instante anterior al inicio de la llamada.

Deduplica por id

Como updated_since se basa en updated_at, un mismo registro puede volver a aparecer si cambió. Haz upsert por id (UUID) en tu almacén.

Ejemplo en Python

import os, requests from datetime import datetime, timezone BASE = os.environ["KINMU_BASE_URL"] KEY = os.environ["KINMU_API_KEY"] session = requests.Session() session.headers.update({"Authorization": f"Bearer {KEY}"}) def sync(resource, since=None): rows, cursor = [], None params = {"limit": 100} if since: params["updated_since"] = since while True: if cursor: params["cursor"] = cursor r = session.get(f"{BASE}/{resource}", params=params, timeout=30) r.raise_for_status() body = r.json() rows.extend(body["data"]) if not body["meta"]["has_more"]: break cursor = body["meta"]["next_cursor"] return rows # Marca de agua ANTES de llamar, para no perder registros escritos durante la sync watermark = datetime.now(timezone.utc).isoformat() employees = sync("employees", since=load_last_watermark()) # incremental checkins = sync("check-ins", since=load_last_watermark()) save_watermark(watermark)

Toma la marca de agua antes de empezar la sincronización, no después. Así los registros escritos mientras corría el proceso entran en la siguiente pasada.

Recursos útiles para BI

RecursoAporta
work-summariesMétricas de jornada listas para agregación (horas, extra, nocturnas).
check-insGrano de evento para análisis de presencia y puntualidad.
absencesAbsentismo por tipo y período.
vacation-balancesSaldos y provisiones de vacaciones.
locations / unitsDimensiones para segmentar (centro, departamento).

Conexión desde Power BI

Power BI puede consumir la API directamente con Web.Contents y cabecera de autorización. Ejemplo simplificado en Power Query (M):

let BaseUrl = "https://api.kinmu.app/v1", ApiKey = "kinmu_sk_live_…", // usa Parámetros / almacén de credenciales, no lo escribas en claro Source = Json.Document( Web.Contents(BaseUrl, [ RelativePath = "work-summaries", Query = [ period = "month", from = "2026-01-01", #"to" = "2026-12-31", limit = "100" ], Headers = [ Authorization = "Bearer " & ApiKey, Accept = "application/json" ] ]) ), Data = Source[data], Table = Table.FromRecords(Data) in Table

Para paginar en Power Query, envuelve la llamada en una función que siga meta.next_cursor con List.Generate hasta que has_more sea false.

Respeta los límites de tasa: para volúmenes grandes, programa la actualización fuera de horas punta y vigila X-Kinmu-Quota-Remaining.

Alternativa event-driven

Si prefieres no hacer polling, suscríbete a webhooks (checkin.created, absence.approved, vacation_balance.updated, …) y actualiza tu almacén al recibir cada evento. Combina bien: webhooks para tiempo real + un polling nocturno con updated_since como red de seguridad.

Last updated on