Skip to contents

These are low level functions for constructing requests to the CrossFit API. You can use them to build custom requests along with the data objects if the wrapped functions don't provide enough flexibility or don't hit an endpoint you'd like to see. Be aware that certain endpoints may lose support for query parameters as you go back in time. Additionally different endpoints require different query parameters, but none of this is documented on the CrossFit side.

cf_request() creates the base request object for a particular competition/year combination. Always start with this object.

Then you can layer in additional query parameter modifiers:

  • cf_req_division(): Request a particular division. The set of divisions can be seen with cf_division.

  • cf_req_region(): Request a particular region. The set of regions can be seen with cf_region. The easiest to use is cf_region$worldwide.

  • cf_req_scale(): Request a particular scale (Rx, Scaled, Foundations). The set of scales can be seen with cf_scale.

  • cf_req_limit(): Alter the number of returned rows. Default seems to be 50 if you don't set anything, and has a maximum value of 100.

  • cf_req_affiliate(): Request a particular affiliate's data. You'll have to look up your affiliate's ID on the CrossFit website. It is generally in the URL on your affiliate's webpage.

  • cf_req_page(): Alter the current page, i.e. for use with pagination. If you process a response with resp_body_json() and look at resp$pagination, then there is typically some information there about which page you are currently on and how many pages of data are available.

Usage

cf_request(competition, year)

cf_req_division(req, division)

cf_req_region(req, region)

cf_req_scale(req, scale)

cf_req_limit(req, limit)

cf_req_affiliate(req, affiliate)

cf_req_page(req, page)

Arguments

competition

A competition. One of the values from cf_competition.

year

A single integer of the year to retrieve data for.

req

A request object from cf_request() to modify.

division

A division. One of the values from cf_division.

region

A region. One of the values from cf_region.

scale

A workout scaling. One of the values from cf_scale.

limit

The number of rows to return. A single integer between [0, 100].

affiliate

A single integer of the affiliate ID to return data for.

page

A single integer of the "current page" to retrieve data for.

Value

A request object.

Examples

library(tidyr)
library(tibble)
library(dplyr)
#> 
#> Attaching package: ‘dplyr’
#> The following objects are masked from ‘package:stats’:
#> 
#>     filter, lag
#> The following objects are masked from ‘package:base’:
#> 
#>     intersect, setdiff, setequal, union

# ---------------------------------------------------------------------------

# Top two from the crossfit open 2022, Men's Rx
resp <- cf_request(cf_competition$open, 2022) %>%
  cf_req_division(cf_division$Men) %>%
  cf_req_region(cf_region$worldwide) %>%
  cf_req_scale(cf_scale$rx) %>%
  cf_req_limit(2L) %>%
  req_perform() %>%
  resp_body_json()

# Some pagination information here!
resp$pagination
#> $totalPages
#> [1] 77408
#> 
#> $totalCompetitors
#> [1] 154815
#> 
#> $currentPage
#> [1] 1
#> 

leaderboard <- tibble(rows = resp$leaderboardRows)
leaderboard
#> # A tibble: 2 × 1
#>   rows            
#>   <list>          
#> 1 <named list [6]>
#> 2 <named list [6]>

leaderboard %>%
  unnest_wider(rows)
#> # A tibble: 2 × 6
#>   overallRank overallScore nextStage ui               entrant           scores
#>   <chr>       <chr>        <chr>     <list>           <list>            <list>
#> 1 1           25           ""        <named list [2]> <named list [20]> <list>
#> 2 2           28           ""        <named list [2]> <named list [20]> <list>

leaderboard %>%
  unnest_wider(rows) %>%
  unnest_wider(entrant)
