Time Off Requests

The time off request object

Attribute Type Description
id integer Unique ID for the time off request.
status string Status of request: pending, approved, declined, changes_requested, or cancelled.
start_date date Start date of the request.
end_date date End date of the request.
days decimal Total business days requested.
business_days_at_submission decimal Working days snapshot at the time of submission.
start_time_minutes integer Starting minute offset for partial-day requests (e.g. 540 for 09:00).
end_time_minutes integer Ending minute offset for partial-day requests (e.g. 780 for 13:00).
notes string Submitter notes for the request.
review_reason string Reason provided during manager or admin review.
reviewed_at datetime When the request was reviewed.
created_at datetime Date and time the request was created. Use the ISO 8601 Format.
updated_at datetime Date and time the request was updated. Use the ISO 8601 Format.
user object An object containing the id and name of the associated user.
pto_type object An object containing the id, name, color, and icon of the associated policy.
reviewer object An object containing the id and name of the reviewer, or null.
request_days array Array of daily breakdown objects (id, date, hours, day_fraction).

Required permissions

The PTO API is currently being rolled out gradually. Requests from unavailable accounts return 403 Forbidden.

Administrators can list, view, create, edit, approve, decline, and cancel time off requests across the company.

Non-administrators can view, create, update, and cancel only their own time off requests. Requesting or querying another user’s requests will result in a 403 Forbidden status code.

List all time off requests

Returns a list of time off requests.

The response contains an object with a pto_requests property that contains an array of up to per_page time off requests. Each entry in the array is a separate time off request object. If no more requests are available, the resulting array will be empty. Several additional pagination properties are included in the response to simplify paginating your requests.

GET /v2/pto/requests
Parameter Type Description
user_id integer Filter requests by user ID. Non-administrators can only pass their own user ID.
status string Filter requests by status (pending, approved, declined, changes_requested, cancelled).
pto_type_id integer Filter requests by time off policy ID.
from date Only return requests overlapping with or on/after this date.
to date Only return requests overlapping with or on/before this date.
updated_since datetime Only return requests updated since this timestamp.
page integer The page number to use in pagination. (Default: 1)
per_page integer The number of records to return per page. Can range between 1 and 2000. (Default: 2000)

Example Request:

curl "https://api.harvestapp.com/v2/pto/requests?status=pending" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Harvest-Account-Id: $ACCOUNT_ID" \
  -H "User-Agent: MyApp ([email protected])"

Example Response:

{
  "pto_requests": [
    {
      "id": 501,
      "status": "pending",
      "start_date": "2026-10-01",
      "end_date": "2026-10-02",
      "days": 2.0,
      "business_days_at_submission": 2.0,
      "start_time_minutes": null,
      "end_time_minutes": null,
      "notes": "Fall break",
      "review_reason": null,
      "reviewed_at": null,
      "created_at": "2026-09-01T12:00:00Z",
      "updated_at": "2026-09-01T12:00:00Z",
      "user": {
        "id": 1782959,
        "name": "Kim Allen"
      },
      "pto_type": {
        "id": 101,
        "name": "Vacation",
        "color": "blue",
        "icon": "vacation"
      },
      "reviewer": null,
      "request_days": [
        {
          "id": 1001,
          "date": "2026-10-01",
          "hours": 8.0,
          "day_fraction": 1.0,
          "created_at": "2026-09-01T12:00:00Z",
          "updated_at": "2026-09-01T12:00:00Z"
        },
        {
          "id": 1002,
          "date": "2026-10-02",
          "hours": 8.0,
          "day_fraction": 1.0,
          "created_at": "2026-09-01T12:00:00Z",
          "updated_at": "2026-09-01T12:00:00Z"
        }
      ]
    }
  ],
  "per_page": 2000,
  "total_pages": 1,
  "total_entries": 1,
  "next_page": null,
  "previous_page": null,
  "page": 1,
  "links": {
    "first": "https://api.harvestapp.com/v2/pto/requests?page=1&per_page=2000",
    "next": null,
    "previous": null,
    "last": "https://api.harvestapp.com/v2/pto/requests?page=1&per_page=2000"
  }
}

Retrieve a time off request

Retrieves the details of an existing time off request. Returns a time off request object and a 200 OK response code.

GET /v2/pto/requests/{PTO_REQUEST_ID}

