Recibe tu plantilla
Tu programa envía sus centros y sus personas, completos la primera vez y solo los cambios después. Repetir un envío no duplica nada, y cada registro se acepta o se rechaza por separado, con el motivo.
Para programas de gestión
Dilu registra quién entra y quién sale. Tu programa recibe esos fichajes y, si quiere, nos envía su plantilla de centros y personas. Sin copiar datos a mano y sin tocar el registro.
Qué ofrece
Dilu es siempre el registro oficial. Tu programa no escribe fichajes: los recibe, y a cambio puede mantener al día la plantilla.
Tu programa envía sus centros y sus personas, completos la primera vez y solo los cambios después. Repetir un envío no duplica nada, y cada registro se acepta o se rechaza por separado, con el motivo.
Una lista ordenada de entradas, salidas, correcciones y cierres de día de tus centros. Pides «lo nuevo desde aquí» y, aunque pases días sin preguntar, te pones al día sin perder nada.
Si prefieres no emparejar entradas y salidas tú, pides un día de un centro y recibes los intervalos de cada persona y su total, calculado al momento.
Cómo se conecta
No hay cuentas de desarrollador ni claves que copiar y pegar. Cada empresa conecta cada programa por su cuenta, y puede desconectarlo cuando quiera.
Desde su móvil, en Ajustes → Enlaces → Nuevo enlace, y con su PIN. Le sale un código de 12 caracteres que vale 15 minutos y una sola vez.
Alguien escribe el código en tu programa, que lo cambia por un token. El token se ve una única vez: guárdalo cifrado. Solo abre los datos de esa empresa.
Tu programa envía su plantilla y, cada pocos minutos o cada día, pide los fichajes nuevos con un cursor. El dueño ve en Dilu qué se ha recibido y qué hay que revisar.
Si se pierde el token o se reinstala el programa, el dueño pide un código nuevo y el anterior deja de valer al instante. El código no debe mandarse nunca por correo: es una llave durante 15 minutos.
Cómo se usa
Todas las rutas empiezan por /v1/. Las claves van en inglés y en snake_case, las fechas en formato ISO 8601 con su zona horaria, y los identificadores que tú nos das (external_id) son siempre texto. Después del canje, cada llamada lleva Authorization: Bearer <token>.
| Llamada | Para qué sirve |
|---|---|
| POST /v1/link | Cambia el código del dueño por tu token (sin token todavía). |
| GET /v1/link | Comprueba la conexión y lista tus centros. |
| POST /v1/roster | Envía centros y personas: completo, o solo lo que cambió. |
| GET /v1/imports/{id} | Consulta el resultado de un envío grande. |
| GET /v1/events?since=&limit= | Fichajes, correcciones y cierres de día de tus centros, con cursor. |
| GET /v1/workdays?site=&business_date= | Un día de un centro con los intervalos emparejados y el total de cada persona. |
| GET /v1/schemas/roster | Los esquemas JSON públicos (roster, events, workdays), sin token. |
POST /v1/link
{ "code": "K7QM-2XD9-RW4T", "system": "Mi programa 1.0" }
201 Created
{
"schema_version": "1.0",
"token": "17|aB3dE5gH7jK9mN1pQ3sT5vW7yZ9bD1fG3hJ5kL7n",
"link": { "id": "0b6f1c1e-…", "name": "Mi programa" },
"company": { "legal_name": "Bar La Plaza S.L." }
}
El token solo sale en esta respuesta. El código se puede escribir en minúsculas, con espacios o sin guiones.
POST /v1/roster
Idempotency-Key: 6f1c8a2e-9b0d-4a77-8b5e-1d2c3b4a5f60
{
"schema_version": "1.0",
"sync_type": "full",
"sites": [
{ "external_id": "C-01", "name": "Local Centro", "address": "Calle Ejemplo 1, Gijón",
"timezone": "Europe/Madrid", "cutoff_time": "09:00" }
],
"employees": [
{ "external_id": "123", "first_name": "Nombre", "last_name": "Apellidos",
"id_document": "12345678Z", "site_external_ids": ["C-01"] }
]
}
200 OK
{ "schema_version": "1.0",
"import": { "id": "5d1c0b12-…", "status": "done", "sync_type": "full",
"counts": { "created": 2, "updated": 0, "unchanged": 0, "rejected": 0, "needs_review": 0 },
"sites": [ { "external_id": "C-01", "result": "created" } ],
"employees": [ { "external_id": "123", "result": "created" } ] } }
Cada registro responde por separado: created, updated, unchanged o rejected (con motivo). Con más de 100 registros la respuesta es 202 y el resultado se consulta después. Si una persona ya trabajaba en Dilu con el mismo DNI o NIE, se enlaza esa en lugar de crear otra.
GET /v1/events?since=1&limit=500
200 OK
{
"schema_version": "1.0",
"events": [
{ "sequence": 4813, "id": "7c1f4b9e-…", "event_type": "clock_event.recorded",
"site_external_id": "C-01", "employee_external_id": "123",
"business_date": "2026-10-10", "type": "in",
"time": "2026-10-10T20:01:12+02:00", "method": "pin",
"offline": false, "forgotten": false, "corrects_id": null },
{ "sequence": 4814, "id": "2a9d3c6e-…", "event_type": "business_day.closed",
"site_external_id": "C-01", "business_date": "2026-10-10",
"closure_type": "manual", "time": "2026-10-11T03:12:40+02:00", "open_count": 0 }
],
"next": 4815,
"has_more": false
}
Reglas del juego
Repetir un envío no duplica nada, y con Idempotency-Key un corte de red no se convierte en un envío doble. Los errores tienen todos la misma forma y un code que no cambia.
60 lecturas y 10 envíos por minuto en cada enlace, hasta 5 000 registros y 2 MB por envío. Si te pasas, la respuesta dice cuándo volver a intentarlo.
Todo lo que ves aquí es la versión 1. Añadir campos no la rompe (ignora los que no conozcas); un cambio que rompa algo será la versión 2.
Los esquemas JSON de lo que la API acepta y devuelve son públicos: https://app.dilu.es/v1/schemas/roster, …/events y …/workdays. La guía paso a paso y un cliente de ejemplo en Python se entregan con el acceso de pruebas.
Hablemos
Cuéntanos cuál es y qué necesitas (recibir fichajes, enviar plantilla, o las dos cosas). Te damos acceso de pruebas y resolvemos las dudas técnicas.
Dilu es un registro de jornada: no gestiona horarios, saldos de horas, vacaciones ni nóminas. Eso lo hace tu programa; nosotros nos ocupamos de que lo fichado sea fiable.