I tried you code and put together a working example that should get you past the error in Step 5.
The script below retrieves data for multiple tables (Parts 1, 2, and 3) and can be adapted for state or county.
For Parts 3 "Flow" tables, it seems necessary to use parameters "for" and "d-for" to identify the origin and destination geographies.
For tables in Part 1 and Part 2, I feel it is more convenient to use 'for' instead of 'geo'. I’m still a bit unsure about the geoid—it appears to have different prefix codes depending on the geographic summary level used in each table.
Here’s a starting point, feel free to tweak.
#1. load the R libraries jsonlite and httr
library(jsonlite)
library(httr)
#2. Save your API key
api_key <- ("XXXXXXXX")
#3. Define API Endpoint: Specify the URL of the API endpoint you want to access
url <- "https://ctppdata.transportation.org/api/data/2021"
#4. Set Headers: Create a list of headers required for the API request, including the API key.
headers <- c(Accept = "application/json", "x-api-key" = api_key)
#5. Prepare Parameters: Define the parameters needed for your API call. # may include specifying the type of data you want (like geographic IDs)
#6. Make the Request: Use the httr package send a GET request to the API.
## Part 1 residence - table b101100 total population
params <- list(get = "b101100_e1,b101100_m1",
geo ="C0300US06001,C0300US06005,C0300US06019")
response <- GET(url, add_headers(.headers = headers), query = params)
res_data <- fromJSON(rawToChar(response$content))
print(res_data$data)
### Use `for` instead of `geo`
params <- list(get = "b101100_e1,b101100_m1",
`for` ="county:001,005,019", # County FIPS
`in` ="state:06") # state FIPS
response <- GET(url, add_headers(.headers = headers), query = params)
res_data <- fromJSON(rawToChar(response$content))
print(res_data$data)
## Part 2 workplace - table b202101 age of worker, read entire group
params <- list(get = "group(b202101)",
geo ="C2300US06001,C2300US06005,C2300US06019")
response <- GET(url, add_headers(.headers = headers), query = params)
res_data <- fromJSON(rawToChar(response$content))
print(res_data$data)
### get the variables name
url_group <- "https://ctppdata.transportation.org/api/groups/b202101/variables"
params <- list(year="2021")
response <- GET(url_group, add_headers(.headers = headers), query = params)
res_data_name <- fromJSON(rawToChar(response$content))
print(res_data_name$data)
res_data_name$data$label[which(res_data_name$data$name=='B202101_e8')]
## Part 3 Flow - b302100 Total workers
### selected state to state
params <- list(get = "b302100_e1,b302100_m1",
`for` ="state:06",`d-for` = "state:32,53") # Origin:CA , Destination: Nevada, Washington
response <- GET(url, add_headers(.headers = headers), query = params)
res_data <- fromJSON(rawToChar(response$content))
print(res_data$data)
### selected county to county
params <- list(get = "b302100_e1,b302100_m1",
`for` ="county:001,005,019", # From: County FIPS
`in` ="state:06", # From: State FIPS
`d-for` = "county:001,005,019", # To: County FIPS
`d-in` ="state:06") # To: State FIPS
response <- GET(url, add_headers(.headers = headers), query = params)
res_data <- fromJSON(rawToChar(response$content))
print(res_data$data)
I’m not an API expert myself — this one’s new to me too — so if anyone else on the list has a better or more efficient solution, please chime in. Always great to see different approaches.
I've found the CTPP API Explorer page very helpful for understanding the data structures. It would be great if it included an example for a Part 3 table, since the flow data is probably what people are most interested in when working with CTPP. A codebook
in CSV format would also be super handy for searching variable names.
CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
I’ve tested the new chatbot on the CTPP Data Portal, with generally positive results.
Questions I’ve asked include:
1. How can I modify the API scripts to work in the R statistical package?
2. How do I store my API key in an r statistical package environment variable?
The chatbot gave full and easy-to-implement code to store my personal CTPP API key. Good
Various versions of my request for API scripts in R package gave various results.
It was awkward to cut-and-paste my question and the answer I received from the AI chatbot.
Basically:
1. load the R libraries jsonlite and httr
library(jsonlite)
library(httr)
2. Save your API key in your R environment
# Edit your R profile
usethis::edit_r_profile()
Sys.setenv(CTPP_KEY = "mytopsecretapikeyxxxxxxx")
api_key <- Sys.getenv("CTPP_KEY”)
3. Define API Endpoint: Specify the URL of the API endpoint you want to access
url <- "https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fctppdata.transportation.org%2fapi%2fdata%2f2021%e2%80%9d&c=E,1,LM9kkJ8p23BfAjP2MDY7SMjMqETMt5dsPpf8FDgJt8GLvGGHungZ_WJcZKsjW2x9aRyrp9yVgfpghQFx0Lo-8VxGZax-FlkpLQd4esdnPCbvdifzwTo,&typo=1
4. **Set Headers**: Create a list of headers required for the API request, including the API key.
headers <- c(Accept = "application/json", "x-api-key" = api_key)
5. Prepare Parameters: Define the parameters needed for your API call.
# may include specifying the type of data you want (like geographic IDs)
params <- list(get = "b302100_e1,b302100_m1",geo = "C0300US06001,C0300US06005",
size = 10,page = 1)
6. Make the Request: Use the httr package send a GET request to the API.
response <- GET(url, add_headers(.headers = headers), query = params)
############################################################################
The code is failing around step 5: defining the tables and geography for the API data pull….
I really could use some human assistance to fix this R code. I heard there is a cabal of MPO data people who can code anything and everything in R or Python. Can somebody help me?
I’d like to develop examples, in R script, to retrieve data for various tables (Parts 1, 2 and 3) for various geographies (state, county, place, tract). Obviously I’ll share my R code in my bithub repository.
I just need a collaborator / hand-holder.
I received no feedback on my April 4, 2025 post to this CTPP listserv. My guess is that too few people have actually tried to use the API, or they’re too shy to provide feedback.
Hope to hear from you!
Chuck Purvis,
Hayward, California
PS, The single-year 2024 ACS data is scheduled for release in one month, on September 11, 2025. Should keep us busy for a few days. And the five-year, 2020-2024 ACS is scheduled for December 11, 2025.
###
_______________________________________________
CTPP mailing list -- ctpp@listserv.transportation.org
To unsubscribe send an email to ctpp-leave@listserv.transportation.org