Skip to content

Conventions

This content is not available in your language yet.

  • Encoding: UTF-8, content type application/json.
  • Property naming in request and response bodies: camelCase (projectId, startedAt, isBillable). Unknown properties are ignored, so a misspelled or snake_case property is silently dropped — double-check names against the API reference.
  • Enum values are snake_case strings (workspace_user, public).
  • The pagination block is the exception: page.next_cursor and page.has_more are snake_case.
  • Query parameters are named per route, as listed in the reference (project_id, archived, include_archived, …).
  • Validation errors name an offending body property the same way: errors[].field is the camelCase property (projectId), or its JSON path inside a list (items[0].projectId). Errors about a query parameter, a header or an uploaded import file name it as sent instead — see Errors.
  • PATCH leaves any field it does not mention untouched. To clear a value, use the explicit flag the endpoint provides (for entries: clearProject, clearTask, clearStop); sending null means “no change”.
  • All timestamps are ISO 8601 with offset, e.g. 2026-05-19T14:32:00+02:00.
  • The API never returns naive times. If you receive a timestamp without an offset it is a bug — please report.
  • Workspaces have a timezone setting used by the dashboard for day-bucketing. It does not affect the raw timestamps the API returns.

The entries and clients lists (GET /api/v1/entries, GET /api/v1/clients) are cursor-paginated. The projects, tasks and tags lists return the whole (workspace-scoped) set as a plain JSON array, without a page block.

Request:

GET /api/v1/clients?limit=50&cursor=eyJuYW1lIjoiQWNtZSIsImlkIjoiZGVhZGJlZWYtLi4ifQ==

Response:

{
"data": [ { "...": "..." } ],
"page": {
"next_cursor": "eyJuYW1lIjoiQmV0YSIsImlkIjoiYWFhYWFhYWEtLi4ifQ==",
"has_more": true
}
}
  • limit — optional, integer, default 50, max 200.
  • cursor — opaque token from the previous response’s page.next_cursor. Do not parse it.
  • When has_more is false, the iteration is done. next_cursor will be null.
  • 200 OK — successful GET / PATCH / DELETE (when returning a body).
  • 201 Created — successful POST that created a resource.
  • 204 No Content — successful DELETE without a body.
  • 404 Not Found — resource does not exist or the caller cannot see it. We do not differentiate the two (anti-enumeration).
  • 4xx — client error, see Errors.
  • 5xx — server error. Retry with backoff.