Example Request:

curl "https://api.harvestapp.com/v2/pto/requests/501" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Harvest-Account-Id: $ACCOUNT_ID" \
  -H "User-Agent: MyApp ([email protected])"

Example Response:

{
  "id": 501,
  "status": "pending",
  "start_date": "2026-10-01",
  "end_date": "2026-10-02",
  "days": 2.0,
  "business_days_at_submission": 2.0,
  "start_time_minutes": null,
  "end_time_minutes": null,
  "notes": "Fall break",
  "review_reason": null,
  "reviewed_at": null,
  "created_at": "2026-09-01T12:00:00Z",
  "updated_at": "2026-09-01T12:00:00Z",
  "user": {
    "id": 1782959,
    "name": "Kim Allen"
  },
  "pto_type": {
    "id": 101,
    "name": "Vacation",
    "color": "blue",
    "icon": "vacation"
  },
  "reviewer": null,
  "request_days": [
    {
      "id": 1001,
      "date": "2026-10-01",
      "hours": 8.0,
      "day_fraction": 1.0,
      "created_at": "2026-09-01T12:00:00Z",
      "updated_at": "2026-09-01T12:00:00Z"
    },
    {
      "id": 1002,
      "date": "2026-10-02",
      "hours": 8.0,
      "day_fraction": 1.0,
      "created_at": "2026-09-01T12:00:00Z",
      "updated_at": "2026-09-01T12:00:00Z"
    }
  ]
}

Create a time off request

Creates a new time off request. Returns a time off request object and a 201 Created response code if the call succeeded.

POST /v2/pto/requests
Parameter Type Description
pto_type_id integer Required. The policy ID to request time against.
start_date date Required. Start date for the request.
end_date date Required. End date for the request.
user_id integer Target user ID. Only administrators can submit on behalf of another user.
notes string Optional notes describing the request.
start_time_minutes integer Starting minute offset for partial-day requests.
end_time_minutes integer Ending minute offset for partial-day requests.
conflict_resolution string Either skip or replace to resolve overlapping requests.

Example Request:

curl -X POST "https://api.harvestapp.com/v2/pto/requests" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Harvest-Account-Id: $ACCOUNT_ID" \
  -H "Content-Type: application/json" \
  -H "User-Agent: MyApp ([email protected])" \
  -d '{"pto_type_id": 101, "start_date": "2026-11-05", "end_date": "2026-11-06", "notes": "Doctor appointment"}'

Example Response:

{
  "id": 503,
  "status": "pending",
  "start_date": "2026-11-05",
  "end_date": "2026-11-06",
  "days": 2.0,
  "business_days_at_submission": 2.0,
  "start_time_minutes": null,
  "end_time_minutes": null,
  "notes": "Doctor appointment",
  "review_reason": null,
  "reviewed_at": null,
  "created_at": "2026-09-03T12:15:00Z",
  "updated_at": "2026-09-03T12:15:00Z",
  "user": {
    "id": 1782959,
    "name": "Kim Allen"
  },
  "pto_type": {
    "id": 101,
    "name": "Vacation",
    "color": "blue",
    "icon": "vacation"
  },
  "reviewer": null,
  "request_days": [
    {
      "id": 1003,
      "date": "2026-11-05",
      "hours": 8.0,
      "day_fraction": 1.0,
      "created_at": "2026-09-03T12:15:00Z",
      "updated_at": "2026-09-03T12:15:00Z"
    },
    {
      "id": 1004,
      "date": "2026-11-06",
      "hours": 8.0,
      "day_fraction": 1.0,
      "created_at": "2026-09-03T12:15:00Z",
      "updated_at": "2026-09-03T12:15:00Z"
    }
  ]
}

Update a time off request

Updates an unreviewed time off request. Only pending or changes_requested requests can be edited. Updating a request cancels the original request and returns a new replacement request object with a new id and a 200 OK response code.

PATCH /v2/pto/requests/{PTO_REQUEST_ID}
Parameter Type Description
pto_type_id integer Updated policy ID.
start_date date Updated start date.
end_date date Updated end date.
notes string Updated notes.
start_time_minutes integer Updated start minute offset.
end_time_minutes integer Updated end minute offset.
conflict_resolution string Overlap resolution (skip or replace).

