| Type: | Package |
| Title: | Client for the 'Toggl Track' API |
| Version: | 1.0.0 |
| Description: | Read and write time entries, projects and clients of the 'Toggl Track' time tracker https://toggl.com from R, and download its reports. Reads never return silently truncated or empty results: HTTP errors are raised, the hourly quota and rate limits are respected, and paginated reports are checked for completeness. |
| License: | GPL-3 |
| Depends: | R (≥ 4.1.0) |
| URL: | https://github.com/ThinkR-open/togglr |
| BugReports: | https://github.com/ThinkR-open/togglr/issues |
| Imports: | assertthat, cachem (≥ 1.0.0), dplyr (≥ 1.0.0), filelock (≥ 1.0.2), getPass, glue, httr (≥ 1.4.0), jsonlite (≥ 1.7.0), keyring, lubridate (≥ 1.7.0), openssl, magrittr, parsedate, prettyunits, purrr, rappdirs, rstudioapi, stats, utils |
| Suggests: | callr, covr, knitr, pkgload, rmarkdown, testthat (≥ 3.1.7), withr (≥ 2.5.0) |
| VignetteBuilder: | knitr |
| ByteCompile: | true |
| Config/testthat/edition: | 3 |
| Encoding: | UTF-8 |
| Config/roxygen2/version: | 8.1.0 |
| NeedsCompilation: | no |
| Packaged: | 2026-10-15 08:28:15 UTC; PC |
| Author: | Vincent Guyader [aut, cre], ThinkR [cph, fnd] |
| Maintainer: | Vincent Guyader <vincent@thinkr.fr> |
| Repository: | CRAN |
| Date/Publication: | 2026-10-15 08:50:02 UTC |
togglr: client for the 'Toggl Track' API
Description
Track time spent in R with the toggl.com timesheet: read and write time entries, projects and clients, and download reports (Reports API v3).
Options
Every request goes through the same policy (quota, rate limits, retries), tuned by these options:
togglr.min_intervalminimal number of seconds between two requests (1). Raise it (e.g. 16) to spread a long extraction over the hourly quota of the API.
togglr.max_waitmaximal number of seconds a call waits for a retry or for the reset of an exhausted quota (60); beyond, it fails without sending the request.
togglr.timeouttimeout of a request, in seconds (120).
togglr.state_filepath of a file sharing the pacing of the requests and the known quota between R processes (callr, future, targets workers, cron jobs), under a lock. Without it, this state is private to the session.
togglr.quota_spreadwhen an answer announces fewer remaining requests than this (10), the next ones are spread until the reset of the quota.
togglr.page_sizenumber of entries per page of the detailled report (1000). With
togglr.max_pages, it caps the entries read in one period: 100 000 by default.togglr.report_attemptsnumber of reads of a period that keeps changing during its pagination (3), before an error.
togglr.max_pagesmaximal number of pages read by a paginated call (100), against an endless pagination.
togglr.cache_dirfolder of the reports cache (
get_detailled_report(cache = TRUE)).
Quota
Toggl counts an hourly quota per organization (endpoints of a workspace,
reports included) and per user (/me). togglr remembers an exhausted quota
per token and per scope; two workspaces of one organization each learn it
from their own 402 answer.
Author(s)
vincent vincent@thinkr.fr
See Also
Useful links:
ask_toggl_api_token
Description
ask for the toggle api token
Usage
ask_toggl_api_token(msg = "toggl api token")
Arguments
msg |
the message |
Value
the token typed by the user, or NULL when nothing was typed
Empty the cache of the reports
Description
Removes the periods stored by get_detailled_report(cache = TRUE).
Usage
clean_cache(cache_dir = toggl_cache_dir())
Arguments
cache_dir |
folder of the cache |
Value
invisibly, the result of unlink() (0 for success)
Examples
## Not run:
clean_cache()
## End(Not run)
clean memoise cache (deprecated)
Description
Deprecated: togglr no longer memoises. Removes the cache folder of togglr
0.2.x (and the reports cache it contains). Use clean_cache().
Usage
clean_memoise_cache(
memoise_cache_dir = getOption("togglr_memoise_dir", default =
rappdirs::user_cache_dir("togglr"))
)
Arguments
memoise_cache_dir |
folder to remove |
Value
invisibly, the result of unlink() (0 for success)
Examples
## Not run:
clean_memoise_cache()
## End(Not run)
client_id_to_name
Description
return client name from client id
Usage
client_id_to_name(
id,
api_token = get_toggl_api_token(),
workspace_id = get_workspace_id(api_token)
)
Arguments
id |
client id |
api_token |
the toggl api token |
workspace_id |
workspace id |
Value
the client name
client_name_to_id
Description
return client id from client name
Usage
client_name_to_id(
name,
api_token = get_toggl_api_token(),
workspace_id = get_workspace_id(api_token)
)
Arguments
name |
client name |
api_token |
the toggl api token |
workspace_id |
workspace id |
Value
the client id
create_client
Description
create a client
Usage
create_client(
name = "wihtout client",
api_token = get_toggl_api_token(),
workspace_id = get_workspace_id(api_token)
)
Arguments
name |
client name |
api_token |
the toggl api token |
workspace_id |
workspace id |
Value
the created client, as returned by the API (a list with its id)
Examples
## Not run:
get_toggl_api_token()# set your api token here
create_client("new client")
## End(Not run)
delete_toggl_api_token
Description
delete the toggle api token
Usage
delete_toggl_api_token()
Value
invisibly, NULL or the error caught when there was no key
get_all_client_info
Description
get_all_client_info
Usage
get_all_client_info(
api_token = get_toggl_api_token(),
workspace_id = get_workspace_id(api_token)
)
Arguments
api_token |
the toggl api token |
workspace_id |
workspace_id |
Value
a data.frame
Examples
## Not run:
get_all_client_info()
## End(Not run)
get all client's name
Description
get all client's name
Usage
get_all_client_names(
api_token = get_toggl_api_token(),
workspace_id = get_workspace_id(api_token),
since = toggl_today() %m-% lubridate::years(1),
until = toggl_today()
)
Arguments
api_token |
the toggl api token |
workspace_id |
the workspace id |
since |
a date |
until |
a date |
Value
a character vector of the client names, without duplicates
Get all project's names
Description
Get all project's names
Usage
get_all_project_names(
api_token = get_toggl_api_token(),
workspace_id = get_workspace_id(api_token),
since = toggl_today() %m-% lubridate::years(1),
until = toggl_today(),
user_ids = NULL
)
Arguments
api_token |
the toggl api token |
workspace_id |
the workspace id |
since |
a date |
until |
a date |
user_ids |
optional, only the projects these users worked on |
Value
a character vector of the project names
get_client_project
Description
get_client_project
Usage
get_client_project(
id,
api_token = get_toggl_api_token(),
workspace_id = get_workspace_id(api_token)
)
Arguments
id |
client id |
api_token |
the toggl api token |
workspace_id |
workspace_id |
Value
the client name
get_context
Description
retrieve Rstudio projet if possible
Usage
get_context()
Value
a text describing the RStudio project, or "I'm using R" outside a project
get_context_projet
Description
retrieve Rstudio projet if possible
Usage
get_context_project()
Value
the name of the RStudio project, or "sans projet" outside a project
get_current
Description
retrieve current projet id
Usage
get_current(api_token = get_toggl_api_token())
Arguments
api_token |
the toggl api token |
Value
a list describing the running time entry (id, description, start, project_id...), or NULL when nothing is running
get current duration
Description
get current duration
Usage
get_current_duration(api_token = get_toggl_api_token())
Arguments
api_token |
the Token API |
Value
a difftime
Examples
## Not run:
get_current_duration()
## End(Not run)
get all task from a project
Description
get all task from a project
Usage
get_current_project_task_detail(
project_name = get_context_project(),
api_token = get_toggl_api_token(),
workspace_id = get_workspace_id(api_token),
since = toggl_today() %m-% lubridate::years(1),
until = toggl_today(),
humain = TRUE
)
Arguments
project_name |
project name |
api_token |
the toggl api token |
workspace_id |
the workspace id |
since |
a date |
until |
a date |
humain |
boolean humain readable time |
Value
a data frame of the tasks of the project (title, time...), the running entry included
get all data from https://toggl.com
Description
get all data from https://toggl.com
Usage
get_dashboard(
api_token = get_toggl_api_token(),
workspace_id = get_workspace_id(api_token),
since = toggl_today() %m-% lubridate::years(1),
until = toggl_today(),
user_ids = NULL
)
Arguments
api_token |
the toggl api token |
workspace_id |
the workspace id |
since |
begin date |
until |
stop date |
user_ids |
optional, ids of the users whose time is counted (all by default) |
Value
an object of class toggl: a list with synthese (one row per project: id, project, client, time in ms) and tache (per project, a data frame of its time entries: title, time in ms, local_start)
Detailled report: every time entry of a period
Description
Downloads the time entries of the workspace between since and until
(both included) from the reports API v3, all pages included.
Usage
get_detailled_report(
api_token = get_toggl_api_token(),
workspace_id = get_workspace_id(api_token),
since = toggl_today() %m-% lubridate::years(1),
until = toggl_today(),
user_agent = toggl_user_agent(),
max_page = NULL,
cache = FALSE,
cache_dir = toggl_cache_dir(),
memoise_cache_dir = NULL,
user_ids = NULL
)
Arguments
api_token |
the toggl api token |
workspace_id |
the workspace id |
since |
begin date (included): a |
until |
end date (included), same formats; today by default |
user_agent |
ignored since the move to Reports v3 (the user agent is sent in the header of every request) |
max_page |
deprecated, ignored: every page is read. |
cache |
logical. If |
cache_dir |
folder of the cache used when |
memoise_cache_dir |
deprecated, use |
user_ids |
optional, ids of the users whose entries are wanted (all the users of the workspace by default) |
Details
Columns: id, pid, tid, uid, description, start, end,
updated (text, ISO 8601), dur (milliseconds), user, use_stop,
client, project, project_color, project_hex_color, task,
billable, is_billable, cur, tags (list), then any column added by
the API.
The entries come from Reports v3 (/search/time_entries, enriched with
the names of users, projects, clients and tags), with large pages
(options(togglr.page_size), 1000 by default).
The period is checked against the total duration announced by the API
before and after the pagination, and against the edit time of every entry
received; if entries were added, removed or edited meanwhile, the period
is fetched again, up to options(togglr.report_attempts) reads in all (3
by default), then an error is raised. One movement escapes these checks:
an entry deleted and another one of exactly the same duration created
during the read, when the new entry is not in the pages received. The
rounding set in the Toggl profile is not applied. A running entry is left out. An HTTP error (quota, server
error, authentication) raises an error too: the function never returns a
silently truncated period.
Periods longer than a year (365 days or more between since and
until, across a new year) are split by calendar year.
Value
a tibble, one row per time entry, with fixed column types (see Details); 0 rows for an empty period
Data of one project
Description
Data of one project
Usage
get_project_data(
project_id,
api_token = get_toggl_api_token(),
workspace_id = get_workspace_id(api_token)
)
Arguments
project_id |
the project id |
api_token |
the toggl api token |
workspace_id |
the workspace id |
Value
a list with the fields of the project (id, name, client_id,
active, billable, color...), as returned by the API v9
Examples
## Not run:
get_project_data(get_project_id("my_project"))
## End(Not run)
get_project_id
Description
retrieve project id
Usage
get_project_id(
project_name = get_context_project(),
api_token = get_toggl_api_token(),
create = FALSE,
client = NULL,
workspace_id = get_workspace_id(api_token),
color = NULL
)
Arguments
project_name |
the project name |
api_token |
the toggl api token |
create |
boolean do you want to create the project if it doesnt exist ? |
client |
client name |
workspace_id |
workspace id |
color |
id of the color selected for the project |
Value
the id of the project, or NULL when it does not exist (and is not created)
get_project_id_and_name
Description
retrieve project id and name
Usage
get_project_id_and_name(
api_token = get_toggl_api_token(),
workspace_id = get_workspace_id(api_token),
active = NULL
)
Arguments
api_token |
the toggl api token |
workspace_id |
workspace id |
active |
|
Value
a tibble with id, project_name and active; 0 rows when the
workspace has no such project
get project total time
Description
get project total time
Usage
get_project_total(
project_name = get_context_project(),
api_token = get_toggl_api_token(),
workspace_id = get_workspace_id(api_token),
since = toggl_today() %m-% lubridate::years(1),
until = toggl_today()
)
Arguments
project_name |
project name |
api_token |
the toggl api token |
workspace_id |
the workspace id |
since |
a date |
until |
a date |
Details
The rounding set in the Toggl profile is not applied
(rounding = 0 in the request), as in Reports v2.
Value
the total time spent on the project, as text (e.g. "12:30:00"), the running entry included
get summary report
Description
by user then projet
Usage
get_summary_report(
api_token = get_toggl_api_token(),
workspace_id = get_workspace_id(api_token),
since = toggl_today() %m-% lubridate::years(1),
until = toggl_today(),
user_agent = toggl_user_agent(),
users = get_workspace_users(api_token = api_token, workspace_id = workspace_id)
)
Arguments
api_token |
the toggl api token |
workspace_id |
the workspace id |
since |
begin date |
until |
stop date |
user_agent |
ignored since the move to Reports v3 (the user agent is sent in the header of every request) |
users |
the users of the workspace (a data frame with |
Details
The rounding set in the Toggl profile is not applied
(rounding = 0 in the request), as in Reports v2.
Value
a tibble, one row per user: id, user (full name), time (ms) and items (a data frame of the user's time entries: title, time in ms, local_start; cur, sum and rate are NA since Reports v3)
Get all time entries between 2 dates
Description
Get all time entries between 2 dates
Usage
get_time_entries(
api_token = get_toggl_api_token(),
since = Sys.time() - lubridate::weeks(1),
until = Sys.time(),
workspace_id = get_workspace_id(api_token)
)
Arguments
api_token |
the toggl api token |
since |
begin date (One week ago by default) |
until |
stop date (Now by defaut) |
workspace_id |
the workspace id (to name the projects and clients) |
Value
a data.frame containing all time entries, with project_name and
client_name. The endpoint goes back at most 3 months: for an older
period, use get_detailled_report() with user_ids.
Examples
## Not run:
get_time_entries()
## End(Not run)
get_toggl_api_token
Description
return the toggle api token
Usage
get_toggl_api_token(ask = TRUE)
Arguments
ask |
booleen do we have to ask if missing |
Value
the token (a character string), or NULL when there is none and ask = FALSE
get weekly report
Description
get weekly report
Usage
get_weekly_report(
api_token = get_toggl_api_token(),
workspace_id = get_workspace_id(api_token),
since = toggl_today() %m-% lubridate::years(1),
until = toggl_today(),
user_agent = toggl_user_agent()
)
Arguments
api_token |
the toggl api token |
workspace_id |
the workspace id |
since |
begin date |
until |
stop date |
user_agent |
ignored since the move to Reports v3 (the user agent is sent in the header of every request) |
Details
The rounding set in the Toggl profile is not applied
(rounding = 0 in the request), as in Reports v2.
Value
a tibble, one row per project: pid, title (project, client,
color, hex_color; Reports v3 gives no color index, color is always
"0"), totals (8 values in ms: the 7 days, then the week; NA for 0)
and details (the same per user); 0 rows for a week without any entry
get_workspace_id
Description
Return the id of the default workspace of the account (as set in Toggl), or of its first workspace when no default is set.
Usage
get_workspace_id(api_token = get_toggl_api_token())
Arguments
api_token |
the toggl api token |
Value
the workspace id (an integer)
See Also
get_workspaces() to list every workspace
Users of a workspace
Description
Users of a workspace
Usage
get_workspace_users(
api_token = get_toggl_api_token(),
workspace_id = get_workspace_id(api_token)
)
Arguments
api_token |
the toggl api token |
workspace_id |
the workspace id |
Value
a tibble, one row per user of the workspace (id, fullname, email...)
List the workspaces of the account
Description
List the workspaces of the account
Usage
get_workspaces(api_token = get_toggl_api_token())
Arguments
api_token |
the toggl api token |
Value
a tibble with id, name and default (TRUE for the default
workspace of the account)
show notification
Description
show notification using message
Usage
notification(title, msg)
Arguments
title |
title of the notificatin |
msg |
content of the notification |
Value
invisibly, NULL; called for its message
open toggle.com website on timesheet page
Description
open toggle.com website on timesheet page
Usage
open_toggl_website_app()
Value
invisibly, the result of utils::browseURL()
open toggle.com website on profile page
Description
open toggle.com website on profile page
Usage
open_toggl_website_profile()
Value
invisibly, the result of utils::browseURL()
set_toggl_api_token
Description
set the toggle api token
Usage
set_toggl_api_token(token)
Arguments
token |
toggl api token |
Value
invisibly, the token stored (or NULL when nothing was typed)
Simplify a parsed JSON answer into vectors and data frames
Description
Same result as jsonlite::fromJSON(simplifyVector = TRUE) on a list already
parsed with simplifyVector = FALSE (what httr::content() returns), using
only the public API of jsonlite: the list is serialised back to JSON at full
precision, then read with simplification.
Usage
simplify(x, ...)
Arguments
x |
a list, as returned by |
... |
passed to |
Value
the simplified object
transforme time column into humain readable column
Description
transforme time column into humain readable column
Usage
to_humain(df)
Arguments
df |
a data.frame |
Value
the data frame, with time as a readable duration
toggl_create
Description
create a time entry
Usage
toggl_create(
description = get_context(),
start = now(),
pid = get_project_id(api_token = api_token, workspace_id = workspace_id),
stop,
duration,
tags = NULL,
api_token = get_toggl_api_token(),
workspace_id = get_workspace_id(api_token)
)
Arguments
description |
the task you did |
start |
time in POSIXt |
pid |
pid |
stop |
time in POSIXt |
duration |
in seconds |
tags |
tags |
api_token |
the toggl api token |
workspace_id |
workspace id |
Value
invisibly, the id of the created time entry (NA, with a warning, when the API accepted it but its answer could not be read)
Examples
## Not run:
set_toggl_api_token() # once, stores your token in the keyring
toggl_create(duration=1200)
toggl_create( description="description",
start=now(),
pid = get_project_id(project_name = "projectname",
create=TRUE,client = "client"),
duration=1000,
api_token=get_toggl_api_token())
## End(Not run)
toggl_create_project
Description
create a project
Usage
toggl_create_project(
project_name = get_context_project(),
api_token = get_toggl_api_token(),
workspace_id = get_workspace_id(api_token),
client = NULL,
private = FALSE,
color = NULL,
active = TRUE
)
Arguments
project_name |
project name |
api_token |
the toggl api token |
workspace_id |
workspace_id |
client |
client name: an existing client is reused, an unknown one is
created; |
private |
whether project is accessible for only project users or for all workspace users (boolean, default false) |
color |
color of the project, as a hex code (e.g. "#06aaf5") |
active |
boolean set project as active, TRUE by default |
Value
the id of the project (created, or already existing)
Examples
## Not run:
toggl_create_project()
## End(Not run)
toggl_start
Description
start a task
Usage
toggl_start(
description = get_context(),
client = "without client",
project_name = get_context_project(),
start = now(),
api_token = get_toggl_api_token(),
tags = "",
workspace_id = get_workspace_id(api_token)
)
Arguments
description |
the task you are doing |
client |
client name |
project_name |
nom du projet |
start |
start time in POSIXt |
api_token |
the toggl api token |
tags |
tags |
workspace_id |
workspace id |
Value
invisibly, the id of the started time entry (NA, with a warning, when the API accepted it but its answer could not be read)
Examples
## Not run:
get_toggl_api_token()# set your api token here
toggl_start()
## End(Not run)
toggl_stop
Description
stop the active task
Usage
toggl_stop(
current = get_current(api_token = api_token),
api_token = get_toggl_api_token(),
workspace_id = get_workspace_id(api_token)
)
Arguments
current |
list task id and start time |
api_token |
the toggl api token |
workspace_id |
workspace id |
Value
invisibly, the stopped time entry, as returned by the API
Examples
## Not run:
set_toggl_api_token() # once, stores your token in the keyring
toggl_start()
toggl_stop()
## End(Not run)
toggl_update_entries
Description
update time entries
Usage
toggl_update_entries(
time_entry_ids,
description = NULL,
start = NULL,
pid = NULL,
stop = NULL,
duration = NULL,
tags = NULL,
api_token = get_toggl_api_token(),
workspace_id = get_workspace_id(api_token)
)
Arguments
time_entry_ids |
id(s) of time entries to update: one PUT request is sent per entry |
description |
the task you did |
start |
time in POSIXt |
pid |
project id |
stop |
time in POSIXt |
duration |
in seconds |
tags |
tags |
api_token |
the toggl api token |
workspace_id |
workspace id |
Value
the updated entry, as returned by the API, or a list of them when several ids are given
Examples
## Not run:
set_toggl_api_token() # once, stores your token in the keyring
time_entry_id <- toggl_create(duration=1200)
toggl_update_entries( time_entry_id,
description = "new description",
duration = 100,
tags = c("tag1", "tag2"),
api_token=get_toggl_api_token())
## End(Not run)
update_toggl_api_token
Description
update the toggle api token
Usage
update_toggl_api_token()
Value
invisibly, the new token, or NULL when the input was cancelled (the stored token is then kept)