---
title: "Create Time Off Policy"
method: POST
path: "/api/v1/time-off/policies"
tags: ["Time Off", "Public API"]
---

# Create Time Off Policy

`POST /api/v1/time-off/policies`

## Request

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

Creates a time off policy. Accruing policies include an inlined initial version with milestones; unlimited and manual policies have no version.

OAuth Scopes: time_off:policies.write

## Request body

- TimeOffCreatePolicyV1: Data contract for creating a time off policy. Accruing policies include an inlined initial version with milestones; unlimited and manual policies have no version.
  - `name` string, required: The name of the time off policy. Must be unique among the category's active policies.
  - `categoryId` integer, required: The id of the time off category this policy belongs to.
  - `type` 'ACCRUING' | 'UNLIMITED' | 'MANUAL', required: The type of the time off policy.
  - `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 `201`

The created time off policy, including currentVersion for accruing policies.

- 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 referenced time off category does not exist.
- `409`: A policy with the same name already exists in the category.
- `422`: The request body failed validation.

## Changes

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

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