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

# Update Time Off Policy

`PATCH /api/v1/time-off/policies/{id}`

## Request

- Base URL: `https://companySubDomain.bamboohr.com`
- URL: `https://companySubDomain.bamboohr.com/api/v1/time-off/policies/{id}`
- 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/time-off/policies/:id/patch.ts> (a function with typed inputs; its response is checked against the schema)

Partially updates a time off policy using JSON Merge Patch semantics. A supplied version replaces the complete accrual schedule by archiving overlapping versions and creating a new version, matching admin Edit Schedule.

OAuth Scopes: time_off:policies.write

## Path parameters

- `id` integer, required

## Request body

- TimeOffUpdatePolicyV1: Data contract for partially updating a time off policy. All fields are optional, but at least one must be supplied. The version replaces the complete accrual schedule.
  - `name` string: The policy name. Must be unique among active policies in the category.
  - `version` TimeOffCreatePolicyVersionV1: The initial version of an accruing time off policy, including the milestones that define its accrual schedule. Required when creating an ACCRUING policy; forbidden for UNLIMITED and MANUAL.
    - `effectiveDate` string, date, required: The date this version becomes effective, in ISO 8601 format (YYYY-MM-DD).
    - `rateTransitions` 'IMMEDIATELY' | 'NEXT_PERIOD': When a rate change between milestones takes effect.
    - `firstAccrual` 'PRORATE' | 'FULL': How the first accrual is handled when an employee starts partway through an accrual period.
    - `carryOverYmd` string: The calendar date each year when unused time carries over, in MM-DD format. Omit to use January 1.
    - `negativeBalanceResetOnCarryOver` boolean: When true, negative balances are reset to zero at the carryover date.
    - `milestones` TimeOffCreatePolicyMilestoneV1[], required: The milestones that make up this policy version. At least one is required.
      - `accrualBeginsInterval` integer, required: How long after the accrual-begins reference point this milestone takes effect, measured in the unit given by accrualBeginsType. Must be 0 when accrualBeginsType is IMMEDIATELY.
      - `accrualBeginsType` 'IMMEDIATELY' | 'DAYS' | 'WEEKS' | 'MONTHS' | 'YEARS', required: The unit used with accrualBeginsInterval to determine when this milestone begins.
      - `accrualHours` number, nullable: The amount of time accrued each interval, measured in the time off category unit. Required unless accruesPerHourWorked is true. Must be between 0 and 99999.9999.
      - `accrualInterval` 'HOURLY' | 'DAILY' | 'WEEKLY' | 'BIWEEKLY' | 'SEMIMONTHLY' | 'MONTHLY' | 'QUARTERLY' | 'SEMIANNUALLY' | 'ANNUALLY' | 'ANNIVERSARY', required: How often time is accrued for this milestone.
      - `maximumHours` number, nullable: The maximum balance an employee may hold under this milestone. Null when there is no cap. Must be between 0 and 99999.9999.
      - `maximumCarryOver` number, nullable: The maximum balance that may carry over at the carryover date. Null when there is no carryover cap. Must be between 0 and 99999.9999.
      - `minimumCarryOver` number, nullable: The minimum balance retained at the carryover date. Null when no minimum is configured. Overridden to 0 when the parent version has negativeBalanceResetOnCarryOver true. Must be between 0 and 99999.9999.
      - `accruesPerHourWorked` boolean: Whether time accrues per hour worked rather than on a fixed schedule.
      - `preaccruing` boolean: Whether the accrual is granted at the start of the period (preaccruing) rather than at the end.

## Response `200`

The updated time off policy.

