Biotime Reference Public

Administration

Administering the ERPat Biotime module: the seventeen permissions and what each grants, every setting with its default and clamp, the attendance-import controls, the two scheduled jobs, retention windows and the module's security posture.

Guide version: r4 Module version: 1.8.0 Updated: 2026-09-02 Estimated time: 12 min 7 views 0% helpful

Administration

Permissions, settings, scheduled jobs, retention and the security posture — everything an administrator owns.

Permissions

Seventeen permissions, deliberately fine-grained. The separations that matter: reading attendance does not imply changing the server connection, watching a sync does not imply starting one, running a sync does not imply creating attendance records, managing a connection does not imply being able to enter its password, and reading a row's remarks does not imply being able to write them.

PermissionGrants
BiotimeBase access and the dashboard. Without it the module is invisible and its pages unreachable.
Employees & BindingsView mirrored personnel and their match state.
Bind / unbind employeesChange who a BioTime employee maps to; run the bulk accept.
Attendance transactionsView mirrored punches.
DevicesView mirrored terminals.
OrganizationView departments, positions, areas and locations.
Add / edit remarksWrite a free-form note on a mirrored department, position, area, location, device or employee. Reading remarks is covered by the page's own permission, and a sync never changes a note.
AnalyticsView trends and breakdowns.
View sync historyOpen the Sync Center and read past runs.
Run a syncStart a sync. Separate from viewing, because starting one reaches an external server and consumes its rate limit.
Import punches into ERPat attendanceTurn mirrored punches into attendance records. Deliberately not implied by running a sync: mirroring reads a remote server, importing writes into ERPat's own payroll-facing attendance table.
View API logsSee the record of calls made to the BioTime server.
View raw API payloadsSee the stored response excerpt behind a log entry. Separate, because a raw payload can hold more of the remote record than the listing shows.
Export mirrored dataDownload attendance data.
Biotime settingsOpen the settings page.
Manage connectionsAdd, edit and delete server connections.
Enter / rotate BioTime credentialsSupply or change the BioTime password. Deliberately not implied by managing connections.

Settings

Six tabs under Biotime → Settings. Every numeric setting is clamped on save — an out-of-range value is corrected rather than stored, and read back with the same bounds.

Sync & retention

SettingDefaultRangeNotes
Run the sync automaticallyOnTurns the scheduled job on or off without disabling the module.
Overlap window (minutes)101–120How far before the last seen punch each run re-reads, so a late upload is never skipped.
Rows per page20010–500How many records are requested per API call.
First-run window (days)301–365How far back the very first sync reaches. Full backfill is a separate, explicit action.
Maximum pages per tick51–50Work done per request. Higher is faster but each request runs longer.
Keep API logs for (days)301–365Pruned nightly.
Keep sync runs for (days)901–730Pruned nightly.
Keep transactions for (days)00–36500 means keep forever. Setting a window prunes older punches; the daily analytics rollup survives.

Binding

SettingDefaultNotes
Match employees automaticallyOnRuns the matching pass as part of a sync.
Match on ERPat ID numberOnThe primary rule: BioTime employee code against the ERPat ID number.
Offer name-similarity suggestionsOnSuggestions only — never applied automatically.
Write a canonical Kiosk enrollment rowOnOnly does anything when the Kiosk module is present. Writes under a dedicated enrollment label for this connection, never the shared wildcard.

Attendance import

Off by default, and additionally inert while the Human Resource module is switched off — the records it creates land in HR's Attendance screen, so there is nowhere for them to go without it.

