People Operations Dashboard
Purpose
This recipe produces a startup people operations dashboard that integrates with the HRIS (BambooHR, Rippling, or Gusto) and ATS (Greenhouse, Lever, or Ashby), displays an interactive org chart, tracks compensation against bands, monitors turnover and retention metrics, visualizes the recruiting pipeline, and shows onboarding progress for new hires. The output is a deployed internal tool giving founders and People leads a single view of workforce health. [src3]
Prerequisites
- HRIS system with API access — BambooHR or Rippling with API key or OAuth2 configured
- ATS system with API access — Greenhouse or Lever with API key configured
- At least 3 months of employee data in the HRIS — required for turnover trend analysis; 12+ months for annualized rates
- Compensation bands or salary budget — by role, level, and department
- PostgreSQL database — free tier at Supabase or Neon
- Dashboard tool account — Retool or Metabase
- Onboarding checklist template (optional) — task list per role for 30/60/90-day onboarding
Constraints
- HRIS API rate limits: BambooHR throttles at ~100 requests/minute; Greenhouse Harvest API allows 50 requests/10 seconds. Cache employee roster daily. [src1]
- Compensation data must be restricted to People team + CEO only. Never show individual salaries in department-wide views — use band position percentiles instead. [src3]
- ATS candidate data subject to GDPR (EU) and CCPA (CA). Anonymize rejected candidate records after 6 months or per retention policy. [src2]
- Turnover rate calculation requires 12+ months for annualized accuracy. For startups under 50 employees, show rolling 6-month rate with confidence warning. [src4]
- Org chart visualization breaks at ~200 nodes in browser-rendered SVG/canvas trees. Use collapsible hierarchy with department-level drill-down for larger orgs.
Tool Selection Decision
Which path?
├── User is non-technical AND budget = free
│ └── PATH A: No-Code Free — Google Sheets + manual HRIS/ATS export
├── User is non-technical AND budget > $0
│ └── PATH B: No-Code Paid — Retool + Supabase + Merge HRIS ($300/mo)
├── User is semi-technical or developer AND budget = free
│ └── PATH C: Code + Free — Metabase + PostgreSQL + cron sync scripts
└── User is developer AND budget > $0
└── PATH D: Code + Paid — Retool + PostgreSQL + n8n + direct APIs
| Path | Tools | Cost | Speed | Output Quality |
|---|---|---|---|---|
| A: No-Code Free | Google Sheets + CSV exports | $0 | 3-4 hours | Basic — manual weekly updates |
| B: No-Code Paid | Retool + Supabase + Merge | $300/mo | 5-7 hours | Good — auto-sync, interactive |
| C: Code + Free | Metabase + PostgreSQL + cron | $0 | 8-10 hours | Good — full SQL control |
| D: Code + Paid | Retool + PostgreSQL + n8n | $25-50/mo | 6-8 hours | Excellent — real-time, custom |
Execution Flow
Step 1: Design the People Data Model
Duration: 30-60 minutes · Tool: SQL client
Create the 5-table schema: employees (with manager hierarchy), compensation (with band tracking), recruiting_pipeline (with stage tracking), onboarding_tasks (with 30/60/90-day phases), and headcount_snapshots.
Verify: All 5 tables created successfully. If failed: Check PostgreSQL connection and permissions.
Step 2: Build HRIS/ATS Data Sync
Duration: 1-2 hours · Tool: n8n, custom script, or Merge API
Connect to BambooHR or Rippling API using API key/OAuth2. Extract employee directory and compensation data, upsert to employees and compensation tables. Connect to Greenhouse or Lever API, extract active applications and pipeline data. Schedule daily HRIS sync at 6:00 AM, hourly ATS sync.
Verify: SELECT department, COUNT(*) FROM employees WHERE status='active' GROUP BY department; matches HRIS headcount. If failed: Check API key permissions — BambooHR requires "API Access" level, Greenhouse requires Harvest API key type.
Step 3: Build People Analytics Queries
Duration: 1-2 hours · Tool: SQL
Write 5 core analytics queries: headcount by department with growth trend and turnover rate, compensation band analysis (anonymized percentile positions), recruiting pipeline funnel with conversion rates and source attribution, time-to-hire by department, and onboarding completion rate with overdue task flagging.
Verify: Headcount query returns departments with non-zero counts. Pipeline funnel shows descending candidate counts. If failed: Check employee status field mapping and ensure terminated employees have termination_date set.
Step 4: Assemble the Dashboard UI
Duration: 1-2 hours · Tool: Retool or Metabase
Build 6-section layout: KPI row (Headcount, Open Roles, Turnover %, Avg Time-to-Hire, Onboarding Completion), org chart with collapsible hierarchy, recruiting pipeline funnel, headcount trend stacked area chart, compensation band box plots by level, and onboarding Kanban board.
Verify: All 6 sections render. Headcount matches HRIS. If failed: Check query bindings and data source connections.
Step 5: Configure People Alerts
Duration: 30-60 minutes · Tool: n8n or Pipedream + Slack/Email
Set up weekly alerts for: turnover above 15% annualized, stale pipeline candidates (14+ days without stage change), overdue onboarding tasks, and compensation band violations.
Verify: Test alert fires in Slack/email with sample data. If failed: Check webhook URL and workflow execution.
Step 6: Deploy and Share Access
Duration: 30 minutes · Tool: Dashboard platform settings
Share full dashboard with CEO and Head of People. Create restricted view (no compensation data) for department managers. Set recruiter-only view for pipeline tracking. Enable weekly email digest for hiring managers.
Verify: CEO sees all sections. Department managers cannot see compensation data.
Output Schema
{
"output_type": "people_operations_dashboard",
"format": "deployed web application",
"components": [
{"name": "headcount_by_department", "type": "chart", "description": "Stacked area chart of headcount by department over time", "required": true},
{"name": "org_chart", "type": "visualization", "description": "Interactive collapsible org tree by manager hierarchy", "required": true},
{"name": "recruiting_funnel", "type": "chart", "description": "Horizontal funnel showing candidates by pipeline stage with conversion rates", "required": true},
{"name": "compensation_analysis", "type": "chart", "description": "Box plots showing salary distribution vs band by role level", "required": true},
{"name": "onboarding_tracker", "type": "kanban", "description": "New hire onboarding progress by 30/60/90-day phase", "required": true},
{"name": "kpi_cards", "type": "metrics", "description": "Headcount, open roles, turnover %, avg time-to-hire, onboarding completion", "required": true}
],
"refresh_interval": "daily (HRIS sync) + hourly (ATS pipeline)",
"data_source": "PostgreSQL synced from HRIS and ATS"
}
Quality Benchmarks
| Quality Metric | Minimum Acceptable | Good | Excellent |
|---|---|---|---|
| Data freshness | < 48 hours lag | < 24 hours | Same-day sync |
| Headcount accuracy | Within 2 of HRIS | Exact match | Real-time match |
| Pipeline coverage | Active candidates only | All open roles | + historical hires |
| Comp data completeness | Base salary only | + equity + bonus | Full comp package + bands |
| Onboarding tracking | Manual checklist | Automated task tracking | + manager feedback + NPS |
If below minimum: Check HRIS/ATS API sync logs. Headcount discrepancies usually mean contractor/intern exclusion or delayed termination processing.
Error Handling
| Error | Likely Cause | Recovery Action |
|---|---|---|
| BambooHR API 401 | API key revoked or insufficient permissions | Regenerate API key with "API Access" permission level |
| Greenhouse API 403 | Harvest API key not created or wrong type | Create new Harvest API key (not Job Board or Partner key) in admin |
| Headcount doesn't match HRIS | Contractors or interns excluded from API response | Check employment_type filter — include all types and filter in dashboard |
| Compensation data missing | HRIS doesn't expose salary via API on lower tiers | Use manual CSV upload as fallback; schedule monthly re-import |
| Org chart has orphan nodes | Manager_id references terminated employee or null | Add fallback: orphan employees roll up to department head |
| Onboarding tasks not progressing | Assignees not updating status | Add Slack reminders for overdue tasks; auto-mark overdue after due_date |
Cost Breakdown
| Component | Free Tier | Paid Tier | At Scale (Series A+) |
|---|---|---|---|
| Dashboard (Retool) | $0 (5 users) | $10/user/mo | $50/mo (5 users) |
| Database (Supabase) | $0 (500MB) | $25/mo | $25/mo |
| ETL (n8n) | $0 (self-hosted) | $20/mo | $50/mo |
| Unified HRIS API (Merge) | N/A | $300/mo | $300/mo |
| Total | $0 | $355/mo | $425/mo |
Anti-Patterns
Wrong: Showing individual salaries on shared dashboards
Even if "only managers can see it," one screenshot or screen share leaks compensation data across the company. This destroys trust and creates legal liability. [src3]
Correct: Show percentile position within band, not dollar amounts
Display each person as a dot on a 0-100% band position scale. Managers see "Employee X is at 45th percentile of band" — never the actual salary.
Wrong: Calculating turnover from terminations in the current month only
Monthly turnover of 2/50 = 4% looks alarming but annualizes to 48% — or it could be normal variation. Single-month snapshots create false urgency or comfort. [src4]
Correct: Use 12-month rolling turnover with 3-month trend
Annualized turnover rate = (terminations in trailing 12 months / average headcount) * 100. Show 3-month trend to distinguish spikes from patterns.
When This Matters
Use when a startup has 20+ employees and needs automated visibility into headcount, hiring pipeline, and compensation beyond manual spreadsheets. Critical for companies scaling headcount rapidly (hiring 5+ people/quarter) or preparing for board reporting on team metrics. This recipe builds the dashboard — for recruiting strategy or compensation philosophy, use a playbook card instead.