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

# Assign Employee Time Off Policy

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

## Request

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

Assigns a time off policy to an employee, effective from `effectiveDate`. An employee holds at most one assignment per time off category at any point in time, and this call keeps that true rather than refusing: an assignment in the same category that is in force on `effectiveDate` is end-dated to the day before, and any assignment in that category starting on or after `effectiveDate`, scheduled or already in effect, is archived: it is no longer in effect for any date and is kept as history. Neither is an error: both changed assignments are returned in the response's `supersededAssignments`, the end-dated one with its new `endDate` and status `ACTIVE`, the archived ones with status `ARCHIVED`. A subsequent `GET` of the employee's policies shows the end-dated assignment; archived assignments are not listed anywhere else, so this response is the one place a caller sees them. The one conflict is assigning the policy the employee already holds with the same `effectiveDate`, which would change nothing and returns `409`; that applies to any active assignment on that policy and date, scheduled or already ended, not only the one in force today. `effectiveDate` is required for every policy type and must not precede the employee's hire date. `endDate` is not accepted: new assignments are always open ended, and are ended later by unassigning or by a successor assignment. Accruals for the category are recalculated from the effective date.

OAuth Scopes: time_off:policies.write

## Path parameters

- `employeeId` integer, required

## Request body

- EmployeeTimeOffCreatePolicyAssignmentV1: Data contract for assigning a time off policy to an employee. New assignments are always open ended, so no end date is accepted.
  - `policyId` integer, required: The id of the time off policy to assign. Must be an existing, non-deleted policy.
  - `effectiveDate` string, date, required: The 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. Required for every policy type, including discretionary and manual policies.

## Response `201`

The created assignment, with `supersededAssignments` listing every assignment in the same category the write end-dated or archived (empty when nothing collided).

- 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 or policy not found. A deleted policy is reported as not found.
- `409`: The employee already holds this policy with the same effective date, so there is nothing to change.
- `422`: Invalid request data. `fields` names the offending property: a missing, non-integer or non-positive `policyId`, a missing or malformed `effectiveDate`, an `effectiveDate` before the employee's hire date or an employee with no hire date (both reported on `effectiveDate`), an `endDate` in the body, or a category managed by an employer of record (reported on `policyId`).
- `500`: The assignment was written but could not be read back. The assignment exists and a `GET` of the employee's policies shows it; retrying the same request returns `409`.

## 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/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)
