
brapiR2 is a tidyverse-native, stateless R client for the BrAPI v2 (Breeding API) specification. It provides pipe-friendly, read-only access across all four BrAPI modules - Core, Germplasm, Phenotyping, and Genotyping - wrapping 32 of the specification’s 37 entities (49 of 138 retrieval endpoints) and returning tidy tibbles ready for analysis.
Developed by Joash Joshua Ayo (joashjoshua789@gmail.com).
Every entity brapiR2 wraps, by module:
brapi_germplasm_pedigree()) and batch/tree retrieval
across many germplasm at once (brapi_pedigree(),
brapi_search_pedigree())Not yet covered: Common Crop Names, Germplasm Attribute Values,
Planned Crosses, Plates, and Vendor Samples (lab/vendor order-tracking).
brapiR2 is read-only by design - it does not implement BrAPI’s
POST/PUT write endpoints.
For the full list of endpoints and the function that wraps each one,
see ?brapi_coverage. Each function’s own help page names
its endpoint, links to the BrAPI v2.1 specification, and lists the query
parameters that endpoint accepts.
brapiR2 is developed against the public BrAPI test server and
exercised against every publicly reachable BrAPI v2 server I could find.
As of September 2026 that is eight servers across three implementations:
the reference server, six Breedbase deployments (Cassavabase,
Sweetpotatobase, Coffeabase, Citrusgreening, and the T3 oat and wheat
sandboxes), and USDA-GRIN, which runs GRIN-Global. Of 80 endpoint
probes, 62 succeeded. The failures are server-side rather than
client-side - timeouts on the largest Breedbase instances,
HTTP 500 on two of them, and endpoints GRIN-Global does not
implement - and each one is recorded in dev/SERVERS.md,
alongside the script that produced them.
BMS, EBS, GIGWA and Germinate have not been tested; I have no access to an instance of any of them. If you use brapiR2 against one of those, or any other BrAPI v2 server, reports of what does and does not work are welcome in the issue tracker.
Install from rOpenSci’s R-universe:
install.packages(
"brapiR2",
repos = c("https://ropensci.r-universe.dev", "https://cloud.r-project.org")
)Or the development version from GitHub:
# install.packages("pak")
pak::pak("ropensci/brapiR2")pak builds the vignette as part of the install. If you
prefer remotes or devtools, pass
build_vignettes = TRUE, or the vignette will not be
installed:
remotes::install_github("ropensci/brapiR2", build_vignettes = TRUE)library(brapiR2)
library(dplyr)
# 1. Connect (no global state!)
con <- brapi_connection("https://test-server.brapi.org")
# 2. Explore programs and trials
brapi_programs(con)
brapi_trials(con) |>
filter(active == TRUE) |>
head()
# 3. Get phenotypic data in analysis-ready wide format
data <- brapi_study_data(con, "study_01")
# 4. Get genotypic data as a dosage matrix for GS
dosage <- brapi_get_dosage_matrix(con, "variantset_01")
# 5. Parallel fetch across multiple studies - set the backend yourself;
# brapi_fetch_parallel() uses whatever plan is active rather than
# setting one for you
future::plan(future::multisession, workers = 4)
all_data <- brapi_fetch_parallel(
con,
brapi_study_data,
ids = c("study_01", "study_02", "study_03")
)
future::plan(future::sequential) # shut the workers back down when done# Token-based (most BrAPI servers)
con <- brapi_connection("https://my-breedbase.org")
con <- brapi_login(con, "username", "password")
# OAuth 2.0 (EBS and similar)
con <- brapi_login_oauth2(
con,
client_id = "my_id",
client_secret = "my_secret",
authorize_url = "https://auth.example.org/authorize",
access_url = "https://auth.example.org/token"
)
# Or set an existing token directly
con <- brapi_set_token(con, "my_existing_token")Every function takes a connection object as its first argument and returns a tibble, making it natural to chain with dplyr:
con <- brapi_connection("https://my-breedbase.org", token = "my_token")
# Find all germplasm used in a specific study
brapi_observation_units(con, studyDbId = "study_42") |>
select(germplasmDbId, germplasmName) |>
distinct()
# Get marker positions for a genotyping dataset - from the Genome Maps
# entity (a marker's position on a named map), not from Variant's own
# assembly coordinates, which many servers leave unpopulated
brapi_get_marker_map(con, variantSetDbId = "my_variantset") |>
filter(linkageGroupName == "chr1") |>
arrange(position)| Feature | brapiR2 | QBMS |
|---|---|---|
| Design | Stateless, functional, pipeable | Stateful, menu-driven |
| BrAPI v2 coverage | 32/37 entities, all 4 modules, read-only | See QBMS’s own documentation |
| Genotyping support | Native variants, callsets, dosage matrix | Via GIGWA wrapper |
| Return type | Always tibbles | Mixed lists/dataframes |
| Auth | Unified token/OAuth2 | Engine-specific functions |
| Caching | Built-in response caching | Limited |
brapiR2 complements QBMS - use QBMS for interactive exploration, use brapiR2 for programmatic pipelines and custom tooling.
brapir-v2 is another R client that, like brapiR2, targets the BrAPI v2 specification directly rather than v1. Its own README describes it as still under development, and the repository has had no commits in roughly four years (last pushed April 2022) - it does not appear to be actively maintained.
BrAPI.R
(David Waring, Cornell) is a different kind of tool entirely, and
complementary rather than competing: its own DESCRIPTION calls it
“simple wrapper functions for httr that make it easier to make manual
HTTP calls to a BrAPI server”, and its README is explicit that it “does
not have any knowledge of the currently supported BrAPI endpoints”. It’s
a transport layer - callers pass endpoint paths as strings
(GET, POST, and PUT are all
supported, plus a two-step search helper) and get back raw nested lists,
with a version argument that switches between BrAPI v1 and v2. It also
ships Breedbase-specific functions explicitly outside the BrAPI spec.
brapiR2 takes the opposite approach - named per-endpoint functions
returning tibbles - and covers less ground on writes: BrAPI.R’s
POST/PUT support covers exactly the write
operations brapiR2 deliberately omits.
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
MIT © Joash Joshua Ayo