Overview
Time Tracking
Extended REST API
Clients
Projects
Tasks
People
Expenses
Expense Tracking
User Assignment
Task Assignment
Reports
Invoices
Invoice Messages
Invoice Payments
Invoice Categories
Questions?
Email support@getharvest.com
Time Tracking API
The Time tracking API allows you to access and manipulate time entries in similar fashion to using the daily timesheet view. This allows developers to create lightweight clients or widgets to track time beyond directly interacting with Harvest through the web browser.
Retrieving entries and projects/tasks for a day
GET /daily
Retrieves entries for the today paired with the projects and tasks that can be added to the timesheet by the requesting user.
GET /daily/#{day_of_the_year}/#{year}
Optionally you may ask for entries for a given day by passing in date composed by the year and the day of the year (1..366).
HTTP Response: 200 Success
<?xml version="1.0" encoding="UTF-8"?> <daily> <for_day type="date">Wed, 18 Oct 2006</for_day> <day_entries> <day_entry> <id type="integer">195168</id> <client>Iridesco</client> <project>Harvest</project> <task>Backend Programming</task> <!-- Includes running timer if any --> <hours type="float">2.06</hours> <notes>Test api support</notes> <!-- OPTIONAL returned only if a timer is running --> <timer_started_at type="datetime"> Wed, 18 Oct 2006 09:53:06 -0000 </timer_started_at> </day_entry> <day_entry> ... </day_entry> </day_entries> <!-- These are the project-task combinations that can be added to the timesheet. Not present in readonly timesheets or for users without assigned projects. --> <projects> <project> <name>Click and Type</name> <id type="integer">3</id> <client>AFS</client> <tasks> <task> <name>Security support</name> <id type="integer">14</id> <billable type="boolean">true</billable> </task> <task> ... </task> </tasks> </project> <project> ... </project> </projects> </daily>
Toggling a timer
GET /daily/timer/#{day_entry_id}
Starts and stops a timer for a selected entry.
HTTP Response: 200 Success
<?xml version="1.0" encoding="UTF-8"?> <timer> <!-- day_entry with toggled timer --> <day_entry> <id type="integer">195168</id> <client>Iridesco</client> <project>Harvest</project> <task>Backend Programming</task> <hours>2.06</hours> <notes>Test api support</notes> <!-- OPTIONAL returned if the timer was started --> <timer_started_at type="datetime"> Wed, 18 Oct 2006 10:45:07 +0000 </timer_started_at> </day_entry> <!-- OPTIONAL if a timer for another day_entry was stopped by side effect, returns a confirmed value for the timer. Protects against different clock rates on the client side. --> <hours_for_previously_running_timer type="float"> 0.87 </hours_for_previously_running_timer> </timer>
Creating an entry
POST /daily/add
Create an entry on the daily screen
HTTP Response: 201 Created
You need to POST the following:
<request> <notes>Test api support</notes> <hours>3</hours> <project_id type="integer">3</project_id> <task_id type="integer">14</task_id> <spent_at type="date">Tue, 17 Oct 2006</spent_at> </request> Note: you can transmit a blank string as hours if you want to start a timer against the new day_entry record. For example: <hours> </hours>
You'll get the following reply:
<?xml version="1.0" encoding="UTF-8"?> <timer> <!-- new entry --> <day_entry> <id type="integer">195168</id> <client>Iridesco</client> <project>Harvest</project> <task>Backend Programming</task> <hours>0.00</hours> <notes>Test api support</notes> <!-- OPTIONAL returned only if a timer was started --> <timer_started_at type="datetime"> Wed, 17 Oct 2006 10:45:07 +0000 </timer_started_at> </day_entry> <!-- OPTIONAL returned only if a timer for another --> <!-- day_entry was stopped as a result --> <hours_for_previously_running_timer type="float"> 0.87 </hours_for_previously_running_timer> </timer>
Deleting an entry
DELETE /daily/delete/#{day_entry_id}
Deletes a day entry.
HTTP Response: 200 SuccessUpdating an entry
POST /daily/update/#{day_entry_id}
Updates the note, effort, project or task for a day entry. All sensible values are overwritten for the day entry with the data provided in your request.
HTTP Response: 200 Success
You need to POST the following:
<request> <notes>New notes</notes> <hours>1.07</hours> <project_id>52234</project_id> <task_id>67567</task_id> </request>