---
updatedAt: 2026-01-16T00:07:34.000Z
agentTools:
  siteIndex: https://docs.gusto.com/llms.txt
  projectIndex: https://docs.gusto.com/embedded-payroll/llms.txt
---

# Benefit effective dating

This guide describes how **effective dating** is supported on Gusto’s existing [employee benefit APIs](https://docs.gusto.com/embedded-payroll/reference/post-v1-employees-employee_id-employee_benefits).

Effective dating allows partners to schedule changes to an employee’s benefit deductions and contributions over time by creating **multiple employee benefit records**—each with its own effective window—for the **same company benefit**.

A benefit is applied to payroll if it is effective on the **pay period end date**, regardless of payroll type (regular or off-cycle).

## Core concepts

### Effective-dated benefit windows

Each window is represented as a separate `employee_benefit` record with:

* `effective_date`
  * Default value is unix epoch (1970-01-01)
* `expiration_date` (optional; null if omitted)

Multiple windows can exist for the same `company_benefit_uuid`, provided that **date range windows do not overlap**.

### Automatic handling of existing non–effective-dated benefits

If an employee already has a benefit record **without an expiration date** (`expiration_date` is null) and a new effective-dated benefit record is created for the same `company_benefit_uuid`, Gusto will automatically close the existing benefit window.

Specifically:

* The new employee benefit record’s `effective_date` determines when the new benefit begins
* The existing benefit record will automatically receive an `expiration_date` set to **one day before** the new benefit’s `effective_date`

This ensures there is no overlap between the original benefit record and the newly created effective-dated benefit.

**Example**

1. Existing benefit record:
   * `effective_date`: 1970-01-01
   * `expiration_date`: null
2. New benefit record created with:
   * `effective_date`: December 15
3. Resulting state:
   * Existing benefit record:
     * `expiration_date`: December 14
   * New benefit record:
     * `effective_date`: December 15

### How to resolve overlaps between effective-dated windows

If a benefit with an expiration date already exists and there’s an overlap with a newly created or updated window, you must explicitly resolve the overlap by updating the existing benefit window.

**Example**

* Existing window: December 1 → December 31
* Intended window for new benefit: December 15 → December 31

To resolve the overlap:

1. Update the existing window to end on December 14
2. Create the new benefit with a December 15 → December 31 window

### Active flag

For an employee benefit to be applied to a payroll, it must be marked `active` on **both** the employee and the company benefit levels. Otherwise, even if a benefit is effective on a pay period end date, the benefit will not go into effect.

## Create an effective-dated employee benefit

Call [POST /v1/employees/\{employee\_id}/employee\_benefits](https://docs.gusto.com/embedded-payroll/reference/post-v1-employees-employee_id-employee_benefits) to create a new effective-dated employee benefit. You can also create a baseline (open-ended) benefit by omitting `effective_date` and `expiration_date`.

**Sample request body (create)**

```json
{
  "company_benefit_uuid": "9e89df01-7cc4-48b3-89dd-22ce593def0e",
  "employee_deduction": "60.00",
  "contribution": {
    "type": "amount",
    "value": "100.00"
  },
  "effective_date": "2025-01-01",
  "expiration_date": "2025-02-01"
}
```

Remember, date ranges **must not overlap for the same company benefit and employee**.

## Update an effective-dated employee benefit

Call [PUT /v1/employee\_benefits/\{employee\_benefit\_uuid}](https://docs.gusto.com/embedded-payroll/reference/put-v1-employee_benefits-employee_benefit_id) to update the window for an existing effective-dated employee benefit. For example, you might need to correct dates or adjust amounts.

To make an update, you’ll need to pass in the `version` of the existing employee benefit.

**Sample request body (update)**

```json
{
  "version": "0ebd734767489bb5de33a68f34cbd2gh",
  "company_benefit_uuid": "9e89df01-7cc4-48b3-89dd-22ce593def0e",
  "employee_deduction": "70.00",
  "contribution": {
    "type": "amount",
    "value": "120.00"
  },
  "effective_date": "2025-01-01",
  "expiration_date": "2025-02-15"
}
```

## Bulk create or update employee benefits

The [PUT /v1/company\_benefits/\{company\_benefit\_uuid}/employee\_benefits](https://docs.gusto.com/embedded-payroll/reference/put-v1-company_benefits-company_benefit_id-employee_benefits) endpoint supports **bulk create** and **bulk update** actions.

> 📘 Important limitation
>
> A single bulk request can only perform a **single benefit action** for a given employee.
>
> You must submit separate bulk requests in order to, for example:
>
> * Create a new effective dated window AND update an existing window for the same employee
> * Update multiple windows for the same employee

Each item in the `employee_benefits` array **must specify** either a `create` or `update` action if you are passing effective dating parameters (`effective_date` or `expiration_date` for that employee benefit.

**Sample request body (bulk create)**

```json
{
  "employee_benefits": [
    {
      "employee_uuid": "4ea2606f-770d-4659-9b4f-71282c1a65c7",
      "action": "create",
      "employee_deduction": "50.0",
      "effective_date": "2025-04-01"
    },
    {
      "employee_uuid": "91905d38-14b0-493c-8c3d-d86d4cc96061",
      "action": "create",
      "employee_deduction": "50.0",
      "effective_date": "2025-04-01"
    }
  ]
}

```

**Sample request body (bulk update)**

Bulk updates require both `uuid` and `version`

```json
{
  "employee_benefits": [
    {
      "version": "72b3313fed0c60816b6b37d04a4dc1e4",
      "uuid": "acb74e05-7a3a-4dec-ae32-453375c296fd",
      "employee_uuid": "4ea2606f-770d-4659-9b4f-71282c1a65c7",
      "action": "update",
      "employee_deduction": "70.0",
      "effective_date": "2025-04-01"
    }
  ]
}
```

## Retrieve effective-dated benefits

**Endpoints:**

* [GET /v1/employees/\{employee\_id}/employee\_benefits](https://docs.gusto.com/embedded-payroll/reference/get-v1-employees-employee_id-employee_benefits)
* [GET /v1/company\_benefits/\{company\_benefit\_id}?with\_employee\_benefits=true](https://docs.gusto.com/embedded-payroll/reference/get-v1-company_benefits-company_benefit_id)
* [GET /v1/company\_benefits/\{company\_benefit\_id}/employee\_benefits](https://docs.gusto.com/embedded-payroll/reference/get-v1-company_benefits-company_benefit_id-employee_benefits)

Use these endpoints before creating or updating to validate existing benefit windows, or after to confirm results.

By default, these endpoints return **only active employee benefits** based on the date you pull the record. To retrieve **all employee benefits**, including future and expired records, use the `include=all_benefits` query parameter. It can be helpful to retrieve all benefits when investigating missing or expired benefit windows.

## Common scenarios

### Unpaid leave ($0 window)

1. End the prior window
2. Create a $0 deduction window for the leave period
3. Create a follow-on window to resume deductions

### Catch-up contributions

1. Create a temporary window with increased deductions
2. Calculate catch-up amounts externally
3. Create a follow-on window to revert to the standard amount

### New hire or termination mid-cycle

Supply the true eligibility window

Deductions are applied based on pay period overlap

**Recommendation for terminations**

For the final termination deduction, it is recommended **not to set an `expiration_date`**. This ensures the deduction applies to the correct final payroll cycle

## FAQ

### What will the new date attributes be for benefits that existed before this feature?

Employee benefits that pre-date this feature will have `"effective_date: 1970-01-01"` and `"expiration_date: null"`.

### Can I update existing benefits to specify windows instead of creating new benefits?

Yes! You can update an existing benefit's `effective_date` and `expiration_date` if you’d prefer that over creating a new benefit window and letting the windows automatically update.