---
title: "How to Read Employee Payroll History from Payslips with"
img: https://s3.us-east-2.amazonaws.com/unified-article-images/how_to_read_employee_payroll_history_from_payslips_with-icon.png
date: 2026-01-10T00:00:00.000Z
updated: 2026-10-21T01:16:39.021Z
readingTime: 4
tag: Product
description: "To read an employee's payroll history with Unified.to, list their payslips, each one records a pay period, the pay date, gross and net pay, and line items for..."
url: "https://unified.to/blog/how_to_read_employee_payroll_history_from_payslips_with"
---

# How to Read Employee Payroll History from Payslips with

To read an employee's payroll history with [Unified.to](http://unified.to/), list their payslips: each one records a pay period, the pay date, gross and net pay, and line items for earnings, taxes and deductions, on supported payroll integrations such as ADP Workforce Now, UKG Pro HCM, Workday (Legacy), [Remote.com](http://remote.com/), Deel and Xero (as of 19 October 2026). This guide is for teams building payroll analytics, audit or benefits features, and shows how to join payslips (and, for hourly staff, timeshifts) to employees and total them yourself.


Across HR systems, 'pay history' is often implied rather than explicit. Employee records may show a current salary or hourly rate, but they rarely encode _when_ that compensation applied, _which period_ it covered, or _what was actually paid_ after deductions. Vendors model it differently, and many don't provide it at all.


For a PM, this creates real constraints:

- Can payroll analytics be trusted across HR systems with different data models?
- Can historical pay be reconstructed without guessing past compensation?
- Can you explain exactly where a number came from during audits or disputes?

Many products solve this by storing snapshots, reconstructing history, or quietly falling back to current-state compensation fields. That works until a number is challenged and you can't show where it came from.


