- slug
- harvest-time-tracking
- display_name
- Harvest Time Tracking
- version
- 1.0.0
- tags
- [latest]
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 (your@email.com)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 (me@example.com)"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 (me@example.com)" \
-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 (me@example.com)" \
-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 (me@example.com)"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 (me@example.com)" \
-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 (me@example.com)" \
-X DELETERestart 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 (me@example.com)" \
-X PATCHStop 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 (me@example.com)" \
-X PATCHProjects
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 (me@example.com)"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 (me@example.com)"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 (me@example.com)" \
-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 (me@example.com)" \
-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 (me@example.com)" \
-X DELETEProject 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 (me@example.com)"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 (me@example.com)" \
-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 (me@example.com)"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 (me@example.com)" \
-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 (me@example.com)"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 (me@example.com)"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 (me@example.com)" \
-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 (me@example.com)" \
-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 (me@example.com)" \
-X DELETEClients
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 (me@example.com)"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 (me@example.com)"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 (me@example.com)" \
-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 (me@example.com)" \
-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 (me@example.com)" \
-X DELETEContacts
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 (me@example.com)"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 (me@example.com)"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 (me@example.com)" \
-H "Content-Type: application/json" \
-X POST \
-d '{"client_id":12345,"first_name":"John","last_name":"Doe","email":"john@example.com"}'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 (me@example.com)" \
-H "Content-Type: application/json" \
-X PATCH \
-d '{"email":"newemail@example.com"}'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 (me@example.com)" \
-X DELETEUsers
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 (me@example.com)"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 (me@example.com)"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 (me@example.com)"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 (me@example.com)" \
-H "Content-Type: application/json" \
-X POST \
-d '{"first_name":"Jane","last_name":"Doe","email":"jane@example.com"}'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 (me@example.com)" \
-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 (me@example.com)" \
-X DELETEUser 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 (me@example.com)"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 (me@example.com)"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 (me@example.com)"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 (me@example.com)" \
-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 (me@example.com)"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 (me@example.com)" \
-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 (me@example.com)"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 (me@example.com)"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 (me@example.com)" \
-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 (me@example.com)" \
-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 (me@example.com)" \
-X DELETEInvoice 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 (me@example.com)" \
-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 (me@example.com)"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 (me@example.com)" \
-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 (me@example.com)"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 (me@example.com)" \
-H "Content-Type: application/json" \
-X POST \
-d '{"recipients":[{"email":"client@example.com"}],"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 (me@example.com)"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 (me@example.com)"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 (me@example.com)"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 (me@example.com)" \
-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 (me@example.com)"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 (me@example.com)"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 (me@example.com)" \
-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 (me@example.com)" \
-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 (me@example.com)" \
-X DELETEExpense 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 (me@example.com)"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 (me@example.com)"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 (me@example.com)" \
-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 (me@example.com)" \
-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 (me@example.com)" \
-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 (me@example.com)" \
-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 (me@example.com)" \
-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 (me@example.com)" \
-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 (me@example.com)" \
-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 (me@example.com)" \
-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 (me@example.com)" \
-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 (me@example.com)" \
-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 (me@example.com)"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 (me@example.com)"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 (me@example.com)" \
-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 (me@example.com)"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 (me@example.com)"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 (me@example.com)" \
-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