Time Entries
The time entry object
Attribute | Type | Description |
---|---|---|
id |
bigint | Unique ID for the time entry. |
spent_date |
date | Date of the time entry. |
user |
object | An object containing the id and name of the associated user. |
user_assignment |
object | A user assignment object of the associated user. |
client |
object | An object containing the id and name of the associated client. |
project |
object | An object containing the id and name of the associated project. |
task |
object | An object containing the id and name of the associated task. |
task_assignment |
object | A task assignment object of the associated task. |
external_reference |
object | An object containing the id , group_id , account_id , permalink , service , and service_icon_url of the associated external reference. |
invoice |
object | Once the time entry has been invoiced, this field will include the associated invoice’s id and number. |
hours |
decimal | Number of (decimal time) hours tracked in this time entry. |
hours_without_timer |
decimal | Number of (decimal time) hours already tracked in this time entry, before the timer was last started. |
rounded_hours |
decimal | Number of (decimal time) hours tracked in this time entry used in summary reports and invoices. This value is rounded according to the Time Rounding setting in your Preferences. |
notes |
string | Notes attached to the time entry. |
is_locked |
boolean | Whether or not the time entry has been locked. |
locked_reason |
string | Why the time entry has been locked. |
is_closed |
boolean | Whether or not the time entry has been approved via Timesheet Approval. |
is_billed |
boolean | Whether or not the time entry has been marked as invoiced. |
timer_started_at |
datetime | Date and time the running timer was started (if tracking by duration). Use the ISO 8601 Format. Returns null for stopped timers. |
started_time |
time | Time the time entry was started (if tracking by start/end times). |
ended_time |
time | Time the time entry was ended (if tracking by start/end times). |
is_running |
boolean | Whether or not the time entry is currently running. |
billable |
boolean | Whether or not the time entry is billable. |
budgeted |
boolean | Whether or not the time entry counts towards the project budget. |
billable_rate |
decimal | The billable rate for the time entry. |
cost_rate |
decimal | The cost rate for the time entry. |
created_at |
datetime | Date and time the time entry was created. Use the ISO 8601 Format. |
updated_at |
datetime | Date and time the time entry was last updated. Use the ISO 8601 Format. |
Required permissions
Administrators can see all time entries for the account.
Managers can see time entries for themselves, assigned teammates, and time tracked to projects they manage. Additionally, Managers with permission to edit assigned teammates’ time entries can create, edit, and destroy time entries on their behalf.
Members can only see their own tracked time.
List all time entries
Returns a list of time entries. The time entries are returned sorted by spent_date
date. At this time, the sort option can’t be customized.
The response contains an object with a time_entries
property that contains an array of up to per_page
time entries. Each entry in the array is a separate time entry object. If no more time entries are available, the resulting array will be empty. Several additional pagination properties are included in the response to simplify paginating your time entries.
GET /v2/time_entries
Parameter | Type | Description |
---|---|---|
user_id |
integer | Only return time entries belonging to the user with the given ID. |
client_id |
integer | Only return time entries belonging to the client with the given ID. |
project_id |
integer | Only return time entries belonging to the project with the given ID. |
task_id |
integer | Only return time entries belonging to the task with the given ID. |
external_reference_id |
string | Only return time entries with the given external_reference ID. |
is_billed |
boolean | Pass true to only return time entries that have been invoiced and false to return time entries that have not been invoiced. |
is_running |
boolean | Pass true to only return running time entries and false to return non-running time entries. |
updated_since |
datetime | Only return time entries that have been updated since the given date and time. Use the ISO 8601 Format. |
from |
date | Only return time entries with a spent_date on or after the given date. |
to |
date | Only return time entries with a spent_date on or before the given date. |
page |
integer | The page number to use in pagination. For instance, if you make a list request and receive 2000 records, your subsequent call can include page=2 to retrieve the next page of the list. (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/time_entries" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Harvest-Account-Id: $ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Example Response:
Retrieve a time entry
Retrieves the time entry with the given ID. Returns a time entry object and a 200 OK
response code if a valid identifier was provided.
GET /v2/time_entries/{TIME_ENTRY_ID}
Example Request:
curl "https://api.harvestapp.com/v2/time_entries/636708723" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Harvest-Account-Id: $ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Example Response:
Create a time entry via duration
Creates a new time entry object. Returns a time entry object and a 201 Created
response code if the call succeeded.
You should only use this method to create time entries when your account is configured to track time via duration. You can verify this by visiting the Settings page in your Harvest account or by checking if wants_timestamp_timers
is false in the Company API.
POST /v2/time_entries
Parameter | Type | Required | Description |
---|---|---|---|
user_id |
integer | optional | The ID of the user to associate with the time entry. Defaults to the currently authenticated user’s ID. |
project_id |
integer | required | The ID of the project to associate with the time entry. |
task_id |
integer | required | The ID of the task to associate with the time entry. |
spent_date |
date | required | The ISO 8601 formatted date the time entry was spent. |
hours |
decimal | optional | The current amount of time tracked. If provided, the time entry will be created with the specified hours and is_running will be set to false. If not provided, hours will be set to 0.0 and is_running will be set to true. |
notes |
string | optional | Any notes to be associated with the time entry. |
external_reference |
object | optional | An object containing the id , group_id , account_id , and permalink of the external reference. |
Example Request:
curl "https://api.harvestapp.com/v2/time_entries" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Harvest-Account-Id: $ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-X POST \
-H "Content-Type: application/json" \
-d '{"user_id":1782959,"project_id":14307913,"task_id":8083365,"spent_date":"2017-03-21","hours":1.0}'
Example Response:
Create a time entry via start and end time
Creates a new time entry object. Returns a time entry object and a 201 Created
response code if the call succeeded.
You should only use this method to create time entries when your account is configured to track time via start and end time. You can verify this by visiting the Settings page in your Harvest account or by checking if wants_timestamp_timers
is true in the Company API.
POST /v2/time_entries
Parameter | Type | Required | Description |
---|---|---|---|
user_id |
integer | optional | The ID of the user to associate with the time entry. Defaults to the currently authenticated user’s ID. |
project_id |
integer | required | The ID of the project to associate with the time entry. |
task_id |
integer | required | The ID of the task to associate with the time entry. |
spent_date |
date | required | The ISO 8601 formatted date the time entry was spent. |
started_time |
time | optional | The time the entry started. Defaults to the current time. Example: “8:00am”. |
ended_time |
time | optional | The time the entry ended. If provided, is_running will be set to false. If not provided, is_running will be set to true. |
notes |
string | optional | Any notes to be associated with the time entry. |
external_reference |
object | optional | An object containing the id , group_id , account_id , and permalink of the external reference. |
Example Request:
curl "https://api.harvestapp.com/v2/time_entries" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Harvest-Account-Id: $ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-X POST \
-H "Content-Type: application/json" \
-d '{"user_id":1782959,"project_id":14307913,"task_id":8083365,"spent_date":"2017-03-21","started_time":"8:00am","ended_time":"9:00am"}'
Example Response:
Update a time entry
Updates the specific time entry by setting the values of the parameters passed. Any parameters not provided will be left unchanged. Returns a time entry object and a 200 OK
response code if the call succeeded.
PATCH /v2/time_entries/{TIME_ENTRY_ID}
Parameter | Type | Description |
---|---|---|
project_id |
integer | The ID of the project to associate with the time entry. |
task_id |
integer | The ID of the task to associate with the time entry. |
spent_date |
date | The ISO 8601 formatted date the time entry was spent. |
started_time |
time | The time the entry started. Defaults to the current time. Example: “8:00am”. |
ended_time |
time | The time the entry ended. |
hours |
decimal | The current amount of time tracked. |
notes |
string | Any notes to be associated with the time entry. |
external_reference |
object | An object containing the id , group_id , account_id , and permalink of the external reference. |
Example Request:
curl "https://api.harvestapp.com/v2/time_entries/636718192" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Harvest-Account-Id: $ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-X PATCH \
-H "Content-Type: application/json" \
-d '{"notes":"Updated notes"}'
Example Response:
Delete a time entry’s external reference
Delete a time entry’s external reference. Returns a 200 OK
response code if the call succeeded.
DELETE /v2/time_entries/{TIME_ENTRY_ID}/external_reference
Example Request:
curl
"https://api.harvestapp.com/v2/time_entries/636718192/external_reference" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Harvest-Account-Id: $ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-X DELETE
Delete a time entry
Delete a time entry. Deleting a time entry is only possible if it’s not closed and the associated project and task haven’t been archived. However, Admins can delete closed entries. Returns a 200 OK
response code if the call succeeded.
DELETE /v2/time_entries/{TIME_ENTRY_ID}
Example Request:
curl "https://api.harvestapp.com/v2/time_entries/636718192" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Harvest-Account-Id: $ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-X DELETE
Restart a stopped time entry
Restarting a time entry is only possible if it isn’t currently running. Returns a 200 OK
response code if the call succeeded.
PATCH /v2/time_entries/{TIME_ENTRY_ID}/restart
Example Request:
curl "https://api.harvestapp.com/v2/time_entries/662202797/restart" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Harvest-Account-Id: $ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-X PATCH
Example Response:
Stop a running time entry
Stopping a time entry is only possible if it’s currently running. Returns a 200 OK
response code if the call succeeded.
PATCH /v2/time_entries/{TIME_ENTRY_ID}/stop
Example Request:
curl "https://api.harvestapp.com/v2/time_entries/662202797/stop" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Harvest-Account-Id: $ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-X PATCH
Example Response: