Skip to content

togglr

1.0.0Package record

Client for the 'Toggl Track' API

0packages depend
2.5Kdownloads / year
93.2%test coverage
13/13flavors OK

Overview

About
Maintained by Vincent GuyaderCRAN page ↗GitHub ↗Issues ↗Declared funder: ThinkR

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.

Changes in 1.0.0

Breaking changes

  • Reports come from the Reports API v3 (#76): get_summary_report() items no longer give cur, sum and rate (NA); entries without a visible project are grouped under an NA id and name instead of "Private Project"; the user_agent argument of the report functions is ignored. The columns and types of get_detailled_report() are unchanged. The rounding set in the Toggl profile is never applied (rounding = 0 in every request), as in Reports v2.
  • get_workspace_id() returns the default workspace of the account, no longer always the first one (#23).
  • get_time_entries() fails before any request for a period starting more than 3 months ago (the API refused it anyway) (#13).
Show all changes in 1.0.0Hide the rest of the changes in 1.0.0
  • create_client() returns the created client (a list), no longer the httr response (#54); toggl_update_entries() sends one PUT per entry and returns the updated entry, or a list of them (#56).
  • A write refused by the API raises an error (#54); toggl_start() and toggl_create() return NA, with a warning, when the API accepted the entry but its answer could not be read.
  • get_toggl_api_token() fails, outside an interactive session, instead of prompting, and never deletes the stored key (#51).
  • set_toggl_api_token() returns the token invisibly (#84).
  • simplify() is rewritten on the public API of jsonlite (#69).
  • get_detailled_report(): cache = FALSE by default, max_page and memoise_cache_dir deprecated (#60, #67); a 7th positional argument now goes to cache.

Other changes

  • get_detailled_report() reads Reports API v3 (/search/time_entries, enriched with the names of users, projects, clients and tags) instead of Reports v2, with the same columns and types. Pages of 1000 entries (options(togglr.page_size)) instead of 50: a month of a team of 20 is read in one or two requests. The period is checked against the total duration of /search/time_entries/totals, equal before and after the pagination and, up to the rounding of the API (1 s per entry), to the sum of the entries. New argument user_ids; user_agent is ignored (#76).
  • The completeness checks of get_detailled_report() also treat as a movement any entry received that was edited after the read started: the pages are numbered by row, so a deletion followed by an insertion of the same duration shifts the rows without changing the totals. This replaces the total_grand tolerance for running timers, which could hide such a movement (#77). A running timer may only grow by the time between the two totals, measured by the clock of the server from its own start, not by the time spent waiting before the first total. One movement still escapes: an entry deleted and replaced by one of exactly the same duration that is not in the pages received.
  • get_summary_report(), get_weekly_report() and get_dashboard() read Reports API v3 too, with the output of Reports v2. Reports v3 only returns ids: the names of users, projects and clients come from the Track API v9, archived projects included. get_weekly_report() returns an empty tibble for a week without any entry. An unreadable answer to a report request is an error, never an empty report. The amounts of the summary items (cur, sum, rate) are no longer given (NA). Entries without a visible project are grouped with an NA id and name (Reports v2 called them "Private Project") (#76).
  • With a shared state file, an exhausted quota, or a spread of the requests, recorded by another process while this one was waiting is no longer erased: it is waited for in turn, or fails within max_wait (#78).
  • The requests of Reports v3 (/reports/api/v3/workspace/<id>/) count against the quota of their workspace, like the requests of the API v9 (/workspaces/<id>/): an exhausted Reports quota no longer blocks /me.
  • get_time_entries() is never truncated: /me/time_entries returns at most 1000 entries, so a full answer splits the period in two, recursively. A period starting more than 3 months ago (the limit of the API) fails before any request, pointing to get_detailled_report(user_ids = ) (#13). Its output gains a client_name column; project_name and client_name cover the archived projects too (#14). get_project_id_and_name() gains active (NULL, "false" or "both") and returns 0 rows, not an error, for a workspace without any matching project. since and until may be text dates again.
  • get_workspace_id() returns the default workspace of the account (default_workspace_id of /me), and the first workspace only when no default is set; it used to be always the first one. New get_workspaces() lists every workspace, the default one flagged (#23).
  • get_dashboard() and get_all_project_names() gain user_ids, to keep the projects some team members worked on (#12).
  • New get_project_data(): the data of one project from its id (#28).
  • toggl_start(tags = ) sends its tags, now covered by a test (#16).
  • set_toggl_api_token() returns the token invisibly (it was printed when called at top level, e.g. in a script whose output is logged), and checks the new token before deleting the stored one. update_toggl_api_token() asks first: a cancelled input keeps the stored token (#84).
  • Tests: coverage from 85 % to 93 %, a real multi-process test of togglr.state_file, no test depending on covr's instrumentation; new workflow measuring the coverage (#84, #32, #33).
  • DESCRIPTION declares R (>= 4.1.0) and the minimal versions of its dependencies; the obsolete inst/dependencies.R is no longer shipped (#83).
  • The API token is no longer printed: create_client() and toggl_create_project() used httr::verbose(), which shows the Authorization header (#50).
  • Every request times out after options(togglr.timeout) seconds (120 by default), and network errors (timeout, DNS, connection reset) are retried like a 5xx (#45).
  • get_detailled_report() returns fixed column types (e.g. task is always text, tid integer), whatever the content of the page: periods over a year with an empty year no longer fail to combine (#46).
  • New option togglr.state_file: the pacing of the reports calls and the knowledge of an exhausted quota are stored in that file, under a lock, and shared by every R process using it (callr / future / targets workers, cron jobs). Without it, the state stays private to the session (#48).
  • A 402 without quota headers (a feature of a paid plan) now stops at once with the message of the API, instead of blocking every request for an hour. An exhausted quota is remembered per token, as a hash: the token is never stored (#49).
  • The api_token and workspace_id given to a function are now used by every call it makes: project, client and dashboard helpers, get_time_entries() (new workspace_id argument), toggl_start(), toggl_stop(), toggl_create(), toggl_create_project() no longer fall back to the keyring token nor to an extra /workspaces request. client_name_to_id() and client_id_to_name() gain a workspace_id argument (#51).
  • get_toggl_api_token() no longer deletes the stored key when the keyring cannot be read (e.g. locked under cron); in a non interactive session it fails with a clear message instead of prompting (#51).
  • toggl_start() and toggl_create() send the start time converted to UTC, instead of removing one hour: entries were one hour off in summer, and more outside Paris (#52, from #44 by @bradyrippon).
  • get_current_duration() counts from the start of the running entry, not from its last edit (at); get_project_total() and get_current_project_task_detail() were affected (#53).
  • Every write (POST, PUT, PATCH) goes through toggl_request(), with the policy of the reads: an error of the API is raised with its message (no more "$ operator is invalid for atomic vectors"), the quota and 429 are respected. A POST is never retried after a 5xx or a network error, as it may have been processed. toggl_start() / toggl_create() notify then raise the error; toggl_stop() only notifies STOP once the API accepted it. create_client() now returns the created client (a list) instead of the raw httr response (#54).
  • toggl_create_project() works again: no crash without client, an existing client is reused instead of being created again, its client_id is sent, and the body follows the v9 format (private, color, active are no longer ignored) (#55).
  • toggl_update_entries() sends one PUT per entry (the v9 API takes a single id per PUT), sends stop (it was accepted then dropped), sends the project as project_id, and no longer sends the read-only at. It returns the updated entry, or a list of them for several ids (#56).
  • get_time_entries() sends its dates in UTC (...Z): the + of a time zone offset was sent unencoded in the url, and read as a space by the server (#57). Entries with several tags are covered by a test (#30).
  • get_detailled_report() splits by calendar year as soon as a period spans 365 days or more across a new year: a 367 days period (bounds included) was sent as is, beyond the one year limit of the reports API v2 (#58).
  • The pagination of get_all_projects() is bounded: it stops with an error if the API returns the same page twice, or after options(togglr.max_pages) pages (100 by default), instead of spending the quota in an endless loop (#59).
  • get_detailled_report(max_page = ) now warns that the argument is deprecated and ignored (#60).
  • The reports functions (get_detailled_report(), get_summary_report(), get_weekly_report(), get_dashboard()) accept since / until as a Date, a date-time (its day in its own time zone) or a text "YYYY-MM-DD", and fail with a clear message, before any request, on anything else or on since after until (#61).
  • Default periods ("one year ago") are computed with %m-%: they were NA on February 29th (#62).
  • options(togglr.min_interval) (1 s by default) now spaces every request, reads and writes, retries included, not only the pages of the detailled report (#64).
  • A period that keeps moving during the pagination is read up to options(togglr.report_attempts) times (3 by default, 2 before) (#65).
  • An entry seen twice during the pagination keeps its most recently updated version, not the first one read (#66).
  • The reports cache (cache = TRUE) lives in its own folder, the reports sub-folder of rappdirs::user_cache_dir("togglr") or options(togglr.cache_dir), apart from the memoise files of 0.2.x. New argument cache_dir and function clean_cache(); memoise_cache_dir and clean_memoise_cache() are deprecated (#67).
  • The quota announced by every answer (x-toggl-quota-remaining) is used: at 0, the next request waits for the reset (or fails within max_wait) instead of receiving a 402; with fewer than options(togglr.quota_spread) (10) requests left, they are spread until the reset (#68).
  • simplify() no longer calls an internal function of jsonlite (getFromNamespace()): it uses the public toJSON() / fromJSON(), at full precision, with the same result (#69).
  • globalVariables() no longer declares function names (case_when, full_join, tribble) nor unused names, which could hide a missing import (#70).
  • Every request sends the user agent togglr/<version> in its header; get_dashboard() no longer sends a hardcoded api_test (#71). The user_agent argument of the report functions is kept for compatibility and ignored.
  • get_workspace_id() fails with its message when the account has no workspace, instead of "subscript out of bounds". New tests cover the edge cases of the pagination, of the quota and of the cache (#73).
  • Package metadata and documentation: new title and description, no more LazyData without data, targeted imports only (no more whole dplyr, httr, keyring, assertthat, getPass), get_detailled_report() has its own help page, the vignette no longer runs install.packages() during R CMD check. R CMD check is clean: 0 error, 0 warning, 0 note (#74).
  • toggl_create_project() (and so toggl_start() on a new project) works again in a workspace without any client: get_all_client_info() returns the id and name columns, even with no rows (review of #75).
  • The reports cache is kept per token (as a hash): a period fetched with one token is no longer returned to another token of the same workspace (review of #75).
  • The spreading of the last requests of the quota waits at most max_wait, with a message, and only slows down the token that is short of quota (review of #75).
  • The quota is remembered per token and per scope (the workspace or organization of the url, or the user for /me and /workspaces): an exhausted workspace no longer blocks /me or another workspace (review of #75).
  • A request processed by the API is returned even if its quota cannot be recorded in the state file (warning): a time entry is no longer reported as not started, then created twice (review of #75).
  • One pass on the state file per request instead of three, and a read no longer rewrites it (review of #75).
  • A time entry accepted by the API but whose answer cannot be read is reported as started (with a warning, id NA), not as NOT STARTED (review of #75).
  • A state file that cannot be replaced is an error instead of a silently lost update, and the temporary file is removed (review of #75).
  • Network errors are no longer retried when the backoff exceeds max_wait (review of #75).

From NEWS.md in the release

Install

Health

CRAN checks
13OK
Slowest check: 1.9 min · r-oldrel-windows-x86_64
Status changes
  • OK13 OK2026-10-22
  • NOTE13 NOTE2026-06-09
  • ERROR12 NOTE, 1 ERROR2026-06-08
  • NOTE3 OK, 11 NOTE2026-03-10
Advisories

none known

Documentation

In release 1.0.0
READMEYes · 231 wordsVignettesYes · 1 · staticNEWSYes · 100% structured · mentions 1.0.0Citation fileNo
Help pages
42includes a package overview page
Examples that run
0%12 never run
Exported functions with examples
29%
Documented parameters
92%
Return-value docs
100%
Help pages citing references
0%
Vignettes (1)

Downloads

2.5K
CRAN downloads in the past year
Rank #16,419 · ~7/day · ~212/mo
Daily download trend is not available in this view yet.
33530 days
76390 days
2.5K1 year
Compare downloads with other packages →
Also on67 r2u5 autocran

Repository

50Stars
17Forks
0Open issues
0Open PRs
2Releases
211Commits
12Commit identities
rtoggl-apitogglerhacktoberfest
211 commits · Last activity 2026-10-15 · 0% stars, 30d
Responsiveness
How these are sampled
PRs merged (all time)
77%
Median days to close, 50 most recently updated closed issues
0
Median days to close, 50 most recently updated closed PRs
0

Stars over time

2025-09-27 · 502026-07-07 · 50
PracticesBeta

9 development-tooling and community-health practices detected across 6 families in the upstream repository

Checks run against github.com/thinkr-open/togglr on 2026-10-18.

Continuous integration (2)
GitHub ActionsR CMD check workflow

The R CMD check workflow runs on Linux, macOS and Windows, and on R-devel

Docs source (3)
README.Rmdpkgdown

GitHub Pages site last deployed 2020-07-09

Coverage (1)
Coverage reporting
CRAN release process (1)
cran-comments.md
Show all practicesHide 2 practices
Lint, format, editor (1)
RStudio project
Git structural (1)
.gitattributes
How this is detected·Detection ruleset v3 (2026-09-26)
AI coding toolsBeta

This repository shows signs of AI coding tools.

  • Claude Codefirst seen 2026-10-14
    Pull request it wrote: opened by a project member
    Commits: at least 46 crediting it in the message
Models named in its commits
  • Claude Opus 5.546 commits · Oct 2026
Counts are commits, not lines of code. Commits by a tool's accounts count once across all of its accounts. Commits crediting it are the largest count among its credit lines, a minimum.How this is detected·Detection ruleset v4 (updated 2026-09-27)

Dependencies

Declared dependencies
24 external dependencies (excludes base and recommended)

Installing togglr adds 37 packages (26 with compiled code, 10 MB of source tarballs). Heaviest: openssl 1.1 MB, jsonlite 1.0 MB, vctrs 1.0 MB.

Depends (1)
R >= 4.1.0
LinkingTo (0)
none
Enhances (0)
none
Reverse dependencies
0direct
0indirect

Nothing depends on this yet.

People & History

People (2)
Author, Maintainer since 0.1.3 (2017)
Copyright holder, Funder · added in 0.1.33
Releases (6)

Pick two releases to compare their code metrics.

  • R
    R 4.6.0 released · 2026-04-24
  • R
    R 4.5.0 released · 2025-04-11
  • R
    R 4.4.0 released · 2024-04-24
  • 1.0.0Latest
    record
    2024-02-19 · current release · diff ↗ ·
    added 3 exports
    clean_cache, get_project_data, get_workspaces
  • 0.2.1
    record
    2024-02-20 · diff ↗
  • 0.2
    record
    2024-02-15 · diff ↗ ·
    removed 1 export
    get_project_task_detail
    added 2 exports
    clean_memoise_cache, get_current_project_task_detail
  • R
    R 4.3.0 released · 2023-04-21
  • 0.1.99
    record
    2022-07-11 · diff ↗ ·
    added 7 exports
    get_detailled_report, get_summary_report, get_weekly_report, get_workspace_users, simplify, to_humain, toggl_update_entries
  • R
    R 4.2.0 released · 2022-04-22
  • R
    R 4.1.0 released · 2021-05-18
  • R
    R 4.0.0 released · 2020-04-24
  • R
    R 3.6.0 released · 2019-04-26
  • 0.1.33
    record
    2018-08-14 · diff ↗ ·
    removed 1 export
    open_toggl_website
    added 4 exports
    get_project_id_and_name, get_time_entries, open_toggl_website_app, open_toggl_website_profile
  • R
    R 3.5.0 released · 2018-04-23
  • 0.1.3
    record
    2017-12-07
  • R
    R 3.4.0 released · 2017-04-21

Package metadata

First published
2017-12-07
Total releases
6 / 9 yrs
License
GPL-3 OSI
Minimum R
≥ 4.1.0
Download size
70 KB

Cite

Cite this package

Run in R for the authors' preferred citation:

citation("togglr")
Guyader, V., & ThinkR. (2026). togglr: Client for the 'Toggl Track' API (Version 1.0.0) [Computer software]. https://doi.org/10.32614/CRAN.package.togglr

This package has no citation file, so citation() returns this entry built from DESCRIPTION.

Cite the R Observatory

For a number measured here: a download total, a coverage figure, an archival date.

APA

Balamuta, J. J. (2026). R Observatory: Metrics for togglr version 1.0.0 [Data set]. HJJB, LLC. Data release v2026-10-22. https://doi.org/10.5281/zenodo.21843040

From data release v2026-10-22, which the citation names so these numbers can be found later. More on citing and the projects behind them.

Report a problem with this page →

Privacy choices

These apply to this browser and are stored on this device only. Nothing about your choice is sent to us.

Read the privacy policy