Cambios en la API pública de Crehana.

Eliminar una solicitud de tiempo libre

DELETE /org/{slug}/timeoff/requests/{request_id}/ elimina una solicitud de ausencia de la organización. La solicitud deja de aparecer en GET /org/{slug}/timeoff/requests/ y el tiempo que consumía vuelve al saldo del colaborador.

Con una credencial de administrador de la organización —así se crean las api-key— podés eliminar cualquier solicitud y en cualquier estado. Si la credencial corresponde a un colaborador, sólo puede eliminar las solicitudes propias y sólo mientras sigan pendientes; en el resto de los casos la respuesta es 403 Forbidden.

Una baja correcta responde:

1{
2 "success": true,
3 "message": "Time off request deleted correctly.",
4 "code": "timeoff-001",
5 "datetime": "2026-08-19T14:48:58.833958",
6 "data": { "request_id": "531" }
7}

La respuesta distingue el motivo del rechazo:

SituaciónStatus
Solicitud eliminada200 OK
La solicitud no existe404 Not Found
Sin permiso sobre esa solicitud403 Forbidden
Ya estaba eliminada, o ya fue aprobada o denegada409 Conflict

Reintentar es seguro: un segundo DELETE sobre la misma solicitud responde 409 y no vuelve a tocar el saldo.

Los reportes de asistencia se pueden consultar por API

Los cuatro seguimientos del producto Asistencia —los mismos que hasta ahora solo se podían bajar en Excel desde el panel— ya están disponibles como endpoints paginados:

EndpointQué devuelveUna fila es
GET /org/{slug}/reports/attendance/shifts/Creación de turnosun turno configurado
GET /org/{slug}/reports/attendance/shifts-schedule/Programación de turnosuna asignación vigente de turno a un colaborador
GET /org/{slug}/reports/attendance/marks/Recepción de marcasuna marca individual
GET /org/{slug}/reports/attendance/daily-management/Gestión diaria de marcasun colaborador en un día

Los cuatro responden { "total": N, "results": [...] } y aceptan limit (hasta 500), pero paginan de dos maneras distintas según el volumen del reporte:

  • Turnos y programación usan offset, como el resto de los reportes.
  • Marcas y gestión diaria usan cursor. La respuesta trae next_cursor y has_next_page; para la página siguiente reenviás ese next_cursor tal cual, sin interpretarlo. Estos dos no aceptan offset: si lo mandás la respuesta es 400, para que no recibas siempre la primera página creyendo que avanzás. La paginación es solo hacia adelante — no hay cursor previo. El detalle está en Paginación.

El rango de fechas es obligatorio en marcas y en gestión diaria, con una ventana máxima de 31 días: son los dos reportes de mayor volumen y sin acotar el período una sola consulta puede recorrer millones de registros. Si faltan from_date o to_date, o el rango es más ancho que 31 días, la respuesta es 400 Bad Request indicando el campo. En turnos y programación el rango es opcional.

En shifts-schedule, marks y daily-management podés filtrar por colaborador con centralized_user_id.

centralized_user_id es el identificador centralizado del colaborador, que no es el mismo que el user_id de los reportes de learning: para la misma persona son números distintos. Si mandás el equivocado vas a recibir 200 con results vacío, no un error.

Tres diferencias a propósito respecto del archivo de Excel:

  • Los campos de tipo catálogo no vienen traducidos. mark_type, source, classification, day_status y shift_type devuelven el valor tal como lo emite el motor de asistencia (entry, APP, late, rotating), no la etiqueta en español que ves en el Excel. Es lo que te permite mapearlos de forma estable: la etiqueta puede cambiar, el valor no. days también va en inglés y ordenado de lunes a domingo (monday, friday); en turnos rotativos es el ciclo 5 work / 2 rest.
  • El estado de un turno y el indicador de feriado son booleanos (true / false), no los textos “Activo”/“Inactivo” ni “Sí”/“No”.
  • Las duraciones de la jornada (worked_minutes, tardiness_minutes, overtime_minutes) vienen en minutos como número entero, listas para sumar, en vez del formato hh:mm.

day_status es el único que no es homogéneo en el origen: cuatro de sus valores llegan en español (feriado, dia_descanso, feriado_trabajado, dia_descanso_trabajado) y el resto en inglés (ok, justified, unjustified_absence, incomplete, with_novelty, no_shift). Se exponen tal como llegan, sin traducir ni retraducir: tratalos como identificadores opacos.

Los datos se consolidan con un corte periódico, así que reflejan la información procesada hasta ese corte y no el marcaje del minuto anterior.