---
title: "Update Employee Time Off Policy Assignment"
method: PATCH
path: "/api/v1/employees/{employeeId}/time-off/policies/{assignmentId}"
tags: ["Time Off", "Public API"]
---

# Update Employee Time Off Policy Assignment

`PATCH /api/v1/employees/{employeeId}/time-off/policies/{assignmentId}`

## Request

- Base URL: `https://companySubDomain.bamboohr.com`
- URL: `https://companySubDomain.bamboohr.com/api/v1/employees/{employeeId}/time-off/policies/{assignmentId}`
- Auth: one of:
  - HTTP basic
  - OAuth 2
    - Authorization code: `/authorize.php`
    - Token URL: `/token.php` scopes: `time_off:policies.write`
- TypeScript: <https://skmtc.dev/bamboohr/apis/bamboohr-api/docs/api/v1/employees/:employeeId/time-off/policies/:assignmentId/patch.ts> (a function with typed inputs; its response is checked against the schema)

Updates one of an employee's time off policy assignments using JSON Merge Patch semantics: a field left out of the body keeps its current value, and at least one of `policyId` and `effectiveDate` must be present. `policyId` reassigns the employee to another policy in the same time off category; reassigning to a policy in a different category is rejected, since that is an assignment for the other category and is created with `POST`. `effectiveDate` moves the date the assignment takes effect (the accrual basis date for accruing policies); it must not precede the employee's hire date, and on an assignment that has already ended it must not pass the end date. `endDate` is server managed and not accepted. The change is recorded the way the admin UI records it: the addressed assignment is kept as an audit copy with status `SUPERSEDED` and a new assignment carrying the requested policy and effective date takes its place, so the response's `id` differs from `assignmentId` whenever something changed. The superseded assignment keeps its own dates; it is an audit copy. The employee holds at most one assignment per category at any point in time and this call keeps that true: an assignment in the category that starts on or after the new effective date and no later than this assignment's end date is archived (no longer in effect, kept as history, whether or not it had already taken effect), and the assignment that preceded this one is re-ended at the day before the new effective date. Assignments that start after this one ends are not affected. Everything the call changed, the superseded assignment included, is returned in `supersededAssignments` in its post-write state; archived assignments are not listed anywhere else. Accruals for the category are recalculated from the earliest date the change affects. A body whose values equal the assignment's current values would change nothing and is refused with `409`, as on assign. Accepts both `application/merge-patch+json` and `application/json`.

OAuth Scopes: time_off:policies.write

## Path parameters

- `employeeId` integer, required
- `assignmentId` integer, required

## Request body

- EmployeeTimeOffUpdatePolicyAssignmentV1: Data contract for partially updating an employee's time off policy assignment. Both fields are optional but at least one must be supplied; a field left out keeps its current value. Neither field accepts null, and `endDate` is server managed and not accepted.
  - `policyId` integer: The id of the time off policy to reassign the employee to. Must be an existing, non-deleted policy in the same time off category as the assignment being updated. The assignment keeps its effective date unless `effectiveDate` is supplied too, so the employee's history for the category is recalculated under the new policy from that date.
  - `effectiveDate` string, date: The new date the assignment takes effect, in ISO 8601 format (YYYY-MM-DD). For accruing policies this is the accrual basis date. Must not precede the employee's hire date, and on an assignment that has already ended must not pass its end date.

## Response `200`

The assignment as it is after the update, under a new `id`, with `supersededAssignments` listing every assignment in the same category the write changed: the addressed assignment with status `SUPERSEDED` and its original dates, any re-ended preceding assignment with status `ACTIVE` and its new `endDate`, and any archived scheduled assignment with status `ARCHIVED`. Never empty: it always carries at least the superseded addressed assignment.

