Export Harvest to Excel: Report Downloads, Full CSV, or a Power Query Refresh
To export Harvest to Excel, open Reports, run a time report (or a detailed time report) for the date range you need, and choose the Excel or CSV export. That covers most requests. Administrators who want every hour ever tracked can use Settings > Import/Export > Export all time, which produces one CSV of all company time. If the workbook has to stay current without anyone downloading a new file each week, connect Excel to the Harvest API with Power Query and press Refresh instead.
Which route fits depends on two questions: how much of the account you need, and how often the numbers change. This guide walks through each one, including a Power Query script you can paste, and ends with the case Harvest cannot help with: a timesheet that only exists as a PDF or a paper printout. If you need JSON for an app rather than a spreadsheet, the Export Harvest to JSON guide covers the API side in more depth.
What you can export from Harvest, and who can do it
Harvest’s Exporting data article lists the exports by section. The ones people usually want in Excel:
| Data | Where in Harvest | Formats | Who |
|---|---|---|---|
| Time entries for a range | Reports > Time | Excel, CSV | Anyone, for the data they can see |
| Detailed time | Reports > New report > Detailed time | Excel, CSV, PDF | Anyone, for the data they can see |
| Saved custom report | Reports > Saved reports | Excel, CSV, PDF | Whoever saved it |
| All company time | Settings > Import/Export | CSV | Administrators |
| Detailed expenses | Reports > New report > Detailed expense | Excel, CSV, PDF | Anyone, if the plan includes expenses |
| Contractor time | Reports > Contractor | Excel, CSV | Administrators |
| Profitability | Reports > Profitability | Excel, CSV | Administrators, if the plan includes it |
| Projects, tasks, people, clients | Projects, Manage, Team | Excel, CSV | Administrators and permitted managers |
Permissions shape every export. Administrators can report on the whole account, managers on the projects and people they manage, and members only on themselves. If a colleague’s hours are missing from your file, check your role before you blame the export.
Route 1: Download a time report as Excel or CSV
This is the right answer for a monthly billing check, a payroll handoff, or a one-off client question.
- Go to Reports > Time and set the timeframe. Filter by client, project, task, or person if you only need part of the account.
- Use the export option and pick Excel or CSV. Harvest says the export includes detailed information for each time entry in the report you are viewing, not just the totals on screen.
- For more control, build a Detailed time report under Reports > New report. Its Excel and CSV files carry more columns than the interface shows. The PDF option gives you a printable copy that looks like the screen.
If your plan supports custom exports, choose Custom when exporting the time, detailed time, detailed expense, profitability, contractor, or uninvoiced report. You can then pick which columns appear and in what order, which saves deleting the same columns every month. Custom exports only come in Excel and CSV.
A report you rerun on a schedule is worth saving. Custom reports must be saved before they can be exported, and once saved you can return through Saved reports and download a fresh copy in a couple of clicks.
Excel or CSV?
Pick Excel when a person will open the file and read it. Pick CSV when the file feeds something else: a Power Query, a payroll import, or a script. CSV has no formatting to strip and imports predictably, though you should check that dates land as dates. If Excel shows dates as text after opening a CSV, import it through Data > Get Data > From File > From Text/CSV instead of double-clicking. Power Query detects column types on import, and you can correct the date locale in the editor before loading.
Route 2: Export all time from Settings
When the request is “everything”, such as an audit, an account migration, or a year-end archive, administrators can go to Settings > Import/Export and click Export all time. Harvest produces a single CSV of all company time data. Small accounts download immediately; for larger ones, Harvest emails you when the file is ready.
The same screen has Export all invoices and Export all estimates, but those produce zip files of PDFs, not spreadsheets. If you need invoice data in rows, run an invoice report from Invoices > Report and export that as Excel or CSV instead.
A full-account CSV can run to a lot of rows. Load it into Excel through From Text/CSV and choose Load To > Only Create Connection with the Data Model option ticked if you plan to summarize it with a PivotTable. You avoid filling a worksheet with every row and still get fast pivots.
Route 3: A Power Query that refreshes from the Harvest API
Downloads go stale. If a manager opens the same workbook every Monday, it is better for the workbook to fetch the data itself. Excel’s Power Query can call the Harvest API v2 directly, so a refresh pulls the latest time entries without anyone logging in to Harvest.
You need three things from Harvest’s authentication guide: a personal access token, your account ID (both come from the Developers section of Harvest ID), and a User-Agent header that names your app and gives a contact email. Harvest rejects requests without a User-Agent with a 400.
In Excel, go to Data > Get Data > From Other Sources > Blank Query, open the Advanced Editor, and paste:
let
Token = "your-personal-access-token",
AccountId = "1234567",
FromDate = "2026-01-01",
ToDate = "2026-12-31",
Headers = [
Authorization = "Bearer " & Token,
#"Harvest-Account-Id" = AccountId,
#"User-Agent" = "Excel time report (ops@example.com)"
],
GetPage = (url as text) as record =>
Json.Document(Web.Contents(url, [Headers = Headers])),
FirstUrl = "https://api.harvestapp.com/v2/time_entries?from="
& FromDate & "&to=" & ToDate,
Pages = List.Generate(
() => GetPage(FirstUrl),
each _ <> null,
each if _[links][next] = null then null else GetPage(_[links][next])
),
Entries = List.Combine(List.Transform(Pages, each _[time_entries])),
Rows = List.Transform(Entries, each [
spent_date = _[spent_date],
person = _[user][name],
client = _[client][name],
project = _[project][name],
task = _[task][name],
hours = _[hours],
rounded_hours = _[rounded_hours],
billable = _[billable],
is_billed = _[is_billed],
notes = _[notes]
]),
Table = Table.FromRecords(Rows),
Typed = Table.TransformColumnTypes(Table, {
{"spent_date", type date},
{"hours", type number},
{"rounded_hours", type number},
{"billable", type logical},
{"is_billed", type logical}
})
in
Typed
When Excel asks how to connect to api.harvestapp.com, choose Anonymous. The token travels in the header you wrote. Then click Close & Load, and every Refresh fetches the date range again.
A few details from Harvest’s time entries reference explain the script. The endpoint returns up to 2,000 entries per page by default, sorted by spent_date, and each response includes a links.next URL for the following page. The loop follows that URL until it comes back empty, so you never guess page numbers. Filters such as client_id, project_id, user_id, and is_billed go in the query string next to from and to if you only want part of the account.
If the sheet only needs totals per client, project, task, or person, the Reports API is lighter. GET /v2/reports/time/projects?from=...&to=... returns one row per project with hours already summed. Those endpoints require both dates and refuse windows longer than 365 days, and Harvest’s rate limits are tighter for them: 100 requests per 15 minutes, against 100 requests per 15 seconds for general endpoints. A workbook refreshed by hand will not get near either limit, but a dozen workbooks set to refresh every few minutes might.
Keep the token out of the file you share
The token above is written into the query, which means anyone who opens the workbook can read it in the Advanced Editor and act as you in Harvest. For a personal workbook that may be acceptable. For anything shared, create the token under a dedicated Harvest user whose permissions match what the report needs, or move the refresh to a place with proper secret storage, such as a scheduled script that writes a CSV to SharePoint for the workbook to read. Revoke the token in Harvest ID if the file leaks.
Which route to use
- One report, one time: Reports > Time or Detailed time, then Excel.
- Same report every month, fixed columns: a saved custom report with a custom export.
- Everything, for an archive or migration: Settings > Import/Export > Export all time.
- A workbook that must stay current: Power Query against the Time Entries API, or the Reports API for totals.
When the timesheet only exists as a PDF or on paper
Sometimes the Harvest account is gone, belongs to a client or subcontractor, or never existed for part of the team. What arrives is a detailed time PDF attached to an invoice, a screenshot of someone’s timesheet, or a signed paper sheet. None of the routes above can reach those, because there is no account to export from.
Excel’s own From PDF connector (Windows) can sometimes lift a clean, digitally generated table straight out of a PDF. It does not read scans, photos, or handwriting. For those, OCR has to turn the page into text first. With ocrskill.com you send the file and get Markdown back, with report tables kept as Markdown tables:
curl https://api.ocrskill.com/get-key.json
curl https://api.ocrskill.com/ocr \
-H "Authorization: Bearer sk-your-key-here" \
-H "Content-Type: application/pdf" \
--data-binary "@detailed-time-report.pdf"
A Markdown table converts to CSV with a few lines of code, or you can paste it into Excel and split columns on the | character. Check the totals against the PDF before you trust the rows, and route anything handwritten or stamped to a person for review. If the paperwork is mostly expense receipts rather than timesheets, the paperless expense management guide covers that workflow, and the image to text API post explains when Markdown OCR is a better fit than typed fields.
Conclusion
Harvest has no single “export to Excel” button because the right file depends on scope. Report exports handle filtered ranges and give you more columns in the file than on screen, Settings gives administrators one CSV of every hour, and Power Query turns the API into a workbook that updates on Refresh. Two details cause most of the trouble: permissions decide which entries appear in any export, and a token written into a shared workbook is a credential anyone can copy. Get those right and the spreadsheet stays accurate. For time records that only survive as PDFs or paper, OCR is how they get into the same sheet.
