Requirements
- Target platform
- OpenClaw
- Install method
- Manual import
- Extraction
- Extract archive
- Prerequisites
- OpenClaw
- Primary doc
- SKILL.md
Integrate with the Harvest API to manage time entries, projects, tasks, clients, and user assignments for detailed time tracking and reporting.
Integrate with the Harvest API to manage time entries, projects, tasks, clients, and user assignments for detailed time tracking and reporting.
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete.
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run.
Integration with Harvest time tracking software (API v2).
HARVEST_ACCESS_TOKEN - Get from https://id.getharvest.com/developers HARVEST_ACCOUNT_ID - Your Harvest account ID
All requests require these headers: Authorization: Bearer $HARVEST_ACCESS_TOKEN Harvest-Account-Id: $HARVEST_ACCOUNT_ID User-Agent: YourApp (your@email.com)
Base URL: https://api.harvestapp.com/v2
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 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 (me@example.com)" \ -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 (me@example.com)" \ -X PATCH
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 DELETE
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}'
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}'
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 DELETE
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 DELETE
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 DELETE
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 DELETE
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)"
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"}'
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"}'
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 DELETE
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}]}'
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"}'
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."}'
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)"
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}]}'
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 DELETE
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"}'
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)"
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}'
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]}'
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)
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
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
Code helpers, APIs, CLIs, browser automation, testing, and developer operations.
Largest current source with strong distribution and engagement signals.