Sistema Biométrico de control de entradas y salidas — Guía para administradores de empresa
A la izquierda está el menú con las secciones de tu empresa:
En el Dashboard, con tu empresa seleccionada, vas a ver el QR que usan los empleados para fichar desde su celular.
En el Dashboard hay un bloque “Dispositivo Fijo de Registro” con un enlace para abrir en una PC o tablet fija dentro de la empresa: la cámara queda escaneando rostros y registra automáticamente. Ver Dispositivo fijo.
Un sector es un lugar de trabajo: una ubicación geográfica y un radio. Sirve para validar que el empleado esté en el lugar al fichar (geocerca). Los horarios ya no viven dentro del sector — ahora son un módulo aparte (ver Horarios) y se combinan con el sector al asignárselos a cada empleado.
Para fijar la ubicación de un sector desde el lugar real (por ejemplo, que un encargado la declare parado en el sitio), podés generar un link para que la marque desde su propio celular:
Con los botones de cada fila podés editar o eliminar/desactivar un sector.
Un horario es una plantilla de jornada con un nombre descriptivo (ej. “Turno mañana”, “Cocina partido”), un margen de gracia y, por cada día de la semana, uno o más tramos. Cada tramo se define con la hora de entrada y la cantidad de horas del turno; la hora de salida se calcula sola (entrada + duración).
El margen de gracia (por defecto 15 min, editable por horario) es la tolerancia en la entrada y en la salida: si el empleado llega o se va dentro de ese margen, no se cuenta como llegada tarde ni como horas extra. Recién fuera del margen se registra tarde (entrada) u horas extra (salida). Ver cómo impacta en Reportes.
Desde Editar empleado, en “Sectores / Horarios asignados”, combinás dónde y cuándo trabaja:
Si tildás “Puede registrar biometría sin estar en ningún sector”, el empleado (ej. un vendedor en lo del cliente) puede fichar aunque no esté dentro de ningún sector; se guarda igual la ubicación del fichaje. Si además asignás un sector sin horario, ese sector solo valida ubicación y alterna entrada/salida.
Si el empleado no está presente, mandale un link para que registre su rostro él mismo desde su celular:
Si un empleado dejó de ser reconocido (cambió mucho su aspecto, mala carga inicial, etc.), volvé a registrar su rostro desde el panel, o generale un nuevo link de empadronamiento. La nueva carga reemplaza la anterior.
Arriba en Empleados tenés el botón Ver horarios de empleados: abre una vista gráfica con, por cada empleado, sus sectores y horarios y la entrada/salida por día de la semana.
En Configuración Biometría ajustás la sensibilidad del reconocimiento. Si no estás seguro, dejá los valores recomendados.
Para un punto de fichaje fijo (PC/tablet en la entrada): abrí el enlace de dispositivo fijo del Dashboard. La cámara queda activa y va registrando a cada persona que se reconoce. No necesita que nadie apriete botones.
Al fichar dentro de un sector, el sistema mira el horario asignado a ese sector para ese empleado y elige el evento más cercano: si estás cerca de una entrada marca entrada; si estás cerca de una salida marca salida (contemplando turnos partidos y nocturnos). Si el sector no tiene horario asignado, alterna entrada/salida. Si ya existe un registro en ese tramo, te pide confirmar.
Al fichar por QR, el sistema verifica que el empleado esté dentro del radio de alguno de sus sectores asignados. Si está fuera y no tiene habilitado fichar sin sector, avisa y no registra. (El dispositivo fijo no usa geolocalización: se asume que está dentro de la empresa.)
Cada fichaje guarda una foto pequeña del momento, optimizada para ocupar poco espacio. La ves en el listado de Registros.
En Ver Registros tenés todos los fichajes. Filtrá por fecha desde/hasta, sector y empleado, y tocá Buscar.
La columna Foto muestra la miniatura del fichaje. Hacé clic en la miniatura para verla en grande.
Con los botones de cada fila podés editar la fecha/hora y el tipo (entrada/salida) , o eliminar el registro (pide doble confirmación).
Con los botones de exportación podés bajar los registros a Excel, PDF, CSV o imprimirlos.
En Reportes generás el detalle de un empleado en un rango de fechas: horas trabajadas, llegadas tarde, horas extra, faltas/ausencias y días trabajados, comparado con los horarios asignados.
Mientras Reportes te dice cuántas horas trabajó cada uno, Cómputo de Jornada te dice qué tipo de horas son: cuáles entran en la jornada normal, cuáles son extra y con qué recargo, y dónde se están pasando de los límites legales.
La columna Alertas marca los problemas del período. Desplegá el detalle para ver cuáles son:
En Reglas ajustás los valores para tu empresa: horas diarias y semanales, porcentajes de recargo, hora de corte del sábado, franja nocturna y descanso mínimo entre jornadas. Vienen configurados según la normativa argentina; cambialos si tu convenio dice otra cosa.
En Feriados cargás el calendario. Los días marcados como feriado se pagan con el recargo especial.
Responde una sola pregunta: ¿quién está adentro ahora mismo y en qué sector? Arriba vas a ver los contadores (dentro, fuera, sectores con gente) y abajo una tarjeta por sector con el nombre de cada persona, la hora en que entró y hace cuánto está.
Si alguien figura adentro desde hace más de 16 horas, casi seguro se olvidó de fichar la salida. El sistema lo muestra igual pero lo resalta en amarillo y avisa arriba. Conviene corregir esos casos (cargando la salida que falta) para que el tablero sea confiable.
El botón Imprimir genera una hoja limpia, solo con las listas por sector, para llevar al punto de encuentro y controlar quién falta.
Es la línea de tiempo completa de la empresa: los fichajes de los empleados y toda modificación hecha desde el panel (altas manuales, ediciones y eliminaciones), con quién la hizo, cuándo y por qué.
Sirve para responder preguntas del tipo "¿quién cambió este fichaje y con qué justificación?", tanto ante un reclamo de un empleado como ante una inspección.
Con este módulo activo, cada vez que edites, elimines o cargues un registro a mano, el sistema te va a pedir un motivo. No es opcional: sin motivo no se guarda el cambio.
Escribí algo que se entienda dentro de seis meses: "el empleado olvidó fichar la salida", "el lector estaba fuera de servicio", "fichaje duplicado por error".
En Ver Registros, los fichajes tocados a mano quedan identificados:
Permite que otro sistema (el de sueldos, un ERP, una planilla automatizada) consulte los datos de asistencia por su cuenta, sin que nadie exporte archivos a mano. Además puede avisar en el momento a un sistema externo cada vez que alguien ficha.
Es un texto largo con esta forma:
bio_k1a2b3c4d_e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0
Lo primero es confirmar que la clave anda. Abrí una terminal y pegá esto, reemplazando
TU_CLAVE:
curl -H "Authorization: Bearer TU_CLAVE" \
"https://relojbiometrico.sirobe.site/api/v1.php?recurso=sectores"
Si la clave es correcta, vas a ver un texto que empieza con {"recurso":"sectores"....
Si ves {"error":"clave_invalida"...}, revisá que la hayas copiado completa,
sin espacios de más.
https://relojbiometrico.sirobe.site/api/v1.phprecurso.Authorization: Bearer TU_CLAVE
También se acepta X-API-Key: TU_CLAVE, si a tu sistema le resulta más cómodo.| Recurso | Devuelve | Filtros que acepta |
|---|---|---|
registros | Los fichajes | desde, hasta, empleado_id, dni, limit, offset |
empleados | La nómina | limit, offset |
sectores | Sectores y su geocerca | — |
presentes | Quién está adentro ahora | — |
Es la consulta que más se usa. Por ejemplo, todo el mes:
curl -H "Authorization: Bearer TU_CLAVE" \
"https://relojbiometrico.sirobe.site/api/v1.php?recurso=registros&desde=2026-08-01&hasta=2026-08-31"
Y esto es exactamente lo que devuelve:
{
"recurso": "registros",
"total": 245,
"limit": 100,
"offset": 0,
"datos": [
{
"id": 167867,
"empleado_id": 11,
"dni": "25317962",
"nombre": "Simon",
"apellido": "Rodriguez beccar",
"tipo_registro": "salida",
"fecha_hora": "2026-08-15 10:24:54",
"sector_id": null,
"sector": null,
"dentro_rango": 0,
"latitud": "-40.21060500",
"longitud": "-71.30448440",
"observacion": null
}
]
}
Qué significa cada campo:
| Campo | Qué es |
|---|---|
total | Cuántos fichajes cumplen el filtro en total (no cuántos vinieron en esta respuesta) |
limit / offset | Cuántos trajo y desde cuál — se usan para paginar |
id | Identificador único del fichaje. Sirve para no procesar dos veces el mismo |
dni | La forma más práctica de cruzar con tu sistema de sueldos |
tipo_registro | entrada, salida o presencia |
fecha_hora | Fecha y hora del fichaje, en la hora local del sector |
sector | Nombre del sector. En null = fichó fuera de todo sector |
dentro_rango | 1 si estaba dentro del radio del sector |
Cada consulta devuelve como máximo 100 fichajes (podés pedir hasta 500 con
limit). Si total es mayor que lo que recibiste, hay más: se piden de a tandas
subiendo offset.
Por ejemplo, con 245 registros y tandas de 100:
...&limit=100&offset=0 → los primeros 100
...&limit=100&offset=100 → los siguientes 100
...&limit=100&offset=200 → los últimos 45
PHP — trae el mes completo, paginando solo:
<?php
$clave = 'TU_CLAVE';
$base = 'https://relojbiometrico.sirobe.site/api/v1.php';
$todos = [];
$offset = 0;
do {
$url = $base . '?recurso=registros&desde=2026-08-01&hasta=2026-08-31'
. '&limit=500&offset=' . $offset;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer ' . $clave]);
$respuesta = curl_exec($ch);
$codigo = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($codigo !== 200) {
echo "Error HTTP $codigo: $respuesta\n";
break;
}
$data = json_decode($respuesta, true);
$todos = array_merge($todos, $data['datos']);
$offset += 500;
} while ($offset < $data['total']);
echo "Trajimos " . count($todos) . " fichajes\n";
Python:
import requests
CLAVE = "TU_CLAVE"
BASE = "https://relojbiometrico.sirobe.site/api/v1.php"
cabeceras = {"Authorization": f"Bearer {CLAVE}"}
todos, offset = [], 0
while True:
r = requests.get(BASE, headers=cabeceras, params={
"recurso": "registros",
"desde": "2026-08-01",
"hasta": "2026-08-31",
"limit": 500,
"offset": offset,
}, timeout=30)
r.raise_for_status()
data = r.json()
todos += data["datos"]
offset += 500
if offset >= data["total"]:
break
print(f"Trajimos {len(todos)} fichajes")
Excel / Power Query — para llevarlo a una planilla sin programar:
https://relojbiometrico.sirobe.site/api/v1.php?recurso=registros&desde=2026-08-01&hasta=2026-08-31&limit=500Authorization,
valor Bearer TU_CLAVE.datos para ver los fichajes en filas.Empleados (?recurso=empleados) — para cruzar por DNI con tu sistema:
{
"recurso": "empleados",
"datos": [
{
"id": 26,
"dni": "2536",
"nombre": "Augusto",
"apellido": "Lacosta",
"email": "",
"telefono": "",
"activo": 1,
"sector_id": null,
"permite_sin_sector": 1,
"permite_presencia": 0,
"tiene_biometria": 1
}
]
}
Sectores (?recurso=sectores) — ubicación y radio de cada uno:
{
"recurso": "sectores",
"datos": [
{
"id": 13,
"nombre": "Casa Los Robles",
"descripcion": "",
"latitud": "-40.12386270",
"longitud": "-71.31864980",
"radio_metros": 50,
"timezone": "America/Argentina/Buenos_Aires",
"activo": 1
}
]
}
Presentes (?recurso=presentes) — quién está adentro en este momento.
tiene_biometria, si ya está empadronado o no.| Código | Qué significa | Qué hacer |
|---|---|---|
200 | Todo bien | — |
401 | Falta la clave o no es válida | Revisá el encabezado Authorization. Ojo con copiarla cortada |
403 | La clave fue desactivada, o la empresa no tiene el módulo | Consultá con el administrador |
404 | Ese recurso no existe | Revisá el nombre: son los cuatro de la tabla |
405 | Usaste POST u otro método | La API es de solo lectura: usá GET |
429 | Demasiadas consultas | Esperá un minuto (ver el límite abajo) |
500 | Error del servidor | Reintentá; si sigue, avisá al administrador |
Los errores también vienen en JSON, con una explicación en castellano:
{ "error": "limite_excedido", "mensaje": "Superaste el límite de 120 consultas por minuto." }
id del último fichaje procesado: así en la corrida
siguiente sabés desde dónde seguir y no repetís trabajo.Es el camino inverso: en vez de que consultes cada tanto, el sistema le avisa a tu servidor en el momento en que alguien ficha.
https://).Cada aviso llega con este contenido:
{
"evento": "fichaje",
"enviado_at": "2026-08-15T10:24:54-03:00",
"datos": {
"registro_id": 167867,
"empleado_id": 11,
"dni": "25317962",
"nombre": "Simon",
"apellido": "Rodriguez beccar",
"tipo_registro": "salida",
"fecha_hora": "2026-08-15 10:24:54",
"sector_id": null,
"sector": null,
"dentro_rango": false,
"origen": "qr"
}
}
Cómo verificar que el aviso es auténtico. Cada envío viene firmado en el
encabezado X-Biometria-Firma. Con el secreto que te da el administrador podés comprobar que
salió del sistema y no de un tercero:
<?php
$secreto = 'EL_SECRETO_DEL_AVISO'; // te lo da el administrador
$cuerpo = file_get_contents('php://input');
$firmaRecibida = $_SERVER['HTTP_X_BIOMETRIA_FIRMA'] ?? '';
$firmaEsperada = hash_hmac('sha256', $cuerpo, $secreto);
if (!hash_equals($firmaEsperada, $firmaRecibida)) {
http_response_code(401);
exit('Firma inválida');
}
$datos = json_decode($cuerpo, true);
// ... acá procesás el fichaje ...
http_response_code(200); // importante: responder 200 para que quede como entregado
echo 'OK';
registros una vez por día para cerrar los números.Esta sección explica todas las combinaciones posibles de configuración y qué pasa en cada una. Si alguna vez alguien te dice “no me deja fichar” o “fichó cuando no debía”, acá está la respuesta.
El sistema decide con tres cosas, y siempre en este orden:
Cuando alguien apoya la cara frente a la cámara, el sistema va pasando estos filtros. Si uno falla, ahí se corta:
| # | Control | Si falla |
|---|---|---|
| 1 | ¿El empleado está activo? | No lo reconoce (queda como “sin coincidencia”) |
| 2 | ¿Se reconoce el rostro? | “No se encontró coincidencia biométrica” |
| 3 | ¿Es un rostro real? (si está activo el control de vida) | “Parece una foto o pantalla” |
| 4 | ¿Está dentro de un sector? | Rechaza, salvo que tenga el permiso “sin sector” |
| 5 | ¿Está dentro del horario? | Rechaza, salvo que tenga el permiso “presencia” |
| 6 | ¿Ya fichó lo mismo en ese turno? | Pregunta si querés registrarlo igual |
“Sin permisos” significa los dos checkboxes desactivados.
| Configuración del empleado | Dónde está | Cuándo | Sin permisos | Con permisos |
|---|---|---|---|---|
| A · Sin ningún sector asignado | ||||
| Sin sector | Cualquier lugar | Cualquier hora | ✗ No puede fichar nunca | ✓ Ficha (queda “Fuera de sectores”) necesita “sin sector” |
| B · Con sector, SIN horario | ||||
| Sector sin horario | Dentro del radio | Cualquier hora | ✓ Ficha siempre, a cualquier hora | ✓ Igual |
| Sector sin horario | Fuera del radio | Cualquier hora | ✗ “Está fuera del rango” | ✓ Ficha sin sector necesita “sin sector” |
| Sector sin horario | Sin GPS (permiso denegado) | Cualquier hora | ✗ Rechaza | ✓ Ficha sin sector necesita “sin sector” |
| C · Con sector Y horario | ||||
| Sector + horario | Dentro del radio | Dentro del turno (± gracia) | ✓ Ficha. Entrada o salida según la mitad del turno | ✓ Igual |
| Sector + horario | Dentro del radio | Fuera del turno | ✗ “Fuera del horario asignado” | ⚠ Le pregunta: Entrada/Salida o Presencia necesita “presencia” |
| Sector + horario | Fuera del radio | Cualquier hora | ✗ “Está fuera del rango” | ✓ Ficha sin sector, sin control de horario necesita “sin sector” |
| D · Varios sectores | ||||
| Varios sectores (con o sin horario) | Dentro de uno | Según ese sector | Se toma el sector más cercano de los que lo contienen, y se aplica su horario | |
| Varios sectores | Fuera de todos | Cualquier hora | ✗ “Fuera del rango de todos los sectores” | ✓ Ficha sin sector necesita “sin sector” |
A · El empleado no tiene ningún sector. Sin el permiso “sin sector” no puede fichar nunca: el sistema lo reconoce, pero lo rechaza con “no está habilitado para registrar sin estar en un sector”. Es la causa más común de “me reconoce pero no me deja”. Con el permiso activado ficha desde cualquier lado, y el registro queda marcado como Fuera de sectores.
B · Sector sin horario. El único control es el geográfico: si está dentro del radio, ficha a cualquier hora, de día o de madrugada. Entrada y salida se alternan: si el último movimiento fue entrada, el siguiente es salida, y así. Es la configuración para gente sin horario fijo.
C · Sector con horario. Acá se aplican los dos controles. Dentro del sector y dentro del turno, el sistema decide solo si es entrada o salida: si estás en la primera mitad del turno es entrada, y en la segunda mitad es salida. El turno tiene un margen de gracia a cada lado: con un turno de 8 a 16 y gracia de 15 minutos, la ventana válida va de 7:45 a 16:15.
D · Varios sectores. Si el empleado está parado dentro de más de un sector a la vez (por ejemplo dos sectores que se superponen), se queda con el más cercano al centro. Y aplica el horario asignado a ese sector, no el de los otros.
Están en Empleados → Editar y cambian por completo el comportamiento:
| Permiso | Qué habilita | Cuándo conviene |
|---|---|---|
| Puede registrar biometría sin estar en ningún sector | Fichar desde cualquier lugar. Si está fuera de todo sector, el fichaje se guarda igual con la ubicación real y la leyenda Fuera de sectores. | Vendedores, personal de campo, gente que trabaja en lo del cliente. |
| Habilitar registro de presencia | Cuando está fuera de horario o fuera de sector, en vez de rechazarlo le pregunta si quiere marcar Entrada, Salida o Presencia (con una observación escrita). | Quien va fuera de su turno a hacer algo puntual y hay que dejar constancia. |
| Situación | ¿Puede fichar fuera de horario? |
|---|---|
| Sector sin horario asignado | Sí. No hay horario que controlar: ficha a cualquier hora |
| Sector con horario, sin permiso de presencia | No. Rechaza con “fuera del horario asignado” |
| Sector con horario y con permiso de presencia | Sí, pero le pregunta primero: puede marcar Entrada, Salida o Presencia |
| Fuera del sector, con permiso “sin sector” | Sí. Al no haber sector, no se controla horario |
| El horario existe pero está desactivado | Sí. Un horario desactivado es como no tener horario |
Si en el mismo turno ya hay una entrada y vuelve a fichar entrada, el sistema no lo bloquea: muestra el registro anterior y pregunta si querés guardarlo igual. Sirve para el caso real de alguien que sale y vuelve a entrar. Si confirma, quedan los dos registros.
No se comportan igual, porque el dispositivo fijo no tiene GPS:
| QR en el celular | Dispositivo fijo | |
|---|---|---|
| Ubicación | La del celular del empleado | No tiene. Se asume que está en el sector donde está la tablet |
| Empleado con varios sectores | Detecta en cuál está | No puede saberlo: lo rechaza y pide usar el QR |
| Control de horario | Sí | Sí |
| Repetir fichaje | Pregunta y deja confirmar | Espera 5 minutos antes de volver a tomar a la misma persona |
Es la parte que más confusión genera. Los tres tipos de registro no valen lo mismo:
| Tipo | En Reportes y en Cómputo de jornada |
|---|---|
| Entrada | Abre la jornada. Cuenta para las horas trabajadas |
| Salida | Cierra la jornada. Recién ahí se computan las horas |
| Presencia | No suma horas ni abre ni cierra jornada. Queda como constancia de que la persona estuvo, con su observación, pero no entra en el cálculo |
Y sobre los fichajes sin sector:
El navegador debe tener permiso de cámara. En el celular, usá el navegador por defecto (Chrome/Safari) y aceptá el permiso. El enlace debe abrirse con https.
El empleado no está dentro del radio del sector. Verificá la ubicación del sector y el radio (Sectores → Editar), o usá el link de ubicación para fijar la posición correcta.
Probá con mejor iluminación. Si sigue sin reconocer, reempadroná el rostro. También podés ajustar la sensibilidad.
Revisá el horario asignado al empleado en ese sector (Empleados → Editar → Sectores/Horarios) y el margen de gracia. La entrada/salida y los cálculos salen de esa combinación.
Cada link (de ubicación o de empadronamiento) sirve una vez. Generá uno nuevo desde el listado correspondiente.
No es un error: la empresa tiene activo el Historial de movimientos y todo cambio manual tiene que quedar justificado. Escribí el motivo y guardá con normalidad.
Casi siempre son fichajes sin la salida correspondiente: esas jornadas no computan horas. Desplegá el detalle del empleado con el botón +, buscá las filas marcadas como sin salida y corregilas con una carga manual.
Se olvidaron de fichar la salida. Los casos de más de 16 horas aparecen resaltados en amarillo. Cargá la salida que falta para que el tablero vuelva a reflejar la realidad.
Son módulos: aparecen solo si están contratados. Pedíselo al administrador del sistema.