Utilization Tracker (Harvest)
The same weekly utilization report as utilization-tracker, read from Harvest instead of a spreadsheet.
Which one do I want?
| reads from | use when | |
|---|---|---|
utilization-tracker |
a TimeLog Google Sheet |
the firm tracks time in a sheet, or not consistently anywhere |
utilization-tracker-harvest |
the Harvest API | the firm actually runs Harvest |
Identical output. If you run Harvest, use this one — the sheet version means somebody re-keys hours that already exist.
What it does
Fetches time entries via the harvest connector, filters them to the trailing 7 days on spent_date, and reports per person: total hours, billable hours, utilization against your target, and realized revenue at each entry's billable_rate. Plus a firm line, anyone under target, anyone over capacity, and hours rolled up by client.
No AI in this workflow at all
Utilization is a number a partner acts on — a conversation with someone about their week, or a decision to hire. It is computed in python or it is not produced. No model touches this pipeline.
Two honest limits
It measures logged time. Hours nobody entered are invisible, so a low number means a slow week or an unlogged one. Pair it with a timesheet reminder if logging is the real problem.
It checks for a truncated fetch. The harvest connector publishes truncated when its page cap stopped the walk. This workflow reads that flag and prints an *** INCOMPLETE banner. A utilization figure computed from a partial fetch under-reports and still looks perfectly reasonable, which is the worst kind of wrong. If you see the banner, narrow the connector's date range.
Setup
1. Install the connector
Install harvest from the Hub.
2. Harvest credentials — there are two
At https://id.getharvest.com/developers, create a personal access token. That page shows a token and an Account ID. Harvest needs both, and a valid token on its own returns a 401 that reads like a bad token.
<<HARVEST_ACCESS_TOKEN>><<HARVEST_ACCOUNT_ID>>
3. The other placeholders
<<HARVEST_FROM_DATE>>— see below<<UTILIZATION_TARGET>>— target percentage, e.g.65<<WEEKLY_CAPACITY_HOURS>>— hours in a full week, e.g.40<<PRACTICE_LEAD_PUBLISHER>>— who receives the report
Why from is a fixed date and not "seven days ago"
IML's {{date(pattern)}} macro formats the current date and takes no offset — the resolver calls LocalDateTime.now().format(pattern), so "minus seven days" cannot be written in a task property.
So the connector fetches from <<HARVEST_FROM_DATE>> to today, and the compose task does the real windowing on spent_date. Set the from-date to the start of your fiscal year and leave it. It only bounds how much history Harvest has to page through; it does not affect the report.
4. Schedule
Weekly, Friday afternoon or Monday morning.
Customization
- Window.
WINDOWincompose, in days. 28 gives a monthly view — no change needed to the fetch. - Target and capacity. Set capacity to the billable-day reality, not the contractual one.
- One person. The connector takes
userId; set it on thefetchtask for a single-person report. - Standard vs realized rates. This uses each entry's
billable_rate. Harvest also exposes cost rates on the user record if you want margin rather than revenue.
Source
workflow.iml