SettingDefaultRangeNotes
Create ERPat attendance from punchesOffThe master switch. Every other Biotime setting governs reading a remote server; this one writes into ERPat.
Import automatically after each syncOffWhen off, the import only runs when somebody starts it from the Sync Center.
New shift after a gap of (hours)61–12Consecutive punches more than this far apart start a new shift. Also the wait before a shift is imported — see the note below.
Ignore repeat taps within (seconds)600–600A second tap this soon after the first is the same arrival. 0 disables it.
Maximum shifts per batch10010–500Work done per request. Higher finishes a backfill in fewer batches but each request runs longer.
Import a lone punch as an incomplete recordOffBest left off. A shift with one punch has no clock-out, and ERPat treats any record without one as still open — so it blocks every later shift for that employee from importing, and the auto-clockout job closes it as "System Clockout" within hours. Measured on a real feed, switching it on cost about a quarter of the records.
Close a shift at its scheduled endOffWhen on, a shift whose last punch is at or after the day's scheduled time out is written once the grace below has passed, instead of waiting the full gap. Needs a schedule with a fixed time out: flexible schedules, rest days, no schedule, a single punch, or a last punch before the scheduled end all keep the normal gap rule. A punch arriving after the record was written still extends it in place.
Grace after the scheduled end (minutes)00–720How long after the scheduled time out to wait before writing the shift. 0 writes it at the scheduled end; 150 waits two and a half hours so overtime and straggler taps land in the record instead of each becoming a separate correction. Whole minutes; never lengthens the wait beyond the gap rule.
Import in-progress shifts before clock outOffWhen on, an employee's clock in and breaks appear in ERPat while they are still at work, as an incomplete record with no time out that each new punch extends until the clock out finishes it. A lone clock in is enough to open it. Only for employees on a schedule with a fixed time out, and only while their last punch is still before that time out — after it, a punch may be the clock out, so the normal rules take over. Also closes shifts at their scheduled end, exactly as the switch above does, whether or not that one is on; see the warning below for why that is a requirement rather than a convenience.
Auto-fix double tap on clock inOffKeeps the first punch of a shift as the time in and discards repeat taps that follow it within the window below. The punch is not deleted — it stays on the record, labelled "Double tap".
Clock-in window (minutes)151–120Measured from the first punch, not the previous one, so 8:00 / 8:07 / 8:12 with a 10-minute window keeps 8:12 — twelve minutes in is a plausible first break, not a fumbled badge.
Auto-fix double tap in breaksOffDiscards a repeat tap on a break, and one made just before clocking out. The clock-out itself is always kept: somebody who taps at 17:00 and again at 17:03 left at 17:03, and without this the 17:00 tap is left behind as a break that never ends.
Break window (minutes)51–120Raise this carefully. Too far and genuine short breaks are erased, which pays people for time they did not work. On a real 219-shift feed, break gaps clustered at 1–5 minutes (re-taps) and again at 11–60 (real breaks), so 5 takes the first cluster and stops short of the ambiguous 6–10 band.
Why a double tap does more damage than it looks. Punches are paired by position — the first is the time in, the last is the time out, and the ones between alternate break-out and break-in. So a stray tap does not simply add noise, it pushes every later punch into the wrong slot. A re-tap at 8:07 after clocking in at 8:00 becomes a break that runs until lunch, and a full morning is paid as a four-hour break. The "ignore repeat taps" setting above cannot catch it: it works in seconds and runs before punches are grouped into shifts, so it has no idea which punch is the clock-in.

Both switches are off, and you do not have to guess. While they are off the import still counts what it would have changed and reports it in the Sync Center console and the batch audit entry, without writing anything. Run a sync, read the count, then decide. To repair records imported before you switched them on, tick Re-check imported records for double taps in the Sync Center.
Nothing is imported until the gap has elapsed. With the default 6 hours, a 17:00 clock-out becomes an attendance record that evening, not immediately. That delay is what keeps a shift whole: importing at 08:00 would consume the clock-in and leave the evening clock-out with no shift to join. Since 1.7.0, Close a shift at its scheduled end shortens that wait for employees on a fixed schedule — the shift is written once the scheduled time out (plus any grace) has passed, provided the last punch reached it. Since 1.8.0, Import in-progress shifts before clock out removes the wait entirely for those employees: the record appears while they are still at work.
Before you switch on in-progress imports. The record it creates has no time out yet, and ERPat treats any attendance record without a time out as that employee's live clock in — so it will show that way on their dashboard, and if they clock out in ERPat themselves, that is the time that sticks (their remaining punches are then set aside for review rather than overwriting it).

