How to Analyze Employee Population for Compliance and Risk (GRC) with Unified's HR & Directory API
February 2, 2026
Employee population analysis for compliance and risk fails when tools blur the line between what is observable and what is inferred.
Across HR systems, demographic attributes, employment classifications, and compensation data vary widely in availability and meaning. Some fields are optional. Some are self-reported. Some exist only for certain geographies or company policies. When products attempt to normalize or infer missing attributes, they introduce legal, audit, and reputational risk.
For governance, risk, and compliance (GRC) teams, the challenge isn't lack of data. It's trusting the analysis.
Unified's HR & Directory API is designed to support population analysis without guessing. It exposes only what the underlying HRIS explicitly provides, with consistent schemas and clear boundaries around what is current-state, optional, or unavailable. Aggregation is possible. Interpretation is left to you.
This guide shows how to analyze employee population data for compliance and risk use cases—workforce composition, demographic distribution, organizational concentration, and geographic exposure—using Unified's HR & Directory API, without reconstructing history or inferring protected attributes.
What GRC analysis means in this context
This article focuses on population analysis, not compliance determination.
We will:
- Analyze workforce composition and distribution
- Segment populations by observable attributes
- Surface structural risk indicators (concentration, imbalance, exposure)
We will not:
- Declare regulatory compliance
- Detect bias or discrimination
- Infer protected characteristics
- Produce legal conclusions
Unified provides the data layer. Compliance interpretation belongs to your governance framework.
The mental model: population analysis is descriptive, not judgmental
GRC-oriented employee analysis should answer questions like:
- How is our workforce distributed by role, location, and employment type?
- Which organizational units concentrate certain demographic attributes?
- Where do optional or sensitive attributes cluster—or go missing?
- How does workforce composition differ across entities or regions?
These are descriptive questions. They rely on counts, distributions, and segmentation—not inference.
Objects you'll use
Employees (HrisEmployee)
Employees are the foundation of population analysis.
Relevant fields:
idemployment_statusemployment_typegender(optional; self-reported where supported)date_of_birthmarital_statushired_atterminated_atgroups[]locations[]company_idupdated_at
Important constraints:
- Demographic fields may be missing or null.
- Gender values are enumerated but not required.
- No assumptions should be made when attributes are absent.
Groups (HrisGroup)
Groups support organizational segmentation.
Relevant fields:
idnameparent_idtypeis_activecompany_id
Groups allow rollups by department, division, or business unit without assuming hierarchy implies reporting structure.
Locations (HrisLocation)
Locations enable geographic and jurisdictional analysis.
Relevant fields:
idnameaddress.regionaddress.countryis_activecompany_id
Location data is essential for region-specific compliance and exposure reporting.
Companies (HrisCompany)
Companies define reporting scope.
Relevant fields:
idname
This supports entity-level compliance views for multi-subsidiary organizations.
Step 1: Fetch the employee population
Employee lists are paginated and support incremental refresh.
import { UnifiedTo } from '@unified-api/typescript-sdk';
const sdk = new UnifiedTo({
security: { jwt: process.env.UNIFIED_API_KEY! },
});
async function fetchEmployees(connectionId: string) {
const results = [];
let offset = 0;
const limit = 100;
while (true) {
const page = await sdk.hris.listHrisEmployees({
connectionId,
limit,
offset,
sort: 'updated_at',
order: 'asc',
fields: [
'id',
'employment_status',
'employment_type',
'gender',
'date_of_birth',
'marital_status',
'groups',
'locations',
'company_id',
].join(','),
});
if (!page || page.length === 0) break;
results.push(...page);
offset += limit;
}
return results;
}
Use updated_gte to refresh only changed records in production systems.
Step 2: Define the population baseline
Most GRC analyses focus on the current workforce.
function activePopulation(employees: any[]) {
return employees.filter(
(e) => e.employment_status === 'ACTIVE' && !e.terminated_at
);
}
Inclusion rules (e.g., contractors vs full-time employees) should be explicit and configurable.
Step 3: Segment by observable attributes
Employment type distribution
function byEmploymentType(employees: any[]) {
const counts: Record<string, number> = {};
for (const e of employees) {
const type = e.employment_type ?? 'UNKNOWN';
counts[type] = (counts[type] ?? 0) + 1;
}
return counts;
}
This is useful for identifying workforce composition risk, such as over-reliance on contractors in regulated roles.
Gender distribution (where available)
function genderDistribution(employees: any[]) {
const counts: Record<string, number> = {};
for (const e of employees) {
const gender = e.gender ?? 'UNSPECIFIED';
counts[gender] = (counts[gender] ?? 0) + 1;
}
return counts;
}
Important:
- Missing values are preserved as a category.
- No assumptions are made about unspecified records.
Age bands
function ageBands(employees: any[]) {
const now = new Date();
const bands = { '<30': 0, '30–50': 0, '50+': 0, UNKNOWN: 0 };
for (const e of employees) {
if (!e.date_of_birth) {
bands.UNKNOWN++;
continue;
}
const age =
(now.getTime() - new Date(e.date_of_birth).getTime()) /
(365.25 * 24 * 60 * 60 * 1000);
if (age < 30) bands['<30']++;
else if (age <= 50) bands['30–50']++;
else bands['50+']++;
}
return bands;
}
Age analysis is useful for workforce planning and regulatory exposure, but should always be treated as descriptive.
Step 4: Segment by org unit and location
Because employees reference groups and locations directly, segmentation is straightforward.
Examples:
- Gender distribution by department
- Employment type by region
- Workforce concentration by company entity
Rollups are performed client-side using the same joins across HRISs.
Step 5: Track population changes over time
Use hired_at, terminated_at, and updated_at to observe change.
Examples:
- Net population growth by quarter
- Attrition concentration by department
- Demographic shifts by region
These are observed trends, not predictions.
What Unified does not infer
Unified intentionally does not:
- Infer ethnicity or protected attributes
- Reconstruct employment or pay history
- Normalize missing demographic data
- Make compliance judgments
This keeps population analysis auditable and legally defensible.
Closing thoughts
GRC-oriented employee analysis depends on restraint as much as insight.
Unified's HR & Directory API provides a clean, normalized foundation for workforce population analysis—exposing only what HR systems explicitly record, preserving missing data where it exists, and leaving interpretation to governance frameworks and human judgment.
That clarity is what makes compliance analysis trustworthy.