Example Request:

curl -X PATCH "https://api.harvestapp.com/v2/pto/requests/502" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Harvest-Account-Id: $ACCOUNT_ID" \
  -H "Content-Type: application/json" \
  -H "User-Agent: MyApp ([email protected])" \
  -d '{"notes": "Updated note"}'

Example Response:

{
  "id": 503,
  "status": "pending",
  "start_date": "2026-11-05",
  "end_date": "2026-11-06",
  "days": 2.0,
  "business_days_at_submission": 2.0,
  "start_time_minutes": null,
  "end_time_minutes": null,
  "notes": "Updated note",
  "review_reason": null,
  "reviewed_at": null,
  "created_at": "2026-09-03T12:15:00Z",
  "updated_at": "2026-09-03T12:20:00Z",
  "user": {
    "id": 1782959,
    "name": "Kim Allen"
  },
  "pto_type": {
    "id": 101,
    "name": "Vacation",
    "color": "blue",
    "icon": "vacation"
  },
  "reviewer": null,
  "request_days": [
    {
      "id": 1003,
      "date": "2026-11-05",
      "hours": 8.0,
      "day_fraction": 1.0,
      "created_at": "2026-09-03T12:15:00Z",
      "updated_at": "2026-09-03T12:15:00Z"
    },
    {
      "id": 1004,
      "date": "2026-11-06",
      "hours": 8.0,
      "day_fraction": 1.0,
      "created_at": "2026-09-03T12:15:00Z",
      "updated_at": "2026-09-03T12:15:00Z"
    }
  ]
}

Cancel a time off request

Cancels a time off request. The request is not deleted from Harvest; instead, its status is updated to cancelled and it remains visible in request listings. Returns a 200 OK response code and the cancelled time off request object.

DELETE /v2/pto/requests/{PTO_REQUEST_ID}

Example Request:

curl -X DELETE "https://api.harvestapp.com/v2/pto/requests/503" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Harvest-Account-Id: $ACCOUNT_ID" \
  -H "User-Agent: MyApp ([email protected])"

Example Response:

{
  "id": 503,
  "status": "cancelled",
  "start_date": "2026-11-05",
  "end_date": "2026-11-06",
  "days": 2.0,
  "business_days_at_submission": 2.0,
  "start_time_minutes": null,
  "end_time_minutes": null,
  "notes": "Updated note",
  "review_reason": null,
  "reviewed_at": null,
  "created_at": "2026-09-03T12:15:00Z",
  "updated_at": "2026-09-03T12:22:00Z",
  "user": {
    "id": 1782959,
    "name": "Kim Allen"
  },
  "pto_type": {
    "id": 101,
    "name": "Vacation",
    "color": "blue",
    "icon": "vacation"
  },
  "reviewer": null,
  "request_days": [
    {
      "id": 1003,
      "date": "2026-11-05",
      "hours": 8.0,
      "day_fraction": 1.0,
      "created_at": "2026-09-03T12:15:00Z",
      "updated_at": "2026-09-03T12:15:00Z"
    },
    {
      "id": 1004,
      "date": "2026-11-06",
      "hours": 8.0,
      "day_fraction": 1.0,
      "created_at": "2026-09-03T12:15:00Z",
      "updated_at": "2026-09-03T12:15:00Z"
    }
  ]
}

Approve a time off request

Approves a pending or changes_requested request. Returns a time off request object and a 200 OK response code. Only administrators can perform this action.

POST /v2/pto/requests/{PTO_REQUEST_ID}/approve

Example Request:

curl -X POST "https://api.harvestapp.com/v2/pto/requests/501/approve" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Harvest-Account-Id: $ACCOUNT_ID" \
  -H "User-Agent: MyApp ([email protected])"

Example Response:

