---
name: unified-hris
description: >-
  Build HR, people-data, and payroll features against many HRIS platforms
  (Workday, BambooHR, Gusto, Deel, HiBob, and more) through the single
  Unified.to HRIS API. Use when a coding task involves syncing employees,
  groups, time off, attendance, or payroll data across one or more HR systems.
license: MIT
metadata:
  category: hris
  api_base: https://api.unified.to
  docs: https://docs.unified.to/hris/overview
---

# Build an HR / employee-data app with the Unified.to HRIS API

Unified.to normalizes many HRIS platforms behind one REST API. Write your HR
integration once and it works across every supported platform. This skill
teaches an agent how to build against the Unified HRIS API.

## When to use this skill

Use this skill when the task is to:

- Sync an employee directory and org structure (groups/departments)
- Read or write time off, attendance, and time shifts
- Read payroll data (payslips, deductions, benefits)
- Onboard or provision employees across more than one HR system

## Prerequisites

1. A Unified.to workspace with an **API key** and **Workspace ID**.
2. An activated HRIS integration (e.g. BambooHR) — start in the Sandbox.
3. A **connection ID** from the embedded Authorization component
   (https://docs.unified.to/concepts/embedded-components).

Keep the API key server-side only.

## Core request pattern

```
https://api.unified.to/hris/{connection_id}/{object}
```

Authenticate every request:

```
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
```

Regional base URLs: `api.unified.to` (NA), `api-eu.unified.to` (EU),
`api-au.unified.to` (AU).

## Data objects (subset)

| Object       | Purpose                                          |
| ------------ | ------------------------------------------------ |
| `employee`   | An employee                                      |
| `group`      | A department / team / group                      |
| `company`    | A company / legal entity                         |
| `location`   | A work location                                  |
| `timeoff`    | A time-off request / balance                     |
| `attendance` | An attendance record                             |
| `timeshift`  | A scheduled shift                                |
| `benefit`    | A benefit enrollment                             |
| `deduction`  | A payroll deduction                              |
| `document`   | A document attached to an employee               |

Read-only objects include `payslip` and `taxonomy`.

### Supported operations (employee shown; most objects follow the same shape)

| Method   | Path                          | Description        |
| -------- | ----------------------------- | ------------------ |
| `GET`    | `/hris/{cid}/employee`        | List employees     |
| `GET`    | `/hris/{cid}/employee/{id}`   | Get one employee   |
| `POST`   | `/hris/{cid}/employee`        | Create an employee |
| `PATCH`  | `/hris/{cid}/employee/{id}`   | Update an employee |
| `DELETE` | `/hris/{cid}/employee/{id}`   | Delete an employee |

The same verbs apply to `group`, `company`, `location`, `timeoff`,
`attendance`, `timeshift`, `benefit`, `deduction`, and `document`.

Not every platform supports every object or field — check the **Feature
Support** tab in `app.unified.to`. A `501` response means unsupported.

## Pagination, filtering & sorting

- `limit` (max 100) and `offset` (zero-based).
- `updated_gte=YYYY-MM-DDTHH:MM:SSZ` for incremental sync.
- `sort` (`created_at`, `updated_at`, `name`) + `order` (`asc` / `desc`).

## Example: sync employees and read time off (fetch)

```javascript
const BASE = 'https://api.unified.to';
const headers = {
    Authorization: `Bearer ${process.env.UNIFIED_API_KEY}`,
    'Content-Type': 'application/json',
};

// Page through the employee directory
async function* allEmployees(connectionId) {
    let offset = 0;
    const limit = 100;
    while (true) {
        const res = await fetch(
            `${BASE}/hris/${connectionId}/employee?limit=${limit}&offset=${offset}`,
            { headers }
        );
        const page = await res.json();
        yield* page;
        if (page.length < limit) break;
        offset += limit;
    }
}

// Read time-off for a given employee
const timeoff = await (
    await fetch(`${BASE}/hris/${connectionId}/timeoff?employee_id=EMPLOYEE_ID`, { headers })
).json();
```

Consult the employee data model at https://docs.unified.to/hris/employee/model
for canonical fields.

## Example: with the official SDK

```bash
npm install @unified-api/typescript-sdk
```

```typescript
import { UnifiedTo } from '@unified-api/typescript-sdk';

const unified = new UnifiedTo({ security: { jwt: process.env.UNIFIED_API_KEY! } });

const { hrisEmployees } = await unified.hris.listHrisEmployees({ connectionId, limit: 100 });
```

SDKs for Python, PHP, Java, Go, C#, and Ruby: https://docs.unified.to/reference/sdks.

## Keeping data in sync (recommended)

- Register **webhooks** for `employee`, `group`, and `timeoff` events and upsert
  by `id`. See https://docs.unified.to/reference/webhooks.
- Sync into your own database for fast, consistent, platform-independent queries.

## Error handling

| Code | Meaning & action                                            |
| ---- | ----------------------------------------------------------- |
| 401  | Connection broken — re-authorize the end-user.              |
| 403  | Missing scopes — fix provider app + Unified.to scopes.      |
| 429  | Provider rate limit — back off; prefer webhook sync.        |
| 501  | Operation unsupported by platform — check Feature Support.  |

## References

- HRIS API overview & data model: https://docs.unified.to/hris/overview
- Employee data model: https://docs.unified.to/hris/employee/model
- Accessing employees and users: https://docs.unified.to/guides/how_to_access_employees_and_users
- REST basics: https://docs.unified.to/reference/rest
- Pagination & filtering: https://docs.unified.to/reference/pagination
