- Brand
- Harvest
- Category
- Productivity
- Primary Subcategory
- Time Tracking & Billing
Integration details
Description
Review the time entries, projects and invoices your Harvest account already has access to, and track time without leaving ChatGPT. Harvest only sees and changes what your Harvest permissions allow. Financial summaries are based on the invoice line items returned by Harvest; they are not an authoritative statement of project profitability.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Time Tracking & Billing
- Secondary Subcategories
- None listed
- Brand
- Harvest
- Access
- Account required
- First tracked
- 2026-10-24
- Tool count
- 37
- Market
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Agent DiscoverabilityChatGPT Discoverability ScoreUpdated dailyThe first to track the ChatGPT, Claude, Muse & Grok ecosystems, with the largest database on the core platforms. Tracked daily since .
0/100
Invisible#6of 22
in Time Tracking & Billing- Picked
- 0.0/100
- Found
- 0.0/100
- Positioned
- –/100
Category leaderboard
Time Tracking & Billing
- 1A
Aerion0
- 2C
Cleverfy0
- 3E
eHour0
- 4F
Fritto Time Tracker0
- 6H
Harvest0
Get alerts for Harvest
Get updates when Harvest’s Discoverability Score or category rank changes.
Competing in ChatGPT Time Tracking & Billing
View Category37 tools agents can invoke
Add a task to a project so time can be logged against it. Reactivates the task on the project if it was previously removed. Both the project and the task must be active — reactivate an archived project with update_project (is_active: true) first. Requires permission to edit the project.
Assign a user to a project so they can log time against it. Reactivates the assignment if it was previously removed. Requires permission to edit the project and to manage the user.
Create a client in the user's Harvest account. `name` is required. `currency_code` defaults to the company currency when omitted.
Create an expense for the authenticated user (or, for managers/admins, another user via `user_id`). Provide `total_cost` for amount-based categories, or `units` for unit-based categories (see `list_expense_categories`). Defaults to billable and to today in the user's timezone. Receipt upload is not supported.
Create a free-form draft invoice for a client. `client_id` is required; supply `line_items` for the invoice content. The invoice number is assigned automatically and the invoice is created as a draft (not sent). The response is the same shape `get_invoice` returns, including `estimate_id`, `retainer_id`, and `recurring_invoice_id` (all null for a free-form invoice created this way). To bill tracked time or expenses instead, use `create_invoice_from_tracked_time`.
Create a draft invoice for a client by importing uninvoiced billable tracked time and/or expenses for the given projects. `client_id` and `project_ids` are required, plus at least one of `time` or `expenses`. When a `time`/`expenses` block omits `from`/`to`, ALL uninvoiced billable activity for those projects is pulled. The invoice number is assigned automatically and the invoice is created as a draft (not sent). The response is the same shape `get_invoice` returns, including the `estimate_id`, `retainer_id`, and `recurring_invoice_id` linkage ids.
Create a project for an existing client. `name` and `client_id` are required. Set `hourly_rate` only when the project bills hourly; it is ignored without billable-rate permission, and implies `bill_by` "Project" unless you pass a different `bill_by`. Pass `bill_by` explicitly to bill by Tasks or People (then set those rates separately). The response echoes `billable_rate` and `rate_status` so you can confirm whether the rate was applied — a rate dropped for lack of permission, or because the project does not bill at the project level, is reported rather than silently ignored. Set `currency` (an ISO code such as "EUR") only to bill this project in a currency other than its client's; costs always stay in the account currency, and the response echoes the resolved `currency`. Omit it, or pass the client's own code, to leave the project inheriting the client's — a value equal to the client's is not stored as the project's own, so it follows the client if that changes. Also sets the project's `starts_on`/`ends_on` dates, a fixed-fee `fee`, saved invoice defaults (`invoice_due_date`, `invoice_due_date_custom_days`, `purchase_order`, `tax`, `tax2`, `discount`) when invoices are enabled, and project tags by name (`tags`) when project tags are enabled. A fee implies `is_fixed_fee` and `is_billable` true and is refused without billable-rate permission; an unsupported field is refused rather than silently ignored.
Create a new task in the Harvest account. Tasks are the kinds of work that get assigned to projects (e.g. "Design", "Development"). Set `add_to_all_projects` to also assign the new task to every active project. Requires task-management permission.
Permanently delete a time entry — your own, or a teammate's whose time you can edit in Harvest (an admin, or a manager of them or of an active project they're assigned to). The server enforces the same permissions as the web timesheet — you'll get a `not_found` error for an entry you're not allowed to delete. Entries on an invoiced or approval-locked period cannot be deleted and return a `validation_failed` error — unless you hold company-wide timer-write permission (an Administrator), which bypasses those locks here exactly as it does on the web timesheet. To zero out hours, delete the entry rather than updating it to 0.
Return the authenticated account's capabilities and tracking conventions so a caller can pre-validate before attempting an action instead of probing blind. Includes: `approval_required` (does logged time need approval), `notes_required` (every time entry must carry notes), `time_rounding` (whether hours are rounded and how), `wants_timestamp_timers` (timers track clock-in/out times vs raw durations), `week_start_day`, `time_format`, and whether the `invoice` and `expense` features are enabled. Account-level read — every authenticated user sees the same values; no per-row authorization applies.
Return a single expense with full detail: amounts, units, category (name, unit metadata), project and client names, currency, billable/invoiced/locked status, and whether a receipt is attached. Invoiced status is `is_invoiced` (true once the expense is on an invoice); the legacy `is_billed` key is a deprecated alias of it — prefer `is_invoiced`. Use `list_expenses` first to find the id. An expense the caller is not permitted to read returns `not_found`, identical to an id that does not exist.
Return a single invoice with its header (client, state, amounts, taxes, dates) and full `line_items`. Use `list_invoices` first to find the id. An invoice the caller is not permitted to read returns `not_found`, identical to an id that does not exist. The header also reports where the invoice came from via `estimate_id`, `retainer_id`, and `recurring_invoice_id` — each is the linked record's id, or null when the invoice is not linked (a non-null `recurring_invoice_id` means it was generated by a recurring schedule; `retainer_id` marks a retainer deposit).
Return budget configuration and current usage for a specific project. `scope` states whether `hours_spent`/`money_spent` cover the `current_month` (monthly-reset budgets) or `lifetime` — read it before comparing usage to a budget (`period` carries the same value and is retained for backward compatibility). For money budgets (`budget_by: project_cost|task_fees`) `money_spent` is populated; `money_spent_status` says why it is null when it is (`not_applicable` = hours-only budget, `hidden` = rate-gated, `visible` = present). Rate fields (`billable_rate`, `cost_budget`, `money_spent`, and a fees `budget`) follow the caller's billable-rate permission. An hours `budget` instead follows project-budget access, so it matches what the caller sees in the Harvest UI. For a `budget_by: person` project this `budget` is the project-wide hours total across everyone assigned; read the per-person breakdown from list_project_assignments (`users` roster), where each currently-active member you're permitted to see carries their own `budget` (those active rows need not sum exactly to this total, which can also include people no longer active). `billing_currency_code` is the project's resolved billing currency (override → client → company) that the money amounts (`money_spent`, `billable_rate`, and a money `budget`) are expressed in; `cost_budget` is in the company currency. Each field is present when visible, null when not.
Return the time entry whose timer is currently running for the authenticated user, or — for managers/admins — another team member via `user_id`. Returns null if no timer is active. Authorization is enforced server-side: a role with no cross-user timer access gets `forbidden` for any `user_id` other than its own. A manager who can read only their managed scope may see null for a `user_id` outside that scope — same as `list_time_entries` may return no entries — rather than `forbidden`. When that happens `scope_limited` is true: a null may mean "you cannot see this user's timer" rather than "no timer is running" — do not report it as the user being idle.
Aggregate time entries over a date range, grouped by project, client, or user. Each row carries total, billable, and non-billable hours, plus invoiced and uninvoiced hours, plus the group's id and display name (`project_name`/`client_name`/`user_name`). The billable split (billable/non-billable) and the invoiced split (invoiced/uninvoiced) are independent: `invoiced_hours` is what has been put on an invoice (invoice_id set), `uninvoiced_hours` is the rest — use these to answer "how many hours are (not) invoiced", e.g. with group_by=client. A `totals` object sums every hours field across all rows. The server scopes results to what the caller is allowed to see — call the tool and let the server decide; only an explicit `forbidden` error indicates a true denial.
List clients in the user's Harvest account, ordered by name. Returns up to 100 clients per page; `total_count` is how many clients match the filter in full, so when `truncated` is true you can tell how many are missing — refine `search` or `is_active` to narrow the result.
List the expense categories in the user's Harvest account, ordered by name. Use this to find the `expense_category_id` for `create_expense`. Unit-based categories report `is_unit_based: true` along with their `unit_name` and `unit_price`. Returns up to `limit` categories; `truncated` is true when more exist.
List expenses, most recent first. Filter by `project_id`, `user_id`, a `spent_at` date range (`from`/`to`), or `billable`. Defaults to the last 30 days and, when `user_id` is omitted, to everyone you're allowed to see — your own expenses as a regular member, but a manager's managed teammates or an admin's whole account. Results are scoped server-side to what the caller may read. Each row carries `is_invoiced` (true once the expense is on an invoice; the legacy `is_billed` key is a deprecated alias — prefer `is_invoiced`). Returns `limit` expenses per page (default 100, max 500); when `truncated` is true, paginate by passing `next_cursor` from the prior response back via `cursor` — keep all other parameters identical and treat the cursor as opaque (do not construct one yourself). Use `get_expense` for full detail (category, project, lock status).
List invoices, most recent first. Filter by `status` (draft/approved/open/sent/paid/late), `client_id`, issue-date range (`issued_from`/`issued_to`), an exact `due_date`, or a `search` term matched against invoice number, subject, and PO. `sent` means open and not yet past due; `late` means open and past due. Results are scoped server-side to what the caller may read. Returns `limit` invoices per page (default 100, max 500); when `truncated` is true, paginate by passing `next_cursor` from the prior response back via `cursor` — keep all other parameters identical and treat the cursor as opaque (do not construct one yourself). Each row reports where the invoice came from via `estimate_id`, `retainer_id`, and `recurring_invoice_id` — the linked record's id, or null when not linked — so you can tell recurring-generated invoices and retainer deposits apart without a second call. Use `get_invoice` for full line-item detail.
List who and what is assigned to a project, with billable rates — the data needed to compute revenue/margin (pair it with get_project_budget for cost). `assignment_type` selects one roster per call: `users` returns the assigned team members (with `is_project_manager`, `uses_default_rate`, the effective `billable_rate`, and — for a project that budgets per person — each member's own hours `budget`); `tasks` returns the assigned tasks (with `is_billable` and the task `billable_rate`). Call once per type when you need both. The per-person `budget` is populated only when the project budgets by person (get_project_budget reports `budget_by: person`); it is null for every other budget method (the budget then lives on the task or the whole project). You always see your own `budget`; you see a teammate's only when you can view all tracked time on the project (an admin or the project's manager), matching the project's Team analysis view — otherwise a teammate's `budget` is null. get_project_budget's `budget` is the project-wide hours total for such a project — broadly the sum of these per-person budgets, but it can also include people no longer active on the project, so the active rows here need not add up to it exactly. This lists ASSIGNED members/tasks, which is distinct from who has logged time — an assigned user with no entries still appears. `billable_rate` follows your role: present when you can view rates on the project, null otherwise. `billing_currency_code` is the project's resolved billing currency that every `billable_rate` in the response is expressed in. Returns `limit` rows per page (default 100, max 500); when `truncated` is true, paginate by passing `next_cursor` back via `cursor` with all other parameters identical, treating the cursor as opaque.
List projects in the user's Harvest account, ordered by project name unless `sort` is passed; each project includes its `starts_on` and `ends_on` dates (YYYY-MM-DD, or null when unset). Pass `sort: start_date_asc`/`start_date_desc` or `end_date_asc`/`end_date_desc` to order by those dates, with projects that have no date last. Each project's `billing_currency_code` is its resolved billing currency (override → client → company). Returns `limit` projects per page (default 100, max 500); `total_count` is how many projects match the filter in full. When `truncated` is true, page through the rest by passing `next_cursor` from the prior response back via `cursor` with all other parameters identical, treating the cursor as opaque — refine `search`, `client_ids`, or `is_active` only when you want a narrower result, not because the list ran out.
List tasks in the user's Harvest account, ordered by name. Returns up to 100 tasks per page; `total_count` is how many tasks match the filter in full, so when `truncated` is true you can tell how many are missing — refine `search` or `is_active` to narrow the result.
List time entries, most recent first. Defaults to the last 30 days when `from`/`to` are omitted. Each entry includes `started_time`/`ended_time` (24h "HH:MM" clock-in/out, null for duration entries). `hours` is the raw tracked duration. Each entry also carries two independent status fields: `billable` (whether the work *can* be billed) and `is_invoiced` (whether it *has* been invoiced — true once the entry is on an invoice). Neither is the same as `is_closed`, which is timesheet-approval status and says nothing about invoicing. To answer invoiced vs. uninvoiced hours, read each entry's `is_invoiced` or pass the `is_invoiced` filter — never infer invoicing from `is_closed` or `billable`. When the account configures hour rounding, each entry also includes `rounded_hours` — the same duration under the account's rounding rule, matching what shows on their Harvest reports and invoices; prefer it when the user asks "how many hours" for a rounding-configured account (accounts with no rounding configured omit `rounded_hours`, since it would equal `hours`). Returns `limit` entries per page (default 100, max 500); when `truncated` is true, paginate by passing `next_cursor` from the prior response back via `cursor` — keep all other parameters identical and treat the cursor as opaque (do not construct one yourself). Authorization is enforced server-side: a role with no cross-user read access gets `forbidden` for any `user_ids` other than its own. A manager who can read only their managed scope receives just the entries they can see for `user_ids` outside that scope (often none), rather than `forbidden`. In that case `scope_limited` is true: the page may be empty or only partial because of your permissions, not because the user logged nothing — do not treat absent or zero hours as authoritative.
List team members in the user's Harvest account, ordered by id. Returns up to 100 users per page; `total_count` is how many users match the filter in full on every page, not how many are left. Fetch the rest by calling again with the returned `next_cursor` and the same filters, until `truncated` is false. Field availability follows the caller's role — populated values reflect what's visible to you.
Log a completed time entry for the authenticated user, or — for managers/admins — another team member via `user_id`. Use this for past time you already know the duration of. To track time as it elapses, use `start_timer` instead. Provide EITHER `hours` (use at least 0.01, the smallest stored increment; positive values that would be stored as 0 are rejected) OR a `started_time` and `ended_time` pair (e.g. "9:00am" to "11:00am"), from which the duration is derived. Accounts that track timestamped timers also record the interval on the entry; accounts that track decimal hours keep only the derived duration.
Remove a task from a project. Historical time entries are preserved. Returns `removed: false` if the task was not assigned to the project. Requires permission to edit the project.
Search the Harvest Help Center for product documentation: how a feature works, setup steps, integrations, billing, permissions, and troubleshooting. Returns article excerpts with the article title, the section heading, and the canonical Help Center URL to cite back to the user. Relevance-ranked semantic search, so wording matters and there is no relevance floor: a response always carries up to `top_k` excerpts even when none are related, and `relevance_score` only orders them within that one response — read the excerpts, and rephrase and search again before concluding a topic is not documented. Documentation only: it never reads the account's own data, so answer questions about the caller's clients, projects, time, or invoices with the tools that read those instead. When `available` is false nothing is indexed and no search ran — say so and point the user at help.getharvest.com rather than retrying.
Start a new running timer on the given project + task, for the authenticated user or — for managers/admins — another team member via `user_id`. If that user already has a running timer for the same day, it is stopped first (cross-day timers are not auto-stopped — use stop_timer + start_timer in that case). Returns the running time entry.
Stop the currently running timer for the authenticated user. If `time_entry_id` is provided, stops that specific entry; otherwise stops whichever timer is running. Returns the stopped time entry, or an error if no timer is running.
Send feedback to the Harvest team. Call this only after the user agrees to send it; summarize their words and do not include data they did not choose to share. After calling, tell the user it was sent.
Submit the authenticated user's timesheet for approval over a date range (or, for managers/admins, another user's via `user_id`). Stop any running timer in the range first — submission is rejected while a timer is running. Only available when timesheet approvals are enabled for the account.
Remove a user's assignment from a project. Historical time entries are preserved. Returns `removed: false` if the user was not assigned. Requires permission to edit the project and to manage the user.
Update a client's name, address, currency, or active state. Only the supplied fields change; omit a field to leave it unchanged. Set `is_active` to false to archive the client (this is blocked while the client still has active projects — archive or reassign them first) or true to reactivate an archived one. Requires client-management permission.
Update an existing expense's amount, units, notes, billable flag, project, category, or date. Pass `delete_receipt: true` to remove an attached receipt. Uploading a receipt is not supported. The server enforces access — you'll get a `not_found` error if the expense isn't visible to you.
Update a project's name, code, billing setup, active state, or billing currency — the fields are: name, project code, type (`hourly`, `fixed_fee`, or `non_billable`), bill-by method, hourly rate, `is_active`, and `currency`. Only the supplied fields change. Set `is_active` to false to archive the project or true to reactivate an archived one — archiving a project with a running timer fails until the timer is stopped, and reactivation is blocked if the account is at its active-projects plan limit. Changing rates requires billable-rate permission. The response echoes `code`, `billable_rate`, `rate_status`, and the resolved `currency` so you can confirm what took effect — a rate that does not bill (the project is not billed at the project level) is reported as `ignored_bill_by` rather than silently kept inert. `currency` is stored as a relabel and does not convert existing amounts; costs always stay in the account currency.
Update a task: rename it, change its default billable rate, and/or archive/reactivate it via `is_active`. Only the supplied fields change. A new name must be unique among active and archived tasks in the account. Set `is_active` to false to archive the task (a task with a running timer can't be archived until the timer is stopped) or true to reactivate an archived one. Requires task-management permission. `default_hourly_rate` changes the task's default billable rate. IMPORTANT: this is retroactive and account-wide — it re-prices EVERY existing time entry on this task, with no date limit, on projects that bill by task where the assignment follows the task's default rate. Past billing data is rewritten and the previous per-entry rates are not recoverable, so confirm with the user before changing a rate on a task that already has tracked time. The rate is ignored without billable-rate permission; check the top-level `rate_status` in the response (`applied` or `ignored_no_permission`) to confirm what happened, since the echoed `default_hourly_rate` is null for callers who cannot view rates.
Update an existing time entry's hours, notes, project, task, date, or clock-in/clock-out times — your own, or a teammate's whose time you can edit in Harvest (an admin, or a manager of them or of an active project they're assigned to). The server enforces the same permissions as the web timesheet — you'll get a `not_found` error for an entry you're not allowed to edit. Set the duration with EITHER `hours` (use at least 0.01, the smallest stored increment; positive values that would be stored as 0 are rejected) OR a `started_time` and `ended_time` pair (e.g. "9:00am" to "11:00am"), which is derived into hours. Accounts that track timestamped timers also record the interval on the entry; accounts that track decimal hours keep only the derived duration. To remove an entry use `delete_time_entry`, which enforces the same permissions.
Harvest ChatGPT Plugin FAQ
How the directory, categories and Discoverability Score work.
Read the methodologyHow do I improve Harvest's ChatGPT Plugin discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are Harvest alternatives on ChatGPT?
As of 2026-10-28, Harvest competes with Aerion, Cleverfy, eHour, Fritto Time Tracker, FunkyTime, Hubstaff, Jibble, Laurel and 13 more in ChatGPT Time Tracking & Billing, ranked by public Discoverability Score.
Where does Harvest rank in Time Tracking & Billing on ChatGPT?
As of 2026-10-28, Harvest ranks #6 of 22 in ChatGPT Time Tracking & Billing with a Discoverability Score of 0/100 (Invisible).
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.