{
  "id": 501,
  "status": "approved",
  "start_date": "2026-10-01",
  "end_date": "2026-10-02",
  "days": 2.0,
  "business_days_at_submission": 2.0,
  "start_time_minutes": null,
  "end_time_minutes": null,
  "notes": "Fall break",
  "review_reason": null,
  "reviewed_at": "2026-09-03T12:25:00Z",
  "created_at": "2026-09-01T12:00:00Z",
  "updated_at": "2026-09-03T12:25:00Z",
  "user": {
    "id": 1782959,
    "name": "Kim Allen"
  },
  "pto_type": {
    "id": 101,
    "name": "Vacation",
    "color": "blue",
    "icon": "vacation"
  },
  "reviewer": {
    "id": 1782884,
    "name": "Bob Powell"
  },
  "request_days": [
    {
      "id": 1001,
      "date": "2026-10-01",
      "hours": 8.0,
      "day_fraction": 1.0,
      "created_at": "2026-09-01T12:00:00Z",
      "updated_at": "2026-09-01T12:00:00Z"
    },
    {
      "id": 1002,
      "date": "2026-10-02",
      "hours": 8.0,
      "day_fraction": 1.0,
      "created_at": "2026-09-01T12:00:00Z",
      "updated_at": "2026-09-01T12:00:00Z"
    }
  ]
}

Decline a time off request

Declines a time off request. Returns a time off request object and a 200 OK response code. Only administrators can perform this action.

POST /v2/pto/requests/{PTO_REQUEST_ID}/decline
Parameter Type Description
reason string Optional decline reason.

Example Request:

curl -X POST "https://api.harvestapp.com/v2/pto/requests/501/decline" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Harvest-Account-Id: $ACCOUNT_ID" \
  -H "Content-Type: application/json" \
  -H "User-Agent: MyApp ([email protected])" \
  -d '{"reason": "Team coverage needed during that week"}'

Example Response:

{
  "id": 501,
  "status": "declined",
  "start_date": "2026-10-01",
  "end_date": "2026-10-02",
  "days": 2.0,
  "business_days_at_submission": 2.0,
  "start_time_minutes": null,
  "end_time_minutes": null,
  "notes": "Fall break",
  "review_reason": "Team coverage needed during that week",
  "reviewed_at": "2026-09-03T12:30:00Z",
  "created_at": "2026-09-01T12:00:00Z",
  "updated_at": "2026-09-03T12:30:00Z",
  "user": {
    "id": 1782959,
    "name": "Kim Allen"
  },
  "pto_type": {
    "id": 101,
    "name": "Vacation",
    "color": "blue",
    "icon": "vacation"
  },
  "reviewer": {
    "id": 1782884,
    "name": "Bob Powell"
  },
  "request_days": []
}

Request changes on a time off request

Requests changes on a time off request. Returns a time off request object and a 200 OK response code. Only administrators can perform this action.

POST /v2/pto/requests/{PTO_REQUEST_ID}/request_changes
Parameter Type Description
reason string Required. Explanation of changes required from the submitter.

Example Request:

curl -X POST "https://api.harvestapp.com/v2/pto/requests/501/request_changes" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Harvest-Account-Id: $ACCOUNT_ID" \
  -H "Content-Type: application/json" \
  -H "User-Agent: MyApp ([email protected])" \
  -d '{"reason": "Please adjust dates to start on Friday"}'

Example Response:

{
  "id": 501,
  "status": "changes_requested",
  "start_date": "2026-10-01",
  "end_date": "2026-10-02",
  "days": 2.0,
  "business_days_at_submission": 2.0,
  "start_time_minutes": null,
  "end_time_minutes": null,
  "notes": "Fall break",
  "review_reason": "Please adjust dates to start on Friday",
  "reviewed_at": "2026-09-03T12:35:00Z",
  "created_at": "2026-09-01T12:00:00Z",
  "updated_at": "2026-09-03T12:35:00Z",
  "user": {
    "id": 1782959,
    "name": "Kim Allen"
  },
  "pto_type": {
    "id": 101,
    "name": "Vacation",
    "color": "blue",
    "icon": "vacation"
  },
  "reviewer": {
    "id": 1782884,
    "name": "Bob Powell"
  },
  "request_days": [
    {
      "id": 1001,
      "date": "2026-10-01",
      "hours": 8.0,
      "day_fraction": 1.0,
      "created_at": "2026-09-01T12:00:00Z",
      "updated_at": "2026-09-01T12:00:00Z"
    },
    {
      "id": 1002,
      "date": "2026-10-02",
      "hours": 8.0,
      "day_fraction": 1.0,
      "created_at": "2026-09-01T12:00:00Z",
      "updated_at": "2026-09-01T12:00:00Z"
    }
  ]
}

Still have questions? We’re happy to help!

Contact Us