← Back to Skills Marketplace
zachgodsell93

Harvest Time Reporting

by zachgodsell93 · GitHub ↗ · v1.0.0
cross-platform ⚠ suspicious
1776
Downloads
3
Stars
0
Active Installs
1
Versions
Install in OpenClaw
/install harvest-time-reporting-api
Description
Integrate with the Harvest API to manage time entries, projects, tasks, clients, and user assignments for detailed time tracking and reporting.
README (SKILL.md)

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
Usage Guidance
This skill appears to be a normal Harvest API integration, but the package metadata omitted the two environment variables the instructions require. Before installing or enabling it: (1) treat HARVEST_ACCESS_TOKEN as a secret — create a least-privilege Harvest personal access token for this use and rotate it if shared; (2) confirm the skill manifest is corrected to declare HARVEST_ACCESS_TOKEN and HARVEST_ACCOUNT_ID so automated tooling and reviewers can see the requirement; (3) verify the skill's source/owner (unknown here) and prefer skills from known maintainers; (4) if you allow the agent to use this skill, ensure your agent's network and secret-management policies prevent accidental exfiltration and that the token will only be sent to api.harvestapp.com; and (5) if you are uncomfortable with providing credentials, consider using a proxy service or human-in-the-loop for actions that require the token.
Capability Analysis
Type: OpenClaw Skill Name: harvest-time-reporting-api Version: 1.0.0 The skill bundle provides a comprehensive API reference for Harvest time tracking, using standard `curl` commands to interact with the legitimate `https://api.harvestapp.com/v2` endpoint. It correctly uses environment variables (`HARVEST_ACCESS_TOKEN`, `HARVEST_ACCOUNT_ID`) for authentication. There is no evidence of prompt injection against the agent, malicious execution, data exfiltration to unauthorized destinations, persistence mechanisms, or obfuscation in `skill.md` or `_meta.json`.
Capability Assessment
Purpose & Capability
The SKILL.md provides a straightforward Harvest API integration (time entries, projects, etc.), which aligns with the skill name. However the published metadata has no description and does not declare the environment variables that the instructions require, so the manifest does not fully represent the skill's real purpose and needs.
Instruction Scope
The runtime instructions explicitly require two environment variables (HARVEST_ACCESS_TOKEN and HARVEST_ACCOUNT_ID) and show curl examples that will send those credentials to https://api.harvestapp.com/v2. The SKILL.md does not ask the agent to read unrelated files or other system secrets, but it does rely on environment-stored secrets that are not declared in the registry metadata — a discrepancy that matters for reviewers and for automated provisioning/permission controls.
Install Mechanism
This is an instruction-only skill with no install spec and no code files, so nothing is written to disk and no external packages are fetched. That limits installation risk.
Credentials
The skill requires two sensitive values (a bearer token and an account ID) according to SKILL.md, but the registry entry lists no required environment variables or primary credential. The required secrets are proportional to the Harvest integration itself, but the manifest omission is a mismatch that can hide credential needs from users and automated checks.
Persistence & Privilege
The skill does not request always:true and has no install actions that modify other skills or system-wide settings. It relies on runtime network calls, which is expected for an API integration.
How to Use
  1. Make sure OpenClaw is installed (local or Docker)
  2. Run the install command in chat: /install harvest-time-reporting-api
  3. After installation, invoke the skill by name or use /harvest-time-reporting-api
  4. Provide required inputs per the skill's parameter spec and get structured output
Version History
v1.0.0
Initial release of the Harvest Time Tracking API skill. - Provides integration with Harvest's time tracking API (v2). - Supports management of time entries, projects, tasks, and clients through documented endpoints. - Includes setup instructions with required environment variables and authentication headers. - Offers detailed cURL examples for listing, creating, updating, and deleting entities. - Supports user and task assignments within projects.
Metadata
Slug harvest-time-reporting-api
Version 1.0.0
License
All-time Installs 0
Active Installs 0
Total Versions 1
Frequently Asked Questions

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.

💬 Comments