- TimeOffPolicyV1: A time off policy that determines how employees accrue or are granted a category of time off. Accruing policies expose their currently effective version, including milestones; unlimited and manual policies have no version.
  - `id` integer: The unique identifier for the time off policy.
  - `name` string: The name of the time off policy.
  - `categoryId` integer: The id of the time off category this policy belongs to.
  - `type` 'ACCRUING' | 'UNLIMITED' | 'MANUAL': The type of the time off policy.
  - `currentVersion` TimeOffPolicyVersionV1: A version of an accruing time off policy that is effective from a given date, including the milestones that define its accrual behavior. Only accruing policies have versions.
    - `id` integer: The unique identifier for the policy version.
    - `policyId` integer: The id of the time off policy this version belongs to.
    - `effectiveDate` string, date, nullable: The date this version becomes effective, in ISO 8601 format (YYYY-MM-DD). Null when the version applies from the beginning of the policy.
    - `status` 'ACTIVE' | 'ARCHIVED': The status of the policy version.
    - `rateTransitions` 'IMMEDIATELY' | 'NEXT_PERIOD': When a rate change between milestones takes effect.
    - `firstAccrual` 'PRORATE' | 'FULL': How the first accrual is handled when an employee starts partway through an accrual period.
    - `carryOverYmd` string, nullable: The calendar date each year when unused time carries over, in MM-DD format. Null when the version has no annual carryover date, which also covers the anniversary-based carryover the settings UI can configure but this contract cannot express.
    - `negativeBalanceResetOnCarryOver` boolean: Whether negative balances are reset to zero at the carryover date. Derived from the milestones: the setting is stored as a zero minimum carryover on every milestone rather than as its own field, so a version with no milestones reports false.
    - `milestones` TimeOffPolicyMilestoneV1[]: The milestones that make up this policy version, ordered chronologically.
      - `id` integer: The unique identifier for the milestone.
      - `accrualBeginsInterval` integer: How long after the accrual-begins reference point this milestone takes effect, measured in the unit given by accrualBeginsType.
      - `accrualBeginsType` 'IMMEDIATELY' | 'DAYS' | 'WEEKS' | 'MONTHS' | 'YEARS': The unit used with accrualBeginsInterval to determine when this milestone begins.
      - `accrualHours` number, nullable: The amount of time accrued each interval, measured in the time off category unit. Null when the policy accrues per hour worked.
      - `accrualInterval` 'HOURLY' | 'DAILY' | 'WEEKLY' | 'BIWEEKLY' | 'SEMIMONTHLY' | 'MONTHLY' | 'QUARTERLY' | 'SEMIANNUALLY' | 'ANNUALLY' | 'ANNIVERSARY': How often time is accrued for this milestone.
      - `maximumHours` number, nullable: The maximum balance an employee may hold under this milestone. Null when there is no cap.
      - `maximumCarryOver` number, nullable: The maximum balance that may carry over at the carryover date. Null when there is no carryover cap.
      - `minimumCarryOver` number, nullable: The minimum balance retained at the carryover date. Null when no minimum is configured.
      - `accruesPerHourWorked` boolean: Whether time accrues per hour worked rather than on a fixed schedule.
      - `preaccruing` boolean: Whether the accrual is granted at the start of the period (preaccruing) rather than at the end.
    - `createdAt` string, date-time, nullable: UTC timestamp when the policy version was created. Null for legacy versions migrated from the pre-versioning schema without a usable creation timestamp.
    - `updatedAt` string, date-time, nullable: UTC timestamp when the policy version was last updated. Null when the version has never been updated.
  - `assignedEmployeeCount` integer: The number of active employees currently assigned to this policy.
  - `createdAt` string, date-time: UTC timestamp when the policy was created.
  - `updatedAt` string, date-time, nullable: UTC timestamp when the policy was last updated. Null when the policy has never been updated.
  - `deletedAt` string, date-time, nullable: UTC timestamp when the policy was deleted. Always null because deleted policies are excluded from the API.

## Other responses

- `400`: Malformed request body.
- `401`: Unauthorized. Missing or invalid authentication.
- `403`: Forbidden. The caller may not manage time off policies.
- `404`: The time off policy does not exist.
- `409`: Another active policy in this category already uses the requested name.
- `422`: The request body failed validation, or attempted to change type or categoryId.

## Changes

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

[Operation history](https://skmtc.dev/bamboohr/apis/bamboohr-api/changes/api/v1/time-off/policies/:id/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)
