Unified.to
All articles

How to Assign Trainings and Programs Based on Employee Attributes with Unified's HR & Directory API


February 2, 2026

Automated training assignment breaks when products assume employee attributes are static, complete, or universally defined.

Across HR systems, the inputs used to assign learning and training programs—department, location, tenure, employment type—are modeled differently and change over time. Some systems treat teams as first-class objects. Others rely on loosely defined groups. Locations may represent offices, regions, or payroll entities. Start dates may be missing or overridden by rehire logic.

When products hardcode rules per HRIS or assume attributes behave consistently, training assignment becomes brittle. Employees miss required programs. Former employees remain enrolled. Compliance training drifts out of sync with organizational reality.

Unified's HR & Directory API avoids that failure mode. It exposes current employee attributes through a normalized, real-time model, without inventing structure or inferring intent. Assignment logic lives in your product, driven by observable employee state—not vendor-specific assumptions.

This guide shows how to assign trainings and programs based on employee attributes using Unified's HR & Directory API—fetching employees, segmenting them by department, location, and tenure, and keeping assignments accurate as employee records change.

What this article does (and does not) cover

This article focuses on assignment logic, not learning delivery.

We will:

  • Use HR attributes to determine eligibility for training programs
  • Assign and revoke programs as employee attributes change
  • Keep assignments aligned with current employment state

We will not:

  • Deliver or track course completion
  • Store training content
  • Infer employee intent or role criticality

Unified provides the HR data layer. Training systems consume the assignments.

The mental model: training eligibility is a function of current state

Training assignment should always be based on current employee attributes, not historical snapshots.

At any point in time, an employee has:

  • An employment status
  • One or more organizational group memberships
  • One or more locations
  • A tenure relative to their start date

When any of those change, eligibility must be re-evaluated.

Unified exposes these attributes explicitly and consistently across HRISs.

Objects you'll use

Employees (HrisEmployee)

Employees are the decision point for training assignment.

Relevant fields:

  • id
  • first_name, last_name
  • emails[] (work email, where available)
  • employment_status
  • employment_type
  • hired_at
  • groups[]
  • locations[]
  • company_id
  • updated_at

Important constraints:

  • Attributes may be missing or incomplete.
  • Employees may belong to multiple groups or locations.
  • Start dates reflect hiring, not necessarily role changes.

Groups (HrisGroup)

Groups define organizational affiliation.

Relevant fields:

  • id
  • name
  • type
  • parent_id
  • is_active
  • company_id

Groups are used to assign department- or team-specific trainings. Their semantics are customer-defined and should not be hardcoded.

Locations (HrisLocation)

Locations define geographic placement.

Relevant fields:

  • id
  • name
  • address.region
  • address.country
  • is_active
  • company_id

Locations are commonly used for jurisdiction-specific or office-based training requirements.

Companies (HrisCompany)

Companies define scope.

Relevant fields:

  • id
  • name

This allows different training rules per entity or subsidiary.

Step 1: Fetch employees incrementally

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 employees = [];
  let offset = 0;
  const limit = 100;

  while (true) {
    const page = await sdk.hris.listHrisEmployees({
      connectionId,
      limit,
      offset,
      sort: 'updated_at',
      order: 'asc',
      fields: [
        'id',
        'first_name',
        'last_name',
        'emails',
        'employment_status',
        'employment_type',
        'hired_at',
        'groups',
        'locations',
        'company_id',
      ].join(','),
    });

    if (!page || page.length === 0) break;

    employees.push(...page);
    offset += limit;
  }

  return employees;
}

Use updated_gte in production to re-evaluate only changed employees.

Step 2: Filter eligible employees

Training assignments should never apply to inactive employees.

function activeEmployees(employees: any[]) {
  return employees.filter(
    (e) => e.employment_status === 'ACTIVE'
  );
}

Whether to include contractors or interns is a policy decision, not a data constraint.

Step 3: Compute tenure-based eligibility

Tenure is derived from hired_at.

function tenureInDays(employee: any): number | null {
  if (!employee.hired_at) return null;
  const hired = new Date(employee.hired_at);
  const now = new Date();
  return Math.floor(
    (now.getTime() - hired.getTime()) / (1000 * 60 * 60 * 24)
  );
}

This enables rules such as:

  • Onboarding training within first 30 days
  • Annual compliance refresh after one year

Step 4: Assign trainings by attribute

Assignment logic is deterministic and explicit.

Examples:

Department-based training

function isInGroup(employee: any, groupId: string): boolean {
  return (employee.groups ?? []).some((g: any) => g.id === groupId);
}

Location-based training

function isInCountry(employee: any, countryCode: string): boolean {
  return (employee.locations ?? []).some(
    (l: any) => l.address?.country_code === countryCode
  );
}

Tenure-based training

function requiresOnboarding(employee: any): boolean {
  const days = tenureInDays(employee);
  return days !== null && days < 30;
}

Your system can combine these rules to assign one or more programs.

Step 5: Handle revocation automatically

Because assignments are driven by current state, revocation is just reassignment.

Examples:

  • Employee leaves a department → remove department-specific training
  • Employee relocates → assign new regional compliance training
  • Employee becomes inactive → disable all assignments

No HRIS-specific cleanup logic is required.

Step 6: Keep assignments in sync

Unified supports incremental refresh across all HR objects.

Typical pattern:

  1. Initial load
  2. Persist last updated_at
  3. Re-fetch employees with updated_gte
  4. Recompute assignments for changed records only

This ensures training programs stay aligned without daily full syncs.

What Unified does not assume

Unified does not:

  • Decide which trainings are required
  • Infer role criticality from titles
  • Map custom training fields automatically
  • Store or manage learning content

It exposes employee attributes consistently so your product can apply its own rules.

Closing thoughts

Automated training assignment isn't about syncing HR data. It's about reacting correctly to change.

Unified's HR & Directory API gives you a stable, normalized view of employee attributes—department, location, tenure, and status—so training and program assignment stays accurate as organizations evolve.

With the right rules in place, training becomes adaptive instead of manual.

Start your 30-day free trial

Book a demo

All articles