← Back to Data & Analytics
Data & Analytics by @zachgodsell93

harvest-time-reporting-api

Integration with Harvest time

0
Source Code

Harvest API

Description

Integration with Harvest time tracking software (API v2).

Setup

Environment Variables

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 number
  • total_pages: Total number of pages
  • total_entries: Total number of records
  • next_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 limit
  • X-Rate-Limit-Remaining: Remaining requests
  • X-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