Harvest Time Reporting
/install harvest-time-reporting-api
Harvest API
Description
Integration with Harvest time tracking software (API v2).
Setup
Environment Variables
HARVEST_ACCESS_TOKEN- Get from https://id.getharvest.com/developersHARVEST_ACCOUNT_ID- Your Harvest account ID
Authentication
All requests require these headers:
Authorization: Bearer $HARVEST_ACCESS_TOKEN
Harvest-Account-Id: $HARVEST_ACCOUNT_ID
User-Agent: YourApp ([email protected])
API Reference
Base URL: https://api.harvestapp.com/v2
Time Entries
List Time Entries
curl "https://api.harvestapp.com/v2/time_entries" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Query parameters: user_id, client_id, project_id, task_id, external_reference_id, is_billed, is_running, updated_since, from, to, page, per_page
Create Time Entry (duration)
curl "https://api.harvestapp.com/v2/time_entries" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X POST \
-d '{"project_id":12345,"task_id":67890,"spent_date":"2024-01-15","hours":2.5}'
Create Time Entry (start/end time)
curl "https://api.harvestapp.com/v2/time_entries" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X POST \
-d '{"project_id":12345,"task_id":67890,"spent_date":"2024-01-15","started_time":"9:00am","ended_time":"11:30am"}'
Get Time Entry
curl "https://api.harvestapp.com/v2/time_entries/{TIME_ENTRY_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Update Time Entry
curl "https://api.harvestapp.com/v2/time_entries/{TIME_ENTRY_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X PATCH \
-d '{"hours":3.0,"notes":"Updated notes"}'
Delete Time Entry
curl "https://api.harvestapp.com/v2/time_entries/{TIME_ENTRY_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-X DELETE
Restart a Stopped Timer
curl "https://api.harvestapp.com/v2/time_entries/{TIME_ENTRY_ID}/restart" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-X PATCH
Stop a Running Timer
curl "https://api.harvestapp.com/v2/time_entries/{TIME_ENTRY_ID}/stop" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-X PATCH
Projects
List Projects
curl "https://api.harvestapp.com/v2/projects" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Query parameters: is_active, client_id, updated_since, page, per_page
Get Project
curl "https://api.harvestapp.com/v2/projects/{PROJECT_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Create Project
curl "https://api.harvestapp.com/v2/projects" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X POST \
-d '{"client_id":12345,"name":"New Project","is_billable":true,"bill_by":"Project","budget_by":"project"}'
Update Project
curl "https://api.harvestapp.com/v2/projects/{PROJECT_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X PATCH \
-d '{"name":"Updated Project Name"}'
Delete Project
curl "https://api.harvestapp.com/v2/projects/{PROJECT_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-X DELETE
Project User Assignments
List User Assignments for Project
curl "https://api.harvestapp.com/v2/projects/{PROJECT_ID}/user_assignments" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Create User Assignment
curl "https://api.harvestapp.com/v2/projects/{PROJECT_ID}/user_assignments" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X POST \
-d '{"user_id":12345}'
Project Task Assignments
List Task Assignments for Project
curl "https://api.harvestapp.com/v2/projects/{PROJECT_ID}/task_assignments" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Create Task Assignment
curl "https://api.harvestapp.com/v2/projects/{PROJECT_ID}/task_assignments" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X POST \
-d '{"task_id":12345}'
Tasks
List Tasks
curl "https://api.harvestapp.com/v2/tasks" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Query parameters: is_active, updated_since, page, per_page
Get Task
curl "https://api.harvestapp.com/v2/tasks/{TASK_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Create Task
curl "https://api.harvestapp.com/v2/tasks" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X POST \
-d '{"name":"New Task","default_hourly_rate":100.0}'
Update Task
curl "https://api.harvestapp.com/v2/tasks/{TASK_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X PATCH \
-d '{"name":"Updated Task Name"}'
Delete Task
curl "https://api.harvestapp.com/v2/tasks/{TASK_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-X DELETE
Clients
List Clients
curl "https://api.harvestapp.com/v2/clients" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Query parameters: is_active, updated_since, page, per_page
Get Client
curl "https://api.harvestapp.com/v2/clients/{CLIENT_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Create Client
curl "https://api.harvestapp.com/v2/clients" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X POST \
-d '{"name":"New Client","currency":"USD"}'
Update Client
curl "https://api.harvestapp.com/v2/clients/{CLIENT_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X PATCH \
-d '{"name":"Updated Client Name"}'
Delete Client
curl "https://api.harvestapp.com/v2/clients/{CLIENT_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-X DELETE
Contacts
List Contacts
curl "https://api.harvestapp.com/v2/contacts" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Query parameters: client_id, updated_since, page, per_page
Get Contact
curl "https://api.harvestapp.com/v2/contacts/{CONTACT_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Create Contact
curl "https://api.harvestapp.com/v2/contacts" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X POST \
-d '{"client_id":12345,"first_name":"John","last_name":"Doe","email":"[email protected]"}'
Update Contact
curl "https://api.harvestapp.com/v2/contacts/{CONTACT_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X PATCH \
-d '{"email":"[email protected]"}'
Delete Contact
curl "https://api.harvestapp.com/v2/contacts/{CONTACT_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-X DELETE
Users
List Users
curl "https://api.harvestapp.com/v2/users" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Query parameters: is_active, updated_since, page, per_page
Get Current User
curl "https://api.harvestapp.com/v2/users/me" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Get User
curl "https://api.harvestapp.com/v2/users/{USER_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Create User
curl "https://api.harvestapp.com/v2/users" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X POST \
-d '{"first_name":"Jane","last_name":"Doe","email":"[email protected]"}'
Update User
curl "https://api.harvestapp.com/v2/users/{USER_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X PATCH \
-d '{"first_name":"Janet"}'
Delete User
curl "https://api.harvestapp.com/v2/users/{USER_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-X DELETE
User Project Assignments
List Project Assignments for Current User
curl "https://api.harvestapp.com/v2/users/me/project_assignments" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
List Project Assignments for User
curl "https://api.harvestapp.com/v2/users/{USER_ID}/project_assignments" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Billable Rates
List Billable Rates for User
curl "https://api.harvestapp.com/v2/users/{USER_ID}/billable_rates" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Create Billable Rate
curl "https://api.harvestapp.com/v2/users/{USER_ID}/billable_rates" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X POST \
-d '{"amount":150.0,"start_date":"2024-01-01"}'
Cost Rates
List Cost Rates for User
curl "https://api.harvestapp.com/v2/users/{USER_ID}/cost_rates" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Create Cost Rate
curl "https://api.harvestapp.com/v2/users/{USER_ID}/cost_rates" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X POST \
-d '{"amount":75.0,"start_date":"2024-01-01"}'
Invoices
List Invoices
curl "https://api.harvestapp.com/v2/invoices" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Query parameters: client_id, project_id, updated_since, from, to, state, page, per_page
Get Invoice
curl "https://api.harvestapp.com/v2/invoices/{INVOICE_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Create Invoice
curl "https://api.harvestapp.com/v2/invoices" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X POST \
-d '{"client_id":12345,"subject":"Invoice for January","due_date":"2024-02-15","line_items":[{"kind":"Service","description":"Consulting","unit_price":150,"quantity":10}]}'
Update Invoice
curl "https://api.harvestapp.com/v2/invoices/{INVOICE_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X PATCH \
-d '{"subject":"Updated Invoice Subject"}'
Delete Invoice
curl "https://api.harvestapp.com/v2/invoices/{INVOICE_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-X DELETE
Invoice Line Items
Create Invoice Line Item
curl "https://api.harvestapp.com/v2/invoices/{INVOICE_ID}/line_items" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X PATCH \
-d '{"line_items":[{"kind":"Service","description":"Additional work","unit_price":100,"quantity":5}]}'
Invoice Payments
List Payments for Invoice
curl "https://api.harvestapp.com/v2/invoices/{INVOICE_ID}/payments" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Create Payment
curl "https://api.harvestapp.com/v2/invoices/{INVOICE_ID}/payments" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X POST \
-d '{"amount":500.0,"paid_at":"2024-01-20T00:00:00Z"}'
Invoice Messages
List Messages for Invoice
curl "https://api.harvestapp.com/v2/invoices/{INVOICE_ID}/messages" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Send Invoice
curl "https://api.harvestapp.com/v2/invoices/{INVOICE_ID}/messages" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X POST \
-d '{"recipients":[{"email":"[email protected]"}],"subject":"Invoice #123","body":"Please find attached invoice."}'
Invoice Item Categories
List Invoice Item Categories
curl "https://api.harvestapp.com/v2/invoice_item_categories" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Estimates
List Estimates
curl "https://api.harvestapp.com/v2/estimates" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Query parameters: client_id, updated_since, from, to, state, page, per_page
Get Estimate
curl "https://api.harvestapp.com/v2/estimates/{ESTIMATE_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Create Estimate
curl "https://api.harvestapp.com/v2/estimates" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X POST \
-d '{"client_id":12345,"subject":"Project Estimate","line_items":[{"kind":"Service","description":"Development","unit_price":150,"quantity":40}]}'
Expenses
List Expenses
curl "https://api.harvestapp.com/v2/expenses" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Query parameters: user_id, client_id, project_id, is_billed, updated_since, from, to, page, per_page
Get Expense
curl "https://api.harvestapp.com/v2/expenses/{EXPENSE_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Create Expense
curl "https://api.harvestapp.com/v2/expenses" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X POST \
-d '{"project_id":12345,"expense_category_id":67890,"spent_date":"2024-01-15","total_cost":50.00,"notes":"Office supplies"}'
Update Expense
curl "https://api.harvestapp.com/v2/expenses/{EXPENSE_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X PATCH \
-d '{"notes":"Updated expense notes"}'
Delete Expense
curl "https://api.harvestapp.com/v2/expenses/{EXPENSE_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-X DELETE
Expense Categories
List Expense Categories
curl "https://api.harvestapp.com/v2/expense_categories" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Query parameters: is_active, updated_since, page, per_page
Get Expense Category
curl "https://api.harvestapp.com/v2/expense_categories/{EXPENSE_CATEGORY_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Create Expense Category
curl "https://api.harvestapp.com/v2/expense_categories" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X POST \
-d '{"name":"Travel"}'
Reports
Time Reports - Clients
curl "https://api.harvestapp.com/v2/reports/time/clients" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-G \
-d "from=2024-01-01" \
-d "to=2024-01-31"
Time Reports - Projects
curl "https://api.harvestapp.com/v2/reports/time/projects" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-G \
-d "from=2024-01-01" \
-d "to=2024-01-31"
Time Reports - Tasks
curl "https://api.harvestapp.com/v2/reports/time/tasks" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-G \
-d "from=2024-01-01" \
-d "to=2024-01-31"
Time Reports - Team
curl "https://api.harvestapp.com/v2/reports/time/team" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-G \
-d "from=2024-01-01" \
-d "to=2024-01-31"
Uninvoiced Report
curl "https://api.harvestapp.com/v2/reports/uninvoiced" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-G \
-d "from=2024-01-01" \
-d "to=2024-01-31"
Expense Reports - Clients
curl "https://api.harvestapp.com/v2/reports/expenses/clients" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-G \
-d "from=2024-01-01" \
-d "to=2024-01-31"
Expense Reports - Projects
curl "https://api.harvestapp.com/v2/reports/expenses/projects" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-G \
-d "from=2024-01-01" \
-d "to=2024-01-31"
Expense Reports - Categories
curl "https://api.harvestapp.com/v2/reports/expenses/categories" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-G \
-d "from=2024-01-01" \
-d "to=2024-01-31"
Expense Reports - Team
curl "https://api.harvestapp.com/v2/reports/expenses/team" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-G \
-d "from=2024-01-01" \
-d "to=2024-01-31"
Project Budget Report
curl "https://api.harvestapp.com/v2/reports/project_budget" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Company
Get Company
curl "https://api.harvestapp.com/v2/company" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Update Company
curl "https://api.harvestapp.com/v2/company" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X PATCH \
-d '{"wants_timestamp_timers":true}'
Roles
List Roles
curl "https://api.harvestapp.com/v2/roles" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Get Role
curl "https://api.harvestapp.com/v2/roles/{ROLE_ID}" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])"
Create Role
curl "https://api.harvestapp.com/v2/roles" \
-H "Authorization: Bearer $HARVEST_ACCESS_TOKEN" \
-H "Harvest-Account-Id: $HARVEST_ACCOUNT_ID" \
-H "User-Agent: MyApp ([email protected])" \
-H "Content-Type: application/json" \
-X POST \
-d '{"name":"Developer","user_ids":[12345,67890]}'
Pagination
All list endpoints support pagination with page and per_page parameters. Responses include:
page: Current page numbertotal_pages: Total number of pagestotal_entries: Total number of recordsnext_page: Next page number (null if last page)previous_page: Previous page number (null if first page)
Rate Limiting
Harvest API has a rate limit of 100 requests per 15 seconds. Response headers include:
X-Rate-Limit-Limit: Request limitX-Rate-Limit-Remaining: Remaining requestsX-Rate-Limit-Reset: Seconds until limit resets
Changelog
v1.0.0
- Initial release with full API v2 coverage
- Time entries, projects, tasks, clients, contacts
- Users, billable rates, cost rates
- Invoices, estimates, payments, messages
- Expenses and expense categories
- Reports (time, expense, project budget)
- Company and roles management
- Make sure OpenClaw is installed (local or Docker)
- Run the install command in chat:
/install harvest-time-reporting-api - After installation, invoke the skill by name or use
/harvest-time-reporting-api - Provide required inputs per the skill's parameter spec and get structured output
What is Harvest Time Reporting?
Integrate with the Harvest API to manage time entries, projects, tasks, clients, and user assignments for detailed time tracking and reporting. It is an AI Agent Skill for Claude Code / OpenClaw, with 1776 downloads so far.
How do I install Harvest Time Reporting?
Run "/install harvest-time-reporting-api" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.
Is Harvest Time Reporting free?
Yes, Harvest Time Reporting is completely free (open-source). You can download, install and use it at no cost.
Which platforms does Harvest Time Reporting support?
Harvest Time Reporting is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).
Who created Harvest Time Reporting?
It is built and maintained by zachgodsell93 (@zachgodsell93); the current version is v1.0.0.