toggl
Time entries, projects and clients from Toggl Track.
Use case
A consultancy's time tracker is its system of record for revenue. This connector pulls the entries so a workflow can compute utilization, realization and what is billable.
The one thing to get right
GET /me/time_entries returns the authenticated user's entries only. There is no workspace-wide GET for time entries in Toggl's v9 API. Point a firm-wide utilization report at it and you get one person's hours presented as the whole firm — a number that is wrong, low, and looks completely reasonable.
So the two operations are named for what they actually cover:
| operation | endpoint | covers |
|---|---|---|
my-time-entries |
GET /api/v9/me/time_entries |
one person — whoever owns the token |
workspace-time-entries |
POST /reports/api/v3/workspace/{id}/search/time_entries |
everyone in the workspace |
Use workspace-time-entries for anything about the firm.
All operations
| operation | endpoint |
|---|---|
me |
GET /api/v9/me |
list-workspaces |
GET /api/v9/me/workspaces |
list-projects |
GET /api/v9/workspaces/{id}/projects |
list-clients |
GET /api/v9/workspaces/{id}/clients |
my-time-entries |
GET /api/v9/me/time_entries |
workspace-time-entries |
POST /reports/api/v3/.../search/time_entries |
Setup
Create an API token in Toggl under Profile Settings → API Token.
Auth is HTTP Basic with the token in the username slot and the literal string api_token as the password — base64("<token>:api_token"). The connector handles the encoding; you supply apiToken.
Store it in the InTouch credential vault, not in the workflow.
Field gotchas
duration is in SECONDS, and is negative for a running entry. Divide by 3600 for hours and drop negatives, or your totals are nonsense. This connector returns Toggl's payload unchanged — the conversion belongs to the caller, who knows whether a running timer should count.
Names only come back when you ask. Project and client names require meta=true on the core API and enrich_response=true on reports. The connector sets both, so you get project_name and client_name rather than bare ids.
Pagination
The reports API paginates through the X-Next-ID and X-Next-Row-Number response headers, fed back as first_id / first_row_number in the next request body. Nothing in the JSON body tells you there is more — read only the body and you will silently take the first 200 rows as the whole period.
This connector follows those headers up to a 25-page stop and publishes truncated. If it is true, an error is set saying the result is incomplete. Narrow the date range; do not treat it as a full period.
Status codes worth knowing
- 403 — bad token, or the token has no access to that workspace. Toggl uses 403 where most APIs use 401, so "403" here does not mean "forbidden action", it usually means "wrong credential."
- 402 — the workspace's plan does not include the feature. Billable filtering is premium. That is a billing answer, not a bug to debug.
Published outputs
| key | meaning |
|---|---|
result |
JSON array of records (or the object for me) |
status |
HTTP status of the last call |
count |
records returned |
truncated |
"true" if the page cap stopped the walk — result is incomplete |
Source
toggl.py, tool.iml
Publishes
The keys a later task may reference as {{taskName.key}}. Referencing anything not listed here resolves to nothing at run time.
counterrorpagesresultstatustruncated
Input Properties
Every property this tool accepts, from its own tool.iml.
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
apiToken |
string | yes | — | Toggl Track API token (Profile Settings). Sent as HTTP Basic with the token as username and the literal 'api_token' as password. |
operation |
string | yes | — | One of: me, list-workspaces, list-projects, list-clients, my-time-entries, workspace-time-entries |
workspaceId |
string | no | — | Numeric workspace id. Required for list-projects, list-clients and workspace-time-entries. |
startDate |
string | no | — | Start date YYYY-MM-DD. Required for workspace-time-entries. |
endDate |
string | no | — | End date YYYY-MM-DD. Required for workspace-time-entries. |
userIds |
string | no | — | Comma-separated numeric user ids to filter workspace-time-entries. |
clientIds |
string | no | — | Comma-separated numeric client ids to filter workspace-time-entries. |
projectIds |
string | no | — | Comma-separated numeric project ids to filter workspace-time-entries. |