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