Export Clockify time entries to Google Sheets, including the per-user endpoint that hides your team's hours and the ISO durations that will not sum.
Clockify has two APIs on two different hosts, and choosing the wrong one is the main reason people struggle. The familiar time-entries endpoint is scoped to a single user, so a team export turns into a loop over every member. The Reports API returns the whole workspace in one request. Add durations that arrive as ISO strings and refuse to sum, and that is most of what there is to know.
The two-minute option: report export
In Clockify open Reports → Detailed, set the date range and any filters, and export to CSV or Excel. This is available on the free plan and gives you exactly the table most people want. Import into Sheets via File → Import.
Clockify to Google Sheets for free (Apps Script + Reports API)
Generate an API key from your profile settings → API, sent as an X-Api-Key header. Get your workspace ID from /v1/workspaces.
Use the Reports API host, reports.api.clockify.me, not the main one. Its detailed report endpoint takes a POST with a JSON body describing the range and returns entries across every user, which is what makes team reporting practical.
function importClockifyEntries() { const API_KEY = "YOUR_API_KEY"; const WORKSPACE_ID = "YOUR_WORKSPACE_ID"; const headers = { "X-Api-Key": API_KEY, "Content-Type": "application/json", }; // Reports API is a different host from api.clockify.me and returns the // whole workspace, rather than one user at a time. const url = "https://reports.api.clockify.me/v1/workspaces/" + WORKSPACE_ID + "/reports/detailed"; const rows = []; let page = 1; while (true) { const payload = { dateRangeStart: "2026-06-01T00:00:00.000Z", dateRangeEnd: "2026-07-01T00:00:00.000Z", detailedFilter: { page: page, pageSize: 1000, sortColumn: "DATE" }, exportType: "JSON", }; const res = JSON.parse(UrlFetchApp.fetch(url, { method: "post", headers: headers, payload: JSON.stringify(payload), muteHttpExceptions: true, }).getContentText()); if (res.message) throw new Error(res.message); const entries = res.timeentries || []; if (!entries.length) break; entries.forEach((e) => { rows.push([ e.userName, e.clientName || "", e.projectName || "", e.taskName || "", e.description || "", e.timeInterval.start, e.timeInterval.end || "", // Reports API gives duration in seconds; convert to decimal hours // so the column actually sums in Sheets. Math.round((e.timeInterval.duration / 3600) * 100) / 100, e.billable, ]); }); if (entries.length < 1000) break; page++; } const header = ["User","Client","Project","Task","Description", "Start","End","Hours","Billable"]; const ss = SpreadsheetApp.getActiveSpreadsheet(); const sheet = ss.getSheetByName("Clockify") || ss.insertSheet("Clockify"); sheet.clearContents(); sheet.getRange(1, 1, 1, header.length).setValues([header]); if (rows.length) { sheet.getRange(2, 1, rows.length, header.length).setValues(rows); }} // If you use the main API instead, durations look like "PT1H30M".function isoDurationToHours(iso) { const m = /PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?/.exec(iso || ""); if (!m) return 0; return (Number(m[1] || 0)) + (Number(m[2] || 0)) / 60 + (Number(m[3] || 0)) / 3600;}The duration handling is the part worth copying. The Reports API returns seconds, which divide cleanly into decimal hours. The main API returns ISO 8601 strings like PT1H30M, which look like data but behave like text, so the helper above parses them. Writing those strings straight into a sheet produces a column that cannot be summed.
Limits: Clockify rate limits per key, and Apps Script stops at six minutes, so long date ranges on a busy workspace should be split across scheduled runs by month.
The Brooked method
Brooked uses the Reports API so one import covers the whole workspace rather than looping users, converts durations to decimal hours that sum correctly, and resolves client, project and task names rather than leaving IDs. Billable and non-billable time arrive as separate columns ready for invoicing.
Step 1: Install Brooked
Install Brooked from the Google Workspace Marketplace. Free tier includes 100 imports per month, no credit card required.
Step 2: Connect Clockify
Choose Clockify in Brooked and paste an API key from your profile settings. Pick the workspace, a date range, and optionally filter by client or project, then import.
Step 3: Schedule the refresh
Set the import to re-run daily or weekly so timesheets and billing summaries are ready when invoicing runs, rather than requiring someone to export first.
Method comparison
| Method | Cost | Setup | Refresh | Two-way | Best for |
|---|---|---|---|---|---|
| Clockify report export | Free | 2 min | Manual | No | A one-off report export |
| Apps Script + Reports API | Free | 25 to 40 min | Time-driven trigger | No | Whole-workspace data on a schedule |
| Scheduled reports | Paid plans | 5 min | Emailed on schedule | No | Recurring email delivery, not live sheets |
| Brooked | Free tier · Pro $29/user/mo | ~3 min | Scheduled (hourly, daily, weekly) | No | Scheduled timesheet and billing reports |
Common use cases
- Client billing: billable hours per client and project ready for invoicing
- Budget tracking: logged hours against project estimates, with variance
- Utilisation: billable versus non-billable time per person
- Payroll support: hours per person per period for contractor payments
- Profitability: join hours against rates and revenue already in the sheet
Troubleshooting common issues
Related Articles
- How to Connect Monday.com to Google Sheets
- How to Connect ClickUp to Google Sheets
- How to Connect Asana to Google Sheets
Frequently asked questions
Why does the Clockify API only return my own time entries?
The time-entries endpoint is scoped to a single user: the path itself contains a user ID. Fetching a whole team that way means looping over every workspace member. The Reports API is the better tool for team-wide data, since one request against the detailed report endpoint returns entries across all users.
Why won't Clockify durations sum in Sheets?
Durations come back as ISO 8601 strings such as PT1H30M, which Sheets treats as text. Parse them into hours before writing, or Sheets will happily concatenate them and produce nonsense totals. The Reports API can also return duration in seconds, which is easier to work with.
Can I export Clockify to Google Sheets for free?
Yes. Clockify's reports export to CSV, Excel and PDF on the free plan, which covers a one-off. The API is also available free, and the Apps Script method here runs on a free trigger. Scheduled email reports are a paid feature, but scheduling your own import is not.
Where do I find my workspace and user IDs?
Call /v1/workspaces to list workspaces you belong to and read the id from the one you want, and /v1/user for your own user object. Both are also visible in the Clockify web app URL when you are inside a workspace, though the API listing is more reliable.
What is the difference between the main API and the Reports API?
They live on different hosts. The main API at api.clockify.me handles CRUD on entries, projects and users. The Reports API at reports.api.clockify.me generates aggregated and detailed reports across the workspace, takes POST requests with a JSON body describing the report, and returns far more per request. For exporting to a spreadsheet, the Reports API is almost always the right one.
Can I write time entries back from Sheets?
The API supports creating entries, so it is technically possible. It is rarely a good idea: bulk-created time entries from a spreadsheet bypass the review that makes timesheets trustworthy for billing. Brooked treats Clockify as read-only for reporting.
Connect Clockify to Google Sheets today.
Free tier: 100 imports per month, no credit card required. Or see the full Clockify integration details.
Install Brooked free →

