Read Payroll Period Data
The Payroll Period endpoints let you read the pay periods 7shifts has generated for a customer's company. Payroll periods define the start and end dates of each pay run, track when each location's period is closed for processing, and — when requested — surface whether the time punches inside a period have been reviewed and approved.
These endpoints are designed for payroll and Earned Wage Access (EWA) integrations that need to know when a pay period covers, whether it has been closed, and whether the underlying punch data is settled and safe to export.
Payroll Period vs Time Punches
Payroll periods describe the calendar window for a pay run. The hours, wages, breaks, and tips that get paid out live on the underlying Time Punches for that window. Always pull time punches for the period's
start/enddates — the payroll period record itself does not include hours or amounts.
Knowing when a period is ready to export
A payroll period has two layers of "doneness":
- Per-location state (
states[]) — each location closes its own pay period independently when the manager finishes reviewing and approving punches for that location. - Company-wide finalization (
finalized) —trueonly when every location's state in the period is closed. This is the signal most payroll integrations poll on before exporting.
Pair with webhooks
Instead of polling, subscribe to the
payroll_period.closedwebhook to be notified the moment a period (or a single location within a period) closes, then call Retrieve Payroll Period to fetch the current state before pulling punches.
List Payroll Periods
Retrieve a paginated list of payroll periods for a company, ordered with the most recent period first. Use this when discovering existing pay periods, when syncing on a schedule, or when you want richer status fields than the Retrieve endpoint returns.
Pass include_punches_status=true when you also need to know whether the punches inside each period have been approved by managers and reviewed by employees.
Request URL
curl --request GET \
--url 'https://api.7shifts.com/v2/time_clocking/payroll_periods?company_id=12345&include_punches_status=true' \
--header 'accept: application/json' \
--header 'authorization: Bearer <ACCESS_TOKEN>'Query parameters
| Parameter | Type | Description |
|---|---|---|
company_id required | int | The 7shifts Company ID. |
cursor | string | Cursor for the next or previous page of results. See Pagination. |
limit | int | Number of results per page. |
include_punches_status | boolean | When true, populates all_punches_approved and employee_punch_approvals on each period. Defaults to false. |
Response body
{
"data": [
{
"id": 9876,
"company_id": 12345,
"start": "2024-01-15",
"end": "2024-01-28",
"closed": true,
"finalized": true,
"states": [
{
"id": 4567,
"location_id": 222,
"closed": true,
"processed": "2024-01-30",
"modified_by_user_id": 333,
"closed_or_reopened_at": "2024-01-29T18:42:11+00:00"
}
],
"all_punches_approved": true,
"employee_punch_approvals": "reviewed",
"created": "2024-01-15T00:00:00+00:00",
"modified": "2024-01-29T18:42:11+00:00"
}
],
"meta": {
"cursor": {
"next": "eyJpZCI6OTg3Nn0=",
"prev": null
}
}
}Here's an explanation of each field on a payroll period:
| Field | Type | Description |
|---|---|---|
id | int | The payroll period ID. Use this with the Retrieve endpoint. |
company_id | int | The 7shifts Company ID the period belongs to. |
start | date | First day of the pay period (YYYY-MM-DD). |
end | date | Last day of the pay period (YYYY-MM-DD). |
closed | bool | true when at least one location's state in the period is closed. |
finalized | bool / null | true only when all location states in the period are closed. This is the recommended "safe to export" signal for company-wide payroll pulls. |
states | array | One entry per location, describing that location's close/process state (see below). |
all_punches_approved | bool / null | true when every punch the requesting user can see for the period has been manager-approved. Only populated when include_punches_status=true. |
employee_punch_approvals | enum / null | reviewed or pending, indicating whether employees have signed off on their punches. null if Compliance is not enabled. Only populated when include_punches_status=true. |
created | datetime | When the period record was created, in UTC. |
modified | datetime | When the period was last modified, in UTC. |
Each entry in states describes the close/process state for a single location:
| Field | Type | Description |
|---|---|---|
id | int / null | The ID of the location's pay period state row. |
location_id | int | The 7shifts Location ID this state describes. |
closed | bool | Whether this location's pay period is closed. |
processed | date / null | The date the period was last exported/processed for this location. |
modified_by_user_id | int | User ID that last modified the state. Negative values indicate a server process (e.g. automatic close). |
closed_or_reopened_at | datetime / null | The last time this location's state was closed or reopened, in UTC. |
Retrieve Payroll Period
Fetch a single payroll period by its ID. Use this when you already know the period you care about — for example, after receiving a payroll_period.closed webhook, or when refreshing a period your integration has previously synchronized.
Request URL
curl --request GET \
--url 'https://api.7shifts.com/v2/company/12345/payroll_periods/9876' \
--header 'accept: application/json' \
--header 'authorization: Bearer <ACCESS_TOKEN>'Path parameters
| Parameter | Type | Description |
|---|---|---|
company_id required | int | The 7shifts Company ID. |
payroll_period_id required | int | The ID of the payroll period. |
Response body
{
"object": "payroll_period",
"data": {
"id": 9876,
"company_id": 12345,
"closed": true,
"start": "2024-01-15",
"end": "2024-01-28",
"states": [
{
"id": 4567,
"location_id": 222,
"closed": true,
"processed": "2024-01-30",
"modified_by_user_id": 333,
"closed_or_reopened_at": "2024-01-29T18:42:11+00:00"
}
]
}
}Here's an explanation of each field:
| Field | Type | Description |
|---|---|---|
object | string | Always payroll_period. |
data | object | The payroll period payload (see below). |
id | int | The payroll period ID. |
company_id | int | The 7shifts Company ID the period belongs to. |
start | date | First day of the pay period (YYYY-MM-DD). |
end | date | Last day of the pay period (YYYY-MM-DD). |
closed | bool | true when at least one location's state in the period is closed. |
states | array | Per-location close/process states. Same shape as the states array on the List endpoint (see above). |
Schema differences vs. List
The Retrieve endpoint wraps the payroll period in an
object/dataenvelope and returns a focused set of fields. If you needfinalized,all_punches_approved,employee_punch_approvals,created, ormodified, use the List Payroll Periods endpoint withinclude_punches_status=trueand filter the response client-side byid.
A typical payroll export flow
- On a schedule (or when you receive a
payroll_period.closedwebhook), call List Payroll Periods withinclude_punches_status=true. - Identify periods where
finalizedistrueandall_punches_approvedistrue— these are safe to export. - For each such period, call List Time Punches filtered to the period's
startandenddates to retrieve the actual hours and wages. - Record the period's
idandmodifiedtimestamp so you can detect re-opens — a manager can reopen a closed period to correct punches, after whichmodified(and the relevant locationstates[].closed_or_reopened_at) will advance.
