Provides pipe-friendly, stateless read access to the Breeding API ('BrAPI') v2.1 specification, an open community standard for plant breeding data interchange maintained by the BrAPI project < https://brapi.org>. Wraps 32 of the 37 'BrAPI' v2.1 entities across all four modules, Core, Germplasm, Phenotyping, and Genotyping, covering 49 of the specification's 138 retrieval ('GET' and search) endpoints and returning tidy tibbles ready for analysis. Write and update endpoints are out of scope by design. Features include automatic pagination, async search handling, response caching, parallel batch fetching, and convenience functions for genomic selection workflows (e.g. dosage matrix extraction). Designed for plant breeders and bioinformaticians who need programmatic access to plant breeding databases that implement the 'BrAPI' v2 specification.

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 ([email protected]).
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