Skip to contents

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 ().

Supported BrAPI Modules

Every entity brapiR2 wraps, by module:

  • Core: Programs, Trials, Studies, Locations, Seasons, Lists, People
  • Germplasm: Germplasm, Progeny, Attributes, Crosses, Seed Lots, and Pedigree - both single-germplasm (brapi_germplasm_pedigree()) and batch/tree retrieval across many germplasm at once (brapi_pedigree(), brapi_search_pedigree())
  • Phenotyping: Observation Units, Observations, Variables, Traits, Scales, Methods, Ontologies, Images, Events
  • Genotyping: Samples, Variants, Variant Sets, Calls, Call Sets, References, Allele Matrix, Genome Maps

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.

Tested against

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.

Installation

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)

Quick Start

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

Authentication

# 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")

Pipe-Friendly Design

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)
  • QBMS — High-level, stateful BrAPI client for interactive use
  • BrAPI.R — HTTP transport layer for manual BrAPI calls, complementary to brapiR2’s named per-endpoint functions
  • rrBLUP — Genomic selection (use brapiR2 to fetch the dosage matrix)
  • sommer — Mixed models for multi-environment trials

brapiR2 and QBMS

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.

Other BrAPI v2 clients

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.

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

License

MIT © Joash Joshua Ayo