Perfcopilot

Attendance

Attendance signals surface presence and schedule adherence data — in-office badge swipes, time-off records, and tracked working hours. Three providers are supported: Kisi (badge/door access), BambooHR (HRIS time tracking + approved PTO/sick/holiday), and Toggl (time tracking). You can connect more than one at a time — Kisi's badge swipes, BambooHR's PTO records, and Toggl's tracked hours are semantically additive (badge swipe ≠ PTO ≠ tracked time), so a multi-source org gets the union of all three sets of signals on every review cycle.

This integration is opt-in and attendance data does not influence reviews unless you explicitly weight it in the skill preset. Connecting it populates the signals dashboard, but the review AI ignores it unless attendance-related skills are weighted above zero.

What we pull

Each adapter produces a different shape of signal — they're stored as RawSignal rows with source="attendance" and a distinct event_type per source so they don't clobber each other on dedup:

  • Kisievent_type="office_day". One row per in-office day (earliest badge swipe collapsed). Includes minutes_late, on_time, scheduled_at_iso.
  • BambooHR clock-insevent_type="bamboohr_clock_in". Same arrival shape as Kisi, derived from the first timesheet entry of the day.
  • BambooHR time-offevent_type="pto_taken", sick_day, or holiday. One row per approved time-off request; pending requests are ignored. day_count captures the request's duration.
  • Togglevent_type="tracked_session". One row per time entry, with duration_seconds. Sum across the cycle yields tracked_hours.

The orchestrator runs all configured adapters concurrently for each employee. A failure in one adapter (e.g. Kisi returns 500) is logged and skipped — the other adapters' rows still get written. Per-adapter dedup is anchored to (cycle_id, event_type) so resyncing Kisi never wipes BambooHR's PTO rows, and vice versa.

Kisi (badge / door access)

Pulls access_granted events from the Kisi Events API for the employee's member ID. Each successful badge swipe at a configured entrance is treated as an arrival.

BambooHR

Pulls timesheet entries from BambooHR's time tracking endpoint (/employees/{id}/timesheet_entries). The start timestamp of each entry is used as the clock-in time. BambooHR's Goals integration shares the same API key but hits different endpoints — see BambooHR Goals.

Toggl

Pulls time entries from the Toggl Track API (/me/time_entries) using the employee's personal API token. The start field of each entry is used as the clock-in time.

Connecting

Attendance is an org-wide install.

Kisi

  1. Go to /admin?tab=integrations, find the Kisi card.
  2. Enter your Kisi API key (from Kisi Dashboard → Account → API). This authenticates via KISI-LOGIN <token>.
  3. Map each employee's Kisi member ID in the card's unmapped-employees list.

BambooHR

  1. Find the BambooHR card. If you already connected BambooHR for Goals, the same integration row is reused.
  2. Provide your API key and subdomain (the acme part of acme.bamboohr.com).
  3. Map each employee's BambooHR employee ID (numeric, visible in the employee's BambooHR URL).

Toggl

  1. Find the Toggl card.
  2. Each employee provides their personal Toggl API token (from Toggl → Profile → API token). Toggl's /me/time_entries endpoint is scoped to the authenticated user, so each employee's token can only pull their own data.
  3. Map each employee's Toggl user ID.

What hits a review

Attendance signals flow into the review prompt only if attendance-related skills are weighted above zero in the skill preset for that employee's role. When multiple sources are connected, the [ATTENDANCE DATA] block folds them together — empty buckets are dropped so an org with only Kisi never sees a misleading pto_days: 0:

[ATTENDANCE DATA]
in_office_days:           16
days_on_time:             14
days_late:                 2
on_time_rate:             88%
pto_days:                  2
sick_days:                 0
tracked_hours:           142.5
attendance_sources:       bamboohr, kisi, toggl

Troubleshooting

"Attendance signals show zero"

  1. No provider ID mapped. All three adapters filter by a provider-specific user ID. An unmapped employee returns nothing.
  2. Kisi entrance not configured. Kisi's API returns events for any configured access point. If the entrance your employees use isn't set up in Kisi or the API key doesn't have access to it, events won't appear.
  3. BambooHR Performance module not enabled. The timesheet endpoint is part of BambooHR's time tracking feature, which requires the Time Tracking add-on. Basic BambooHR accounts don't have access to this endpoint.

"minutes_late is way off"

The scheduled start time defaults to 9:00 AM UTC if no org timezone or per-employee schedule override is set. Go to Settings → Organization to set your timezone and default start time, then re-sync. Per-employee overrides are set in the employee's profile.

"I see arrivals but the review says nothing about attendance"

Attendance data only appears in reviews when the skill preset for the employee's role weights an attendance-related skill above zero. If your skill preset doesn't include attendance skills, the [ATTENDANCE DATA] block is excluded from the review prompt entirely. Check the employee's skill preset under Settings → Review templates.

Privacy notes

  • Attendance data is sensitive. PerfCopilot stores minutes_late and on_time per day — this information is visible to managers in the signals strip.
  • The integration is org-wide, meaning connecting it enables attendance tracking for all mapped employees. Employees who haven't been mapped are unaffected.
  • Attendance signals are designed for roles and cultures where schedule adherence is explicitly part of the job expectation. Using attendance data for employees on flexible schedules or fully async teams is not recommended and may produce misleading review content if weighted.