[Unified.to](http://unified.to/)'s [HR & Directory API](/hris) doesn't reconstruct pay history. It returns the payroll records the HR system holds, payslips and timeshifts, on integrations that support them. Payslips are read-only on every integration. A payslip is a record of one pay period; a timeshift is a worked shift with its hours, and on a few integrations (Workday, plus several in beta) its pay.


## Prerequisites

- Node.js 18+
- A [Unified.to](http://unified.to/) workspace and API key
- An HR & Directory integration activated, and a `connectionId` from [Unified.to](http://unified.to/)'s authorization flow

## Step 1: Fetch employees


Employees are the anchor object for all HR data. All payroll records reference employees by ID.


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

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

const connectionId = 'YOUR_CONNECTION_ID';

const employees = await sdk.hris.listHrisEmployees({
  connectionId,
  limit: 100,
  offset: 0,
  sort: 'updated_at',
  order: 'asc',
});
```


### What this returns

- A **plain array** of `HrisEmployee`
- No wrapper object
- No cursor field

[Pagination](https://docs.unified.to/reference/pagination) is handled with `limit` and `offset`. You know you've reached the end when the number of returned records is less than your requested limit.


### Employee identifiers


Each employee has a canonical identifier:


```typescript
employee.id
```


All payroll objects reference this ID.


## Step 2: Fetch payroll history via payslips


Payslips are the main source of pay history in [Unified.to](http://unified.to/). Where you need the pay run itself rather than each employee's slip, pay runs (`hris_payroll`) are available on Check, Deel, Employment Hero Payroll, Paychex, Paycor, [Remote.com](http://remote.com/) and Rippling (as of 19 October 2026).


```typescript
const payslips = await sdk.hris.listHrisPayslips({
  connectionId,
  limit: 100,
  offset: 0,
  user_id: employeeId, // optional filter
  sort: 'updated_at',
  order: 'asc',
});
```


### Payslip semantics


Each `HrisPayslip` represents a **point-in-time payroll snapshot**:

- `start_at` / `end_at`: pay period
- `paid_at`: payment date
- `gross_amount`
- `net_amount`
- `currency`
- `details[]`: earnings, taxes, deductions

Not every integration returns every field: `currency` is returned on only a few, so read the employee's or company's currency when it's missing.


### Joining payslips to employees


```typescript
payslip.user_id === employee.id
```


### Date filtering


Payslips **cannot** be filtered by pay-period dates server-side. To work with a date range:

- Fetch all payslips
- Filter client-side using `start_at` / `end_at`

## Step 3: Fetch time-based compensation via timeshifts (optional)


For hourly staff, [Unified.to](http://unified.to/) returns **timeshifts** on supported integrations such as Workday, ADP Workforce Now, BambooHR, Deputy and UKG Ready.


```typescript
const timeshifts = await sdk.hris.listHrisTimeshifts({
  connectionId,
  limit: 100,
  offset: 0,
  start_gte: '2026-01-01T00:00:00Z',
  end_lt: '2026-02-01T00:00:00Z',
});
```


### Timeshift semantics


Each `HrisTimeshift` is one worked shift:

- `start_at` / `end_at`
- `hours`
- `compensation[]` entries (few integrations):
    - `amount`
    - `currency`
    - `frequency` (HOUR, DAY, ONE_TIME, etc.)

### Joining timeshifts to employees


```typescript
timeshift.employee_user_id === employee.id
```


Timeshifts support **true server-side date filtering** using `start_gte` and `end_lt`, but availability depends on the integration.


## Step 4: Understand what is _not_ historical


The Employee object also has `compensation[]` (see [How to Analyze Compensation](https://unified.to/blog/how_to_analyze_compensation_with_unified_hr_and_directory_api)), but:

- It has **no effective dates**
- No history semantics are documented
- It should be treated as **current-state compensation only**

For historical payroll analysis, always use **payslips** or **timeshifts**.


## Step 5: Aggregate payroll data client-side


[Unified.to](http://unified.to/) returns **raw numeric values**. All aggregation is your responsibility.


### Key constraints

- **No currency normalization**
    - Each record includes its own `currency`
    - Aggregate only within the same currency
- **No frequency normalization**
    - Timeshift compensation may be hourly, yearly, or one-time
    - Convert units explicitly if needed
- **No server-side aggregation**
    - No totals, averages, or group-by endpoints

### Example aggregation logic (conceptual)


```typescript
const totalsByPeriod = {};

for (const payslip of payslips) {
  const periodKey = `${payslip.start_at}-${payslip.end_at}`;
  const currency = payslip.currency;

  if (!totalsByPeriod[periodKey]) {
    totalsByPeriod[periodKey] = { currency, gross: 0, net: 0 };
  }

  totalsByPeriod[periodKey].gross += payslip.gross_amount ?? 0;
  totalsByPeriod[periodKey].net += payslip.net_amount ?? 0;
}
```


## Error handling and unsupported features


[Unified.to](http://unified.to/) uses standard HTTP status codes.


### Important behavior

- **501 Not Implemented**
    - The integration does not support that feature (e.g. payslips or timeshifts)
    - The connection itself is still valid
- **401 Unauthorized**
    - Connection is broken and must be recreated
- **403 Forbidden**
    - Missing scopes or permissions

Always check the **Feature Support** tab for an integration in `app.unified.to` to confirm object availability.


## Summary


With [Unified.to](http://unified.to/)'s HR & Directory API, you read payroll history in four steps:

1. Fetching employees
2. Joining **payslips** for pay-period payroll snapshots
3. Optionally joining **timeshifts** for time-based compensation
4. Aggregating results client-side with explicit currency and frequency handling

The same code runs on every payroll integration that returns payslips. [Unified.to](http://unified.to/) keeps no customer records at rest (connection credentials and operational metadata are encrypted at rest), and payslips are read-only, so nothing is written back to payroll.


Related: [What Is Payroll Integration?](https://unified.to/blog/what_is_payroll_integration_a_complete_guide_2026) · [15 Payroll APIs to Integrate With in 2026](https://unified.to/blog/15_payroll_apis_to_integrate_with_in_2026_adp_gusto_paychex) · [Payslip data model](https://docs.unified.to/hris/payslip/model)


→ [Start your 30-day free trial](https://app.unified.to/login)


→ [Book a demo](https://calendly.com/d/cph9-g8n-jzg/connect-with-unified)