This is why the setting also closes shifts at their scheduled end. An open record is exactly what the HR auto-clockout job looks for: once one is older than the auto-clockout trigger — 12 hours after clock in by default — that job closes it with a time of its own. Waiting the full gap would let it reach a normal 08:00–17:00 day first and the real clock out would then be refused, so the importer finalizes at the scheduled end instead, hours ahead of it. Two cases still end with the job winning, both harmless but worth recognising: an early leaver, whose last punch falls before their scheduled time out and whose record therefore waits for the gap rule; and a clock in that never receives another punch, which is closed to a zero-length record — the same outcome as "import a lone punch", but far more common with this on.

It costs more work per batch. Every punch that arrives is one more correction, each with its own entry in the record's history. Where a whole shift clocks in at once, raise Maximum shifts per batch.

Display & advanced

SettingDefaultNotes
Show capture photosOffCapture photos are images of employees. Opt in deliberately.
Show body temperatureOffHealth data. Additionally inert on cloud servers, whose feed carries no such field.
Dashboard range (days)71–90.
Default connectionWhich connection the pages read when more than one exists.
Allow private / internal hostsOffOn-premises servers only. See the security note below.

Scheduled jobs

JobScheduleWhat it does
Biotime — incremental sync
biotime_sync
Every 15 minutes Mirrors new data from each active connection, resuming from the stored cursor. Does nothing when the module is off or automatic sync is disabled. When automatic attendance import is also on, the same job turns bound punches into pending attendance records.
Biotime — retention & analytics refresh
biotime_retention
Daily, 02:30 Prunes API logs, sync runs and (if configured) old punches, then refreshes the daily analytics rollup.
The retention job refreshes the rollup only for days whose punches still exist. Purging raw attendance therefore never erases your historical daily totals — which is the entire reason the rollup is kept separately.

Security posture

Credentials

  • The BioTime password is encrypted at rest with AES-256-GCM, using the key in BIOTIME_ENCRYPTION_KEY. Access and refresh tokens are encrypted the same way.
  • Each encrypted value is bound to the connection row and the field it belongs to, so a stored secret copied into another row or another field simply will not decrypt.
  • A credential is only stored after a real sign-in succeeds. There is no path that saves an unproven password.
  • Passwords, tokens and authorization headers are stripped from every stored error message and log excerpt. API log paths are stored without their query strings.
  • Repeated credential failures temporarily lock a connection. Network problems and server errors deliberately do not count toward that — otherwise one bad afternoon on the network would lock every connection.

Outbound requests

  • The server address is re-resolved and re-checked before every single request, including from the scheduled job, and the connection is pinned to the approved address. A single check at setup time can be defeated by changing DNS afterwards.
  • Loopback, link-local and cloud-metadata addresses are refused unconditionally.
  • Allow private / internal hosts widens this to ordinary LAN ranges, applies only to the on-premises profile, and is off by default. It is a security decision, not a convenience toggle.
  • Redirects are never followed, and response size is capped.
There is no “ignore TLS errors” switch anywhere in this module, and there is no plan to add one. Certificate and hostname verification cannot be disabled by a tenant.

What is never collected

  • Biometric templates are never mirrored. Fingerprint and face data stay on your BioTime server. Only enrollment counts are copied.
  • Capture photos and body temperature default to off. Both are personal data and require a deliberate decision.
  • The integration API never exposes credentials, tokens, or the raw remote record.

The integration API

Seven read-only endpoints under /api/v1/biotime/*, requiring the biotime:read scope. Grant it in Settings → API Access like any other scope. A token with the scope still receives a 404 on a tenant where the Biotime module is switched off.

There is no write scope — the module is a read-only mirror, so there is nothing for a machine to contribute. Endpoint details are in Reference.

Audit trail

These actions are recorded in ERPat's audit log: creating, updating and deleting a connection; rotating a credential (the fact, never the value); running a connection test; changing settings (only the keys that actually changed); creating, changing and removing a binding; starting a sync; and importing attendance. Bulk acceptance writes one entry per batch rather than one per employee.

Attendance import writes at two levels, because they answer different questions:

EntryWrittenAnswers
Biotime attendance importedOnce per batchWhat did this sync do? — records created, updated, skipped, failed.
Attendance added / updated from BioTimeOnce per recordWhere did this record come from? Filed against the record itself, so it appears in its Log Details history — the screen an approver is already on.
A scheduled import is recorded as performed by System, because cron has no signed-in user. An import somebody starts from the Sync Center names them.
Was this guide helpful?

Report a content problem