Administration
Public API overview
Authenticate with an API key, choose scopes, stay within the rate limit, page through results and export approved hours.
TimeLogger ends at approved hours — it never computes pay. The public REST API is how your payroll, billing or BI tools pick those hours up. This page is a public overview; the full, always-current reference with every endpoint, parameter and example lives inside the app.
Get started#
Create a key
In WorkspaceSettings, on the API keys card, choose New key, name it after the integration, and tick only the scopes it needs. The secret is shown once — store it in your secrets manager.
Send it as a Bearer token
Every request carries
Authorization: Bearer tl_live_…. The base URL is your TimeLogger address followed by/api/v1.Read approved timesheets
Filter timesheets to
status=approved— these are the hours your approvers signed off.
curl -s "https://timelogger.example.com/api/v1/timesheets?status=approved&limit=50" \
-H "Authorization: Bearer $TIMELOGGER_API_KEY"{
"results": [
{
"id": "51050378-…",
"member_id": "9f686e4d-…",
"member_name": "Ananya Iyer",
"period_start": "2026-09-14",
"period_end": "2026-09-20",
"status": "approved",
"approved_by_name": "Neha Kapoor",
"approved_at": "2026-09-24T21:06:13Z",
…
}
],
"next_cursor": "bz0xMDA"
}How keys are limited
Scopes#
Write scopes don’t include read — tick both if an integration needs both.
| Scope | What it means |
|---|---|
| timesheets:read | Read timesheets and their approval state — the approved-hours hand-off. |
| time:read | Read time entries, the running timer, offline entries and idle blocks. |
| time:write | Create, edit, discard and attribute time entries; start, stop and switch timers. |
| projects:read | Read projects and tasks. |
| projects:write | Create and edit projects and tasks (archive instead of delete). |
| members:read | Read members, departments, teams and a member’s effective tracking policy. |
| reports:read | Read dashboards, reports, activity summaries and the published formulas. |
| exports:read | Download approved hours (CSV, XLSX, PDF or JSON) and fetch background export results. |
Export approved hours#
GET /exports/approved-hours returns only entries in approved or locked timesheets, with your workspace rounding applied. group_by picks the layout and format the file type (csv, xlsx, pdf, or json for rows inline).
curl -s -o approved-hours.csv \
"https://timelogger.example.com/api/v1/exports/approved-hours?from=2026-09-01&to=2026-09-30&group_by=harvest&format=csv" \
-H "Authorization: Bearer $TIMELOGGER_API_KEY"| group_by | What it means |
|---|---|
| member / project / task | Totals per member and period, per project and client, or per project and task. |
| entries | One row per approved entry — the most detailed hand-off. |
| daily | Member × day × project × task. Use for Xero and Deel timesheet imports. |
| harvest | Harvest’s time-import columns: Date, Client, Project, Task, Notes, Hours, First name, Last name. |
| quickbooks_time | QuickBooks import: Date (MM/DD/YYYY), Employee, Customer, Service Item, Description, Duration (H:MM). |
Rate limits#
Each key can make 600 requests a minute. Over that, requests get 429 with a Retry-After header saying how many seconds to wait. Limits are per key, so separate integrations don’t slow each other down.
HTTP/1.1 429 Too Many Requests
Retry-After: 12
{ "error": "rate_limited", "message": "Request was throttled. Expected available in 12 seconds." }Conventions#
Pagination#
Lists return { results, next_cursor }. Pass next_cursor back as cursor until it is null. limit defaults to 50, up to 200.
Formats#
- Timestamps are ISO 8601 in UTC with a
Zsuffix, for example2026-09-21T04:03:00Z. fromandtoare calendar dates (YYYY-MM-DD) in the key creator’s time zone.- Durations are whole seconds. Hours in exports are decimals rounded to 2 places. IDs are UUIDs.
POST /time-entriesandPOST /offline-entriesaccept anIdempotency-Keyheader, so a retried request never creates a duplicate.
Errors#
Every error has the same shape: a machine-readable error code, a readable message and optional details.
HTTP/1.1 403 Forbidden
{
"error": "insufficient_scope",
"message": "This API key needs the time:write scope.",
"details": { "required_scope": "time:write", "key_scopes": ["timesheets:read", "exports:read"] }
}| Status | What it means |
|---|---|
| 400 validation_error | A bad parameter or body. details maps field names to messages. |
| 401 not_authenticated | A missing, malformed, revoked or unknown key. |
| 403 insufficient_scope | The key lacks the scope; details has required_scope and key_scopes. |
| 403 forbidden / out_of_scope | The key’s creator can’t see or change that member or resource. |
| 404 not_found | No such resource in your workspace, or outside your scope. |
| 409 | Conflicts with the current state: timesheet_locked, timer_already_running, overlaps_existing_entry. |
| 422 | Allowed shape, but a policy rule forbids it: blocked_by_compliance, timer_not_available. |
| 429 rate_limited | Too many requests for this key. Wait Retry-After seconds. |
The full reference#
Signed-in owners, admins and auditors can open the complete reference at WorkspacePublic API (/app/developers). It lists every endpoint a key can reach with its scope, parameters, request and response, a curl example, and a Try it button that runs read requests with your own session. It’s generated from the server, so it always matches what the API enforces. The raw OpenAPI schema is at /api/v1/schema, and an interactive explorer at /api/v1/docs.
Questions#
Can a key create API keys or change policies?
Can I change a key’s scopes later?
How do I get very large exports?
Does the API return screenshots?
Something unclear or out of date? Tell your workspace admin, or write to the TimeLogger team from Settings — we update these guides with every release.