This vignette covers everything get_group() does when a
folder already exists, downloading all groups of a user, and the helper
functions. For a first download, see
vignette("zotFunc").
Output formats
output_format takes any Zotero
export format: bibtex, biblatex,
bookmarks, coins, csljson,
csv, mods, refer,
rdf_bibliontology, rdf_dc,
rdf_zotero, ris, tei or
wikipedia. NULL, the default for a new
download, gives Zotero’s own JSON. This is the most complete format but
also the slowest.
Each page of 100 records is saved as
<format>_<first record>.<extension>, for
example bibtex_300.bib or csljson_0.json.
Zotero counts notes and attachments as records, but most export formats
skip them. A page holding only notes and attachments would be empty (for
csv: only the header), so it is not saved, and some numbers
can be missing.
Parallel download and rate limits
The first page is downloaded alone, as its response gives the number
of records. The other pages are downloaded in parallel,
max_active (default 4) at a time. This follows
the rate
limits of the Zotero API:
- never more than 4 concurrent requests, so
max_activemust be 1 to 4; - a
Backoffheader pauses the download for the requested number of seconds once the running requests are done; - a
429 Too Many Requestsor503response is retried after itsRetry-After(or with exponential backoff), and all other requests wait as well.
If Zotero keeps answering with 429, download fewer pages
at a time:
get_group(path = "nff", force = TRUE, max_active = 1)get_groups_from_user() passes max_active
on, but downloads the groups one after the other.
The files describing a download
| File | Content |
|---|---|
.id |
the group id |
.name |
the group name |
.version |
the group’s library version, read before the download started |
.format |
the output format (json for
output_format = NULL) |
The version is read before the download, not after it. If someone edits the group while a long download runs, the next update sees a newer version and downloads again, instead of missing that edit.
Updating an existing folder
When path already exists, get_group()
decides what to do. A download is a folder containing
.version, written at the end of a successful
get_group().
| Situation | Result |
|---|---|
download, update = FALSE
|
error, folder untouched |
folder holds a different group than group_id
|
error, folder untouched |
server version older than .version
|
error, folder untouched |
server version newer than .version
|
folder replaced by a new download |
| versions equal, same format | nothing downloaded |
versions equal, force = TRUE
|
folder replaced by a new download |
versions equal, different output_format requested |
folder replaced by a new download |
not a download (no .version),
overwrite = FALSE
|
error, folder untouched |
not a download, overwrite = TRUE
|
folder deleted, group downloaded |
| empty folder | group downloaded into it |
If group_id or output_format are not given,
they are read from .id and .format.
# download again even though nothing changed
get_group(path = "nff", force = TRUE)
# switch the folder to CSL JSON
get_group(path = "nff", output_format = "csljson")
#> Format changes from bibtex to csljson - downloading again.
#> ...
# never touch an existing download
get_group(path = "nff", update = FALSE)
#> Error in get_group(path = "nff", update = FALSE) :
#> `path` nff contains a download. Delete it or use `update = TRUE`.
# a folder that is not a download is protected
get_group(4937409, path = "my_documents")
#> Error in get_group(4937409, path = "my_documents") :
#> `path` my_documents exists and is not a previous download (no `.version`). Use `overwrite = TRUE` to delete it.
# the folder belongs to another group
get_group(1, path = "nff")
#> Error in group_outdated(path, group_id = group_id, api_key = api_key) :
#> `nff` contains group 4937409 but group 1 was requested.Checking without downloading
group_outdated() compares a folder with the server. It
returns a logical named with the group id: TRUE if the
server has a newer version.
group_outdated("nff")
#> 4937409
#> FALSEIt raises an error if the server version is older than the downloaded
one, which should not happen with a real group. Here
.version was set to 999999999 by hand:
group_outdated("nff")
#> Error in group_outdated("nff") :
#> Server version (2053) of group 4937409 is older than the downloaded version (999999999).For a quick overview of several downloads:
All groups of a user
get_groups_from_user() downloads every group of a Zotero
user into sub-folders named
<group name>_<group id>, and runs
get_group() for each, so all the update rules above apply
per group.
get_groups_from_user(
zotero_user_name = "ipbes",
path = "ipbes_groups",
output_format = "bibtex",
api_key = Sys.getenv("ZOTERO_API_KEY")
)Public groups work without an API key; private groups need a key with
read access, created at zotero.org/settings/security.
Note that api_key defaults to the environment variable
ZOTERO_API_IPBES.
The user is stored in .user_id and
.user_name in path, so a later update only
needs the folder:
get_groups_from_user(path = "ipbes_groups", api_key = Sys.getenv("ZOTERO_API_KEY"))Without output_format, existing groups keep the format
in their .format and new groups use
"rdf_zotero". A group that fails (for example a private
group without a key) prints its error and the next group continues.
Helper functions
Library version
The library version is an integer that Zotero increases with every
change to the group: items, collections, saved searches and deletions.
It is what group_outdated() compares.
get_group_version(4937409)
#> [1] 2053Last modification time
The modification time of the most recently changed item. Unlike the version, it ignores changes to collections only.
get_group_last_modified(4937409)
#> [1] "2026-09-30 07:14:51 UTC"User id from user name
Most functions need the numeric user id. id_from_name()
reads it from the public profile page:
id_from_name("ipbes")
#> [1] "5760254"It parses the HTML of the profile page, which Zotero can change at any time. In scripts, look the id up once and use it directly.
Groups of a user
ids <- get_groupids_from_user(zotero_user_id = "5760254")
head(ids, 3)
#> IPBES NXS IPBES TCA IPBES BBA
#> "4596166" "4589462" "5081872"This returns at most 25 groups, the Zotero default page size.