Clockify Export
Export your Clockify time entries to CSV files, even on the Free plan.
In April/May 2026, Clockify restricted the Free plan: CSV/Excel exports and reports longer than 31 days now require a paid plan. The API itself, however, is still available on the Free plan (30 requests/hour/workspace).
This tool uses the time entries API (not the reports API), so it is not subject to the 31-day reporting window. It paginates through all your entries and writes one CSV per calendar month.
Features
- ✅ Multi-workspace — exports all your workspaces (or select with
-w) - ✅ Incremental — remembers what was exported and only fetches new entries
- ✅ Monthly CSVs — one file per calendar month, current month gets re-exported/overwritten
- ✅ Per-workspace stat — state is tracked in
~/.config/clockify-export/state.json - ✅ Zero dependencies — stdlib only (
urllib,csv,json), Python ≥ 3.11 - ✅ Config file — API key + export path in
~/.config/clockify-export/config.toml
Installation
Requires uv (or any Python 3.11+ + pip).
Global install (recommended, adds clockify-export to your PATH)
uv tool install clockify-export # from PyPI
# or from a local checkout:
uv tool install .
Updates: uv tool upgrade clockify-export.
Development (from a checkout)
uv sync
Setup
1. API key
Generate an API key in Clockify: Profile → Preferences → API → Manage API Keys → Generate.
Provide it via one of (highest priority first):
# a) Config file (recommended)
clockify-export --init-config
# then edit ~/.config/clockify-export/config.toml:
#
# # Clockify export configuration
# api_key = "YOUR_KEY"
# export_dir = "export"
# b) Environment variable
export CLOCKIFY_API_KEY=YOUR_KEY
# c) .env file in the project directory
echo "CLOCKIFY_API_KEY=YOUR_KEY" > .env
# d) Command line flag
clockify-export --api-key YOUR_KEY
Note: TOML is parsed with Python's stdlib
tomllib— no extra dependency.
2. Export directory
Defaults to ./export. Override via config file or -o flag:
clockify-export -o /data/clockify
Usage
# Full export of all workspaces (everything since the beginning)
clockify-export --full
# Incremental export (default — only fetches entries after last run)
clockify-export
# Export only specific workspace(s)
clockify-export -w "Peter's workspace"
# Export since a specific date (ignores incremental state)
clockify-export --from 2026-01-01
# Show export state
clockify-export --status
Output structure
export/
└── <workspace name>/
└── <year>/
└── <workspace name>_<year>-<month>.csv
Each filename carries the workspace and year, so files stay identifiable even if you copy or move them out of the directory tree:
export/etalytics workspace/2026/etalytics workspace_2026-09.csv
CSV columns
| Column | Description |
|---|---|
Date |
Entry date (YYYY-MM-DD) |
Start |
Start time (HH:MM, UTC) |
End |
End time (HH:MM, UTC) |
Duration (h) |
Duration in decimal hours (e.g. 1.5 = 1h 30m) |
Project |
Project name |
Customer |
Client/customer name |
Task |
Task name |
Description |
Entry description |
Tags |
Comma-separated tags |
Billable |
True/False |
Hourly Rate |
Billable rate (e.g. 13.00) |
Currency |
Currency code (e.g. EUR) |
Type |
Entry type (REGULAR, BREAK, …) |
Timezone |
Timezone of the entry (e.g. Europe/Berlin) |
How incremental export works
The tool stores the last exported date per workspace in
~/.config/clockify-export/state.json:
{
"5e9d613a265d3c117c6f3aeb": {
"last_exported": "2026-09-30T00:00:00+00:00",
"updated_at": "2026-09-10T10:20:38.530213+00:00"
}
}
On the next run, entries are fetched starting the day after last_exported.
Monthly CSVs are overwritten entirely, so a partially written current month is
always consistent.
Free plan considerations
- Rate limit: 30 API requests/hour/workspace on Free plan. Each page of
200 entries = 1 request. A full export of thousands of entries can exhaust
the quota — that's why
--fromand--fullexist, and why the tool fetches tasks only for projects that actually have entries. - If you hit the rate limit (HTTP 429), wait an hour and run again — the incremental state means you won't re-fetch everything.
Related projects
- Clockify API docs
- damirarh/ClockifyExport — C# tool using shared reports (paid-only on Free plan now)
- apet97/clockify-ts-sdk — community TypeScript SDK/CLI
License
MIT
Schedule Daily Export via systemd
Use can use systemd timers to call the export regularily.
Install with mise
mise can install the systemd unit automatically:
mise install-systemd
This copies the service/timer files to ~/.config/systemd/user/ and enables the timer.
Systemd Timer (daily export)
To run the export automatically every day as a systemd user unit:
1. Install the service and timer
cp systemd/clockify-export.service "$HOME/.config/systemd/user/"
cp systemd/clockify-export.timer "$HOME/.config/systemd/user/"
systemctl --user daemon-reload
systemctl --user enable --now clockify-export.timer
2. Set your API key
The unit reads the Clockify API key from the config file.
You can create one via clockify-export --init-config and ensure the
api_key is set in ~/.config/clockify-export/config.toml.
3. Manage the timer
The default timer is for daily export. Feel free to adjust OnUnitActiveSec if desired.
# View status
systemctl --user status clockify-export.timer
systemctl --user status clockify-export.service
# Manual run
systemctl --user clockify-export
# Disable
systemctl --user disable --now clockify-export.timer
Note: The service uses
Type=oneshotso it completes and exits each day. Logs can be viewed withjournalctl --user -u clockify-export.service.
Release files for clockify-export 0.1.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| clockify_export-0.1.5.tar.gz | 24.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| clockify_export-0.1.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 39.8 kB
Release files / clockify_export-0.1.5.tar.gz
| Download URL | clockify_export-0.1.5.tar.gz |
|---|---|
| Size | 24.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d4b1e2861684cb7c21dd689b9ddb93ea9bf6426c8645a26e251a221490c48522
|
|
BLAKE2b-256 checksum How to use checksums |
9669895e9ed362ba7dd49f5bc37ad6ee11d9d0e2187460dbdd332e886430312a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.16 {"installer":{"name":"uv","version":"0.12.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / clockify_export-0.1.5-py3-none-any.whl
| Download URL | clockify_export-0.1.5-py3-none-any.whl |
|---|---|
| Size | 15.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d99cb5069054111ca1d66bf9158dbbc4cd859f077b0e2de134ba22db2027b882
|
|
BLAKE2b-256 checksum How to use checksums |
a257967af8f8b55df2de8de4b678a3a6228c65903a91d13e7142449e73c97d40
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.16 {"installer":{"name":"uv","version":"0.12.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|