- EmployeeTimeOffPolicyAssignmentWithSupersededV1: An assignment of a time off policy to an employee. The list endpoint surfaces active assignments only; archived and superseded assignments appear only inside the `supersededAssignments` of the write that changed them.
  - `id` integer: The unique identifier for the policy assignment.
  - `employeeId` integer: The id of the employee the policy is assigned to.
  - `policyId` integer: The id of the assigned time off policy.
  - `categoryId` integer: The id of the time off category the assigned policy belongs to. Denormalized so callers do not need a second request to resolve the policy.
  - `effectiveDate` string, date, nullable: The date the assignment takes effect, in ISO 8601 format (YYYY-MM-DD). For accruing policies this is the accrual basis date.
  - `endDate` string, date, nullable: The date the assignment ends, in ISO 8601 format (YYYY-MM-DD). Null when the assignment is open ended. Read-only; the server manages it when a successor assignment supersedes this one.
  - `createdAt` string, date-time, nullable: UTC timestamp when the assignment was created.
  - `updatedAt` string, date-time, nullable: UTC timestamp when the assignment was last updated. Null when the assignment has never been updated.
  - `status` 'ACTIVE' | 'ARCHIVED' | 'SUPERSEDED': The assignment's lifecycle state. ACTIVE assignments are the ones the list endpoint returns, including those whose `endDate` has passed: an ended assignment is still the record of the period it covered. ARCHIVED means the assignment is no longer in effect for any date: a later write starting on or before its effective date replaced or cancelled it, whether or not it had already taken effect. It is kept as history and never returns to the list. SUPERSEDED is the pre-change snapshot kept when an assignment is unassigned or its date or policy is changed; the successor row carries the change. Only ACTIVE appears in list responses; the other two appear inside `supersededAssignments` on the write response that produced them.
  - `supersededAssignments` EmployeeTimeOffPolicyAssignmentV1[]: The assignments in the same category that this write changed. An assignment that was in force on the new effective date is end-dated to the day before and keeps status ACTIVE; an assignment starting on or after the new effective date, whether scheduled or already in effect, is ARCHIVED (no longer in effect, kept as history) and no longer appears in the list endpoint; on an update, the assignment that was addressed is kept with its original dates as the SUPERSEDED snapshot. Empty when the write changed nothing else.
    - `id` integer: The unique identifier for the policy assignment.
    - `employeeId` integer: The id of the employee the policy is assigned to.
    - `policyId` integer: The id of the assigned time off policy.
    - `categoryId` integer: The id of the time off category the assigned policy belongs to. Denormalized so callers do not need a second request to resolve the policy.
    - `effectiveDate` string, date, nullable: The date the assignment takes effect, in ISO 8601 format (YYYY-MM-DD). For accruing policies this is the accrual basis date.
    - `endDate` string, date, nullable: The date the assignment ends, in ISO 8601 format (YYYY-MM-DD). Null when the assignment is open ended. Read-only; the server manages it when a successor assignment supersedes this one.
    - `createdAt` string, date-time, nullable: UTC timestamp when the assignment was created.
    - `updatedAt` string, date-time, nullable: UTC timestamp when the assignment was last updated. Null when the assignment has never been updated.
    - `status` 'ACTIVE' | 'ARCHIVED' | 'SUPERSEDED': The assignment's lifecycle state. ACTIVE assignments are the ones the list endpoint returns, including those whose `endDate` has passed: an ended assignment is still the record of the period it covered. ARCHIVED means the assignment is no longer in effect for any date: a later write starting on or before its effective date replaced or cancelled it, whether or not it had already taken effect. It is kept as history and never returns to the list. SUPERSEDED is the pre-change snapshot kept when an assignment is unassigned or its date or policy is changed; the successor row carries the change. Only ACTIVE appears in list responses; the other two appear inside `supersededAssignments` on the write response that produced them.

## Other responses

- `400`: Malformed request body.
- `401`: Unauthorized. The credentials are missing or invalid.
- `403`: Forbidden. The authenticated user may not manage this employee's time off policy assignments.
- `404`: Employee, assignment or replacement policy not found. An assignment id that belongs to another employee is reported as not found, as is a deleted replacement policy. Keeping the current policy never fails this way, even if that policy has since been deleted.
- `409`: The requested policy and effective date equal the assignment's current ones, so there is nothing to change.
- `422`: Invalid request data. `fields` names the offending property: an archived or superseded `assignmentId` (such assignments must stay as they are), neither `policyId` nor `effectiveDate` supplied (reported on `body`), a non-integer, non-positive or null `policyId`, a `policyId` in a different time off category, a malformed or null `effectiveDate`, an `effectiveDate` before the employee's hire date or after an ended assignment's end date, an employee with no hire date (reported on `effectiveDate`), an `endDate` in the body, or a category managed by an employer of record (reported on `policyId`).
- `500`: The update was written but could not be read back. The change exists and a `GET` of the employee's policies shows it; the original `assignmentId` is now superseded, so retrying the same request returns `422`.

## Changes

- **2026-11-03** `922fc15f43a7`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/bamboohr/apis/bamboohr-api/changes/api/v1/employees/:employeeId/time-off/policies/:assignmentId/patch.md)

---

[API](https://skmtc.dev/bamboohr/apis/bamboohr-api.md) - [All operations](https://skmtc.dev/bamboohr/apis/bamboohr-api/llms.txt) - [OpenAPI document](https://skmtc.dev/bamboohr/apis/bamboohr-api/revisions/922fc15f43a7?raw)
