How to Assign Trainings Based on Employee Attributes with
·
To assign trainings from HR data, read each employee's status, groups, locations and hire date through Unified.to's HR & Directory API, apply your eligibility rules, and re-run them when an employee changes. To enrol people in the learning platform itself, Unified.to's LMS API writes on a few supported integrations (below). This guide is for learning, compliance-training and onboarding products.
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.to's HR & Directory API returns current employee attributes in one schema, read from the HRIS at request time, without inventing structure. Assignment logic lives in your product, driven by observable employee state—not vendor-specific assumptions.
What does this guide 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.to provides the HR data. To write the assignment into a learning platform, Unified.to's LMS API reads courses, students and activity across 45 learning platforms, but writes are limited: outside beta, for example, Coursera creates students, FactorialHR creates, updates and removes learning activities, and Google Classroom updates courses and activities (as of 19 October 2026). Other LMS writes, such as Docebo, LearnUpon and Go1 activities, are in beta. Elsewhere, keep assignments in your product or use the Passthrough API.
What decides training eligibility?
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.to returns these attributes in one schema on integrations that record them.
Objects you'll use
Employees (HrisEmployee)
Employees are the decision point for training assignment.
Relevant fields:
idfirst_name,last_nameemails[](work email, where available)employment_statusemployment_typehired_atgroups[]locations[]company_idupdated_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:
idnametypeparent_idis_activecompany_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:
idnameaddress.regionaddress.countryis_activecompany_id
Locations are commonly used for jurisdiction-specific or office-based training requirements.
Companies (HrisCompany)
Companies define scope.
Relevant fields:
idname
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;
}
Where the integration supports updated_gte, use it to re-evaluate only changed employees; where it doesn't (Workday, BambooHR and HiBob, for example), subscribe to employee change events.
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
Treat both employment_status: INACTIVE and a deleted event (sent on some integrations, such as BambooHR, HiBob and Personio) as "remove all assignments"; on integrations without delete events, a periodic full read catches removed employees.
Step 6: How do you keep assignments current?
On supported integrations, use employee change events or updated_gte incremental reads. A typical loop:
- Initial load
- Persist last
updated_at - Re-fetch employees with
updated_gte - Recompute assignments for changed records only
This keeps training programs aligned without daily full syncs.
What does Unified.to leave to your product?
Unified.to does not:
- Decide which trainings are required
- Infer role criticality from titles
- Map custom training fields automatically
- Store or manage learning content
It returns employee attributes in one schema so your product applies its own rules.
Next steps
Write your eligibility rules, confirm groups, locations and hired_at coverage on your customers' integrations, and check whether their learning platform accepts writes. Related: How to Sync Enrollment Rosters Across LMS Platforms · 8 LMS APIs to Integrate With in 2026 · HR API Integration.