#> # A tibble: 2 × 25
#>   overallRank overallScore nextStage ui           competitorId competitorName
#>   <chr>       <chr>        <chr>     <list>       <chr>        <chr>         
#> 1 1           25           ""        <named list> 310970       Saxon Panchik 
#> 2 2           28           ""        <named list> 1454081      Matt Poulin   
#> # … with 19 more variables: firstName <chr>, lastName <chr>, status <chr>,
#> #   postCompStatus <chr>, gender <chr>, profilePicS3key <chr>,
#> #   countryOfOriginCode <chr>, countryOfOriginName <chr>,
#> #   countryShortCode <chr>, regionId <chr>, regionName <chr>, divisionId <chr>,
#> #   affiliateId <chr>, affiliateName <chr>, age <chr>, height <chr>,
#> #   weight <chr>, teamCaptain <chr>, scores <list>

# 2022's 3 workouts
workouts <- leaderboard %>%
  unnest_wider(rows) %>%
  unnest_wider(entrant) %>%
  hoist(scores, one = 1, two = 2, three = 3)

# Let's look at 22.1
workouts %>%
  select(competitorName, one) %>%
  unnest_wider(one) %>%
  select(competitorName, rank, score, scoreDisplay, breakdown)
#> # A tibble: 2 × 5
#>   competitorName rank  score   scoreDisplay breakdown                           
#>   <chr>          <chr> <chr>   <chr>        <chr>                               
#> 1 Saxon Panchik  3     3800000 380 reps     "12 rounds +\n3 wall walks\n12 db s…
#> 2 Matt Poulin    10    3640000 364 reps     "12 rounds +\n3 wall walks\n1 db sn…

# ---------------------------------------------------------------------------

# Top five from the crossfit games 2021 Women's division
resp <- cf_request(cf_competition$games, 2021) %>%
  cf_req_division(cf_division$Women) %>%
  cf_req_limit(5L) %>%
  req_perform() %>%
  resp_body_json()

leaderboard <- tibble(rows = resp$leaderboardRows)
leaderboard
#> # A tibble: 5 × 1
#>   rows            
#>   <list>          
#> 1 <named list [6]>
#> 2 <named list [6]>
#> 3 <named list [6]>
#> 4 <named list [6]>
#> 5 <named list [6]>

# Toomey, of course
leaderboard %>%
  unnest_wider(rows) %>%
  unnest_wider(entrant)
#> # A tibble: 5 × 25
#>   overallRank overallScore nextStage ui           competitorId competitorName   
#>   <chr>       <chr>        <chr>     <list>       <chr>        <chr>            
#> 1 1           1435         ""        <named list> 163097       Tia-Clair Toomey 
#> 2 2           1179         ""        <named list> 591912       Laura Horváth    
#> 3 3           1099         ""        <named list> 18588        Annie Thorisdott…
#> 4 4           1064         ""        <named list> 120480       Kristin Holte    
#> 5 5           995          ""        <named list> 671666       Haley Adams      
#> # … with 19 more variables: firstName <chr>, lastName <chr>, status <chr>,
#> #   postCompStatus <chr>, gender <chr>, profilePicS3key <chr>,
#> #   countryOfOriginCode <chr>, countryOfOriginName <chr>,
#> #   countryShortCode <chr>, regionId <chr>, regionName <chr>, divisionId <chr>,
#> #   affiliateId <chr>, affiliateName <chr>, age <chr>, height <chr>,
#> #   weight <chr>, teamCaptain <chr>, scores <list>

# There are actually 15 workouts here, let's just pick the first
workouts <- leaderboard %>%
  unnest_wider(rows) %>%
  unnest_wider(entrant) %>%
  hoist(scores, one = 1)

workouts %>%
  select(competitorName, one) %>%
  unnest_wider(one) %>%
  select(competitorName, rank, score)
#> # A tibble: 5 × 3
#>   competitorName     rank  score
#>   <chr>              <chr> <chr>
#> 1 Tia-Clair Toomey   1     100  
#> 2 Laura Horváth      8     79   
#> 3 Annie Thorisdottir 18    49   
#> 4 Kristin Holte      11    70   
#> 5 Haley Adams        5     88