# Search Payroll Detail

`POST /accounting/payroll-details/search`

Group: Accounting › Payroll Details · Operation ID: `searchPayrollDetail`

Returns the payroll runs that match the given filters, each with its lines.

Searches payroll runs and pages through the matches, returning the full record, header and lines, for each. Matching nothing returns an empty items array, not an error.

[Open in the interactive reference](https://docs.api.lensing.ai/?op=searchPayrollDetail)

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `Api-Version` | header | `"v1"` | yes | The API version this request targets, named by its public identifier. Required on every request; omitting it, or naming a version this company does not have, is answered with 400. This document describes version `v1`. |

## Request body

Required, `application/json`: searchPayrollDetailInput.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `filters` | object | no | The filters to apply. A payroll run must match every filter you send. Omit to return all payroll runs. |
| `filters.id` | string | no | Limits results to the payroll run with this identifier. |
| `filters.payrollDetailNumber` | string | no | Limits results to the payroll run with this number. |
| `filters.periodName` | string | no | Limits results to runs whose payroll period has this name. |
| `filters.currency` | string | no | Limits results to runs in this currency. Format ISO 4217, for example 'USD'. |
| `filters.grouping` | string | no | Limits results to runs grouped this way. Values include 'Employee', 'Department' and 'Multi-level'. Any other value matches no run. |
| `filters.paymentStatus` | string | no | Limits results to runs in this payment status. Values include 'unpaid', 'partiallyPaid', 'fullyPaid', 'pending', 'notApplicable' and 'voided'. Any other value matches no run. |
| `filters.isImported` | boolean | no | Limits results to runs that were imported (true) or entered by hand (false). |
| `filters.entityId` | string | no | Limits results to runs for this legal entity. See id on GET base/entities. |
| `filters.entityName` | string | no | Limits results to runs for a legal entity with this name. |
| `filters.templateId` | string | no | Limits results to runs created from this payroll template. See id on GET accounting/payroll-templates/:id. |
| `page` | object | no | Pagination controls. Omit for the first page. |
| `page.cursor` | string | no | The cursor from the previous response's pagination.nextCursor. Omit for the first request. |
| `page.size` | number | no | The number of payroll runs per page. Defaults to 50. A value above 200 is treated as 200, not rejected. |

Example:

```json
{
  "filters": {
    "paymentStatus": "unpaid"
  },
  "page": {
    "size": 50
  }
}
```

## Response

`200` Success

Under `data` (searchPayrollDetailOutput):

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `items` | array of object | yes | The payroll runs that match, most recently created first. An empty array when nothing matches. |
| `items[].id` | string | yes | The unique identifier for the payroll run. |
| `items[].payrollDetailNumber` | string | no | The payroll run number. Absent until a number has been assigned. |
| `items[].description` | string | no | A description of the payroll run. |
| `items[].periodName` | string | no | The name of the payroll period this run covers, for example '2026-08'. |
| `items[].payrollDate` | string (date) | yes | The date the payroll is dated. Format YYYY-MM-DD. |
| `items[].startDate` | string (date) | no | The first day of the period the run covers. Format YYYY-MM-DD. |
| `items[].endDate` | string (date) | no | The last day of the period the run covers. Format YYYY-MM-DD. |
| `items[].currency` | string | yes | The currency the run is denominated in. Format ISO 4217, for example 'USD'. Governs openAmount and every line amount. |
| `items[].grouping` | string | no | How the payroll run is grouped. Values include 'Employee', 'Department' and 'Multi-level'. |
| `items[].paymentStatus` | string | no | The payment status of the run. Values include 'unpaid', 'partiallyPaid', 'fullyPaid', 'pending', 'notApplicable' and 'voided'. |
| `items[].openAmount` | string (decimal) | no | The amount still unpaid on this run, in currency. |
| `items[].isImported` | boolean | no | Whether the run was imported from a payroll provider rather than entered by hand. |
| `items[].entityId` | string | no | The legal entity the run belongs to. See id on GET base/entities. |
| `items[].entityName` | string | no | The name of the legal entity the run belongs to. |
| `items[].templateId` | string | no | The payroll template this run was created from. See id on GET accounting/payroll-templates/:id. |
| `items[].lastModifiedDate` | string (date-time) | yes | The date and time the payroll run last changed, in UTC. Format YYYY-MM-DDTHH:mm:ss.sssZ. |
| `items[].origin` | string | no | The source system this record came from, as free-form text. Absent when none was supplied. |
| `items[].lines` | array of object | no | The payroll lines, one per employee or department depending on grouping. An empty array when the run has none. |
| `items[].lines[].id` | string | yes | The unique identifier for the line. |
| `items[].lines[].lineNumber` | string | no | The line number. |
| `items[].lines[].lineLevel` | string | no | The level this line sits at. |
| `items[].lines[].employeeName` | string | no | The name of the employee this line pays. |
| `items[].lines[].unmatchedEmployeeName` | string | no | The employee name as it arrived from the payroll provider when it matched no employee on file. |
| `items[].lines[].departmentName` | string | no | The name of the department this line is charged to. |
| `items[].lines[].departmentCode` | string | no | The code of that department. |
| `items[].lines[].departmentNumber` | string | no | The number of that department. |
| `items[].lines[].totalAmount` | string (decimal) | no | The total amount on the line, in the run currency. |
| `items[].lines[].totalGrossAmount` | string (decimal) | no | The gross pay on the line, in the run currency. |
| `items[].lines[].totalNetAmount` | string (decimal) | no | The net pay on the line, in the run currency. |
| `items[].lines[].totalEmployerAmount` | string (decimal) | no | The employer-side contributions on the line, in the run currency. |
| `items[].lines[].errorMessage` | string | no | Why this line could not be processed, when it failed. |
| `pagination` | object | yes | The pagination cursor for this page. |
| `pagination.nextCursor` | string | no | The cursor for the next page. Pass it as page.cursor. Absent on the last page. |
| `pagination.hasMore` | boolean | yes | True when more runs remain beyond this page. |

## Statuses

- `400` — Invalid request or business failure
- `401` — Missing or invalid access token
- `403` — Not authorized
- `404` — Not found
- `429` — Too many requests
- `500` — Internal server error
