fred provides clean, tidy access to economic data from the Federal Reserve Economic Data (FRED) API directly from R.
The Federal Reserve Economic Data (FRED) database is maintained by the Federal Reserve Bank of St. Louis - one of twelve regional Reserve Banks in the US Federal Reserve System. While the Fed's Board of Governors in Washington sets monetary policy, the regional banks each developed their own research specialisms. St. Louis carved out a reputation for applied economic research and data dissemination, and FRED launched in 1991 as a dial-up bulletin board before moving to the web in the mid-1990s. It has since grown into arguably the single most important free data platform for macroeconomic research, now hosting over 800,000 time series covering GDP, employment, inflation, interest rates, trade, financial markets, and more.
What makes FRED unusual is its role as an aggregator. The database doesn't just publish the St. Louis Fed's own data - it pulls in series from 118 different sources, including the Bureau of Labor Statistics, Bureau of Economic Analysis, Census Bureau, Treasury Department, World Bank, and dozens of other US and international agencies. Rather than visiting each agency's website individually and navigating their different data formats, FRED gives you a single, consistent interface to all of them. It's the closest thing economics has to a universal data catalogue.
FRED provides a free REST API that gives programmatic access to the full database. The API supports searching for series, fetching observations, browsing the category tree, tracking data releases and revisions, and applying server-side transformations like percent change or frequency aggregation - all without needing to visit the website. Anyone can register for a free API key.
This package wraps the FRED API so you can pull data directly into R with a single function call. Rather than constructing API URLs by hand, fred_series("GDP") fetches the data, parses the response, and returns a tidy data frame. You can fetch multiple series at once, apply transformations, search by keyword, browse categories, and track revisions - all from R. Results are cached locally so repeated calls are instant.
There is an existing R package called fredr, written by Sam Boysel and Davis Vaughan and published on CRAN in 2021. It's a solid package, but it hasn't been updated since August 2021.
What's better for users:
- Multiple series in one call - fredr can only fetch one series at a time, so pulling GDP, unemployment, and CPI means three separate requests and manually binding the results. With fred,
fred_series(c("GDP", "UNRATE", "CPIAUCSL"))returns everything in one tidy data frame. - Local caching - fredr downloads data fresh every time you run your script. If you're knitting a Quarto report and tweaking a chart title, it re-downloads everything from scratch on every render. fred caches results locally after the first download, so subsequent calls are instant and don't touch the API.
- Automatic pagination - FRED's API returns results in pages of 1,000. If a category has 2,500 series, fredr gives you the first 1,000 and stops - most users won't realise they're getting incomplete data. fred automatically fetches all pages and stitches them together.
What's better under the hood:
- Modern HTTP stack - fredr depends on
httr, which has been superseded byhttr2. fred useshttr2with built-in rate-limit retries and graceful error handling when the API is unreachable. - Fewer dependencies - fred depends on 3 third-party packages (
cli,httr2,tools) plus base R. fredr pulls inhttr,jsonlite,rlang,tibble, andpurrr. - Research-grade infrastructure - offline catalogue of ~50 popular series, NBER recession reference dates, FOMC meeting reference dates, vintage revision summaries, BibTeX/YAML reproducibility helpers, and a default
plot()method with NBER recession shading. - Actively maintained - fredr has had no updates since August 2021.
install.packages("fred")
# Or install the development version from GitHub
# install.packages("devtools")
devtools::install_github("charlescoverdale/fred")You need a free API key to use this package. The FRED API requires authentication so the St. Louis Fed can manage server load - but the key is completely free and takes about two minutes to set up. You only need to do this once.
- Go to https://fredaccount.stlouisfed.org/login/secure/
- Click Create New Account
- Fill in your name, email, and a password, then click Create Account
- Check your email and click the verification link
- Once logged in, go to https://fredaccount.stlouisfed.org/apikeys
- Click Request API Key
- Enter a short description (e.g. "R data analysis") and agree to the terms
- Your API key will appear on screen - it's a string of letters and numbers like
abcdef1234567890abcdef1234567890 - Copy it
The best approach is to store your key in a file called .Renviron, which R reads automatically every time it starts. This means you only set it once and never have to think about it again.
Option A: From RStudio
- Open RStudio
- In the console, type
file.edit("~/.Renviron")and press Enter - this opens (or creates) the file - Add this line, replacing the placeholder with your actual key:
FRED_API_KEY=abcdef1234567890abcdef1234567890 - Save the file and close it
- Restart R (Session → Restart R, or press Ctrl+Shift+F10 / Cmd+Shift+F10)
Option B: From the terminal
- Open Terminal (Mac/Linux) or Command Prompt (Windows)
- Run this command, replacing the placeholder with your actual key:
echo 'FRED_API_KEY=abcdef1234567890abcdef1234567890' >> ~/.Renviron
- Restart R
Option C: Set it for the current session only
If you just want to try things out without editing any files, you can set the key temporarily:
library(fred)
fred_set_key("abcdef1234567890abcdef1234567890")This only lasts until you close R - you'll need to run it again next session.
After restarting R, check that the key is picked up:
library(fred)
fred_get_key()
#> [1] "abcdef1234567890abcdef1234567890"If that prints your key, you're good to go.
Every dataset in FRED has a short series ID. For example, GDP is US quarterly GDP, UNRATE is the US unemployment rate, and CPIAUCSL is the Consumer Price Index. You need to know the series ID to pull data.
There are four ways to find it:
1. Curated offline catalogue using fred_catalogue(). Around 50 of the most-used series, grouped by category, with no API call needed:
fred_catalogue(category = "Inflation")
#> # FRED: catalogue · 6 rows
#> id title frequency category
#> CPIAUCSL CPI for All Urban Consumers: All Items M Inflation
#> CPILFESL CPI for All Urban Consumers: Less Food and Energy M Inflation
#> PCEPI PCE: Chain-type Price Index M Inflation
#> ...
fred_catalogue(query = "mortgage")
#> # FRED: catalogue · 1 row
#> id title frequency category
#> MORTGAGE30US 30-Year Fixed Rate Mortgage Average W Interest Rates2. Search from R using fred_search() for the full FRED database (live API):
fred_search("consumer price index")3. Browse the category tree using fred_browse() (top-level categories are offline; deeper levels hit the API):
fred_browse()
#> FRED top-level categories
#> -------------------------
#> 32991 Money, Banking, & Finance
#> 10 Population, Employment, & Labor Markets
#> 32992 National Accounts
#> 1 Production & Business Activity
#> 32455 Prices
#> ...4. Browse the FRED website at fred.stlouisfed.org.
Once you have a series ID, pass it to fred_series().
library(fred)
# US quarterly GDP
gdp <- fred_series("GDP")
tail(gdp)
#> date series_id value
#> 2023-04-01 GDP 27063.01
#> 2023-07-01 GDP 27610.55
#> ...# GDP, unemployment, and CPI together
macro <- fred_series(c("GDP", "UNRATE", "CPIAUCSL"))
# Returns a single data frame with a series_id column
table(macro$series_id)
#> CPIAUCSL GDP UNRATE
#> 977 310 953FRED can compute transformations server-side, so you don't have to calculate them yourself.
# Year-on-year percent change in GDP
gdp_growth <- fred_series("GDP", units = "pc1")
tail(gdp_growth, 4)
#> date series_id value
#> 2023-01-01 GDP 3.57
#> 2023-04-01 GDP 4.49
#> 2023-07-01 GDP 5.36
#> 2023-10-01 GDP 5.78
# Other options: "pch" (period-on-period %), "chg" (level change),
# "log" (natural log), "pca" (annualised rate)# CPI since 2020 only
cpi <- fred_series("CPIAUCSL", from = "2020-01-01")
head(cpi, 4)
#> date series_id value
#> 2020-01-01 CPIAUCSL 257.971
#> 2020-02-01 CPIAUCSL 258.678
#> 2020-03-01 CPIAUCSL 258.115
#> 2020-04-01 CPIAUCSL 256.389# The 10-year Treasury yield is published daily.
# Aggregate to monthly averages:
rates <- fred_series("DGS10", frequency = "m")
tail(rates, 4)
#> date series_id value
#> 2024-09-01 DGS10 3.73
#> 2024-10-01 DGS10 4.10
#> 2024-11-01 DGS10 4.34
#> 2024-12-01 DGS10 4.39
# Or get end-of-period values instead of averages:
rates_eop <- fred_series("DGS10", frequency = "m", aggregation = "eop")fred_info("UNRATE")
#> id title frequency units seasonal_adjustment
#> UNRATE Unemployment Rate Monthly % Seasonally AdjustedFor multi-series analysis it's often easier to have one column per series. Pass format = "wide":
macro <- fred_series(c("GDP", "UNRATE", "CPIAUCSL"),
from = "2020-01-01", format = "wide")
head(macro)
#> # FRED: 3 series · 60 obs · format=wide
#> date GDP UNRATE CPIAUCSL
#> 2020-01-01 21561.14 3.5 259.037
#> 2020-02-01 NA 3.5 259.250
#> 2020-03-01 21289.27 4.4 258.115
#> ...The header at the top is a one-line summary of the query (series count, observations, transform, frequency, vintage). Downstream code can treat the result as a normal data frame.
The raw FRED units codes (pch, pc1, cca, etc.) work fine, but they're not always memorable. You can pass transform = instead:
# Year-on-year percent change in CPI
fred_series("CPIAUCSL", transform = "yoy_pct")
# Continuously compounded annual rate
fred_series("GDP", transform = "log_diff_annualised")
# Quarter-on-quarter level change
fred_series("GDP", transform = "diff")Available aliases: level, raw, diff, change, yoy_diff, qoq_pct, mom_pct, pop_pct, yoy_pct, annualised, qoq_annualised, log, log_diff, log_diff_annualised. The units and transform arguments are mutually exclusive.
FRED keeps the full revision history for most series via its sister database, ALFRED. fred exposes this through four helpers, all of which add realtime_start and realtime_end columns to the returned data frame.
# 1. The series as it appeared on a specific date
gdp_then <- fred_as_of("GDP", date = "2020-03-01")
# 2. Only the first release of each observation, never revised
gdp_first <- fred_first_release("GDP", from = "2010-01-01")
# 3. Every vintage in the revision history
# (potentially large - narrow with from/to for long series)
gdp_all <- fred_all_vintages("GDP", from = "2020-01-01")
# 4. A panel of selected vintage snapshots
gdp_panel <- fred_real_time_panel(
"GDP",
vintages = c("2020-04-30", "2020-07-31", "2020-10-31", "2021-01-31")
)These are the building blocks for pseudo-real-time forecasting backtests and revision studies. They cache separately from the default (latest-vintage) cache, so calling fred_series("GDP") and fred_as_of("GDP", "2020-03-01") keep distinct cache entries.
fred_cache_info()
#> $dir
#> [1] "/Users/.../R/fred/cache"
#>
#> $n_files
#> [1] 27
#>
#> $size_human
#> [1] "412.3 KB"
#>
#> $files
#> name size_bytes modified
#> obs_GDP_lin_avg.rds 18234 2026-04-09 11:02:13
#> obs_UNRATE_lin_avg.rds 16711 2026-04-09 11:02:14
#> ...clear_cache() wipes everything; fred_cache_info() lets you check what's there before you do.
Every fred_series() result is a fred_tbl, so you can call plot() directly and get a sensible default:
panel <- fred_series(c("UNRATE", "CIVPART"), from = "2000-01-01",
format = "wide")
plot(panel, ylab = "%", main = "US labour market")Recession shading uses NBER reference dates from fred_recession_dates(). Pass recessions = FALSE to switch it off. No ggplot2 dependency.
# All 34 NBER recessions since 1857
fred_recession_dates()
# Modern era only, with duration
fred_recession_dates(from = "1948-01-01")
# Flag a vector of dates as in/out of recession
fred_recession_dates(flag = seq(as.Date("2007-01-01"),
as.Date("2010-12-01"), by = "month"))
# FOMC scheduled meeting dates 2017-2025, with SEP flag
fred_fomc_dates(year = 2024, sep_only = TRUE)
#> # FRED: fomc_dates · 4 rows
#> date type sep
#> 2024-03-20 regular TRUE
#> 2024-06-12 regular TRUE
#> 2024-09-18 regular TRUE
#> 2024-12-18 regular TRUE# Aggregate daily to monthly with any summary
yields_m <- fred_aggregate(fred_series("DGS10", from = "2023-01-01"),
fun = "mean", by = "month")
# Fill NAs with last-observation-carry-forward or linear interpolation
filled <- fred_interpolate(fred_series("GDPC1"), method = "linear")
# Extract data inside a window around event dates (e.g. FOMC meetings)
ur <- fred_series("UNRATE", from = "2023-01-01")
sep <- fred_fomc_dates(year = 2024, sep_only = TRUE)
fred_event_window(ur, events = sep$date, window = c(-60L, 60L))# BibTeX citation pinned to a vintage date
fred_cite_series("GDPC1", vintage_date = "2024-12-18", format = "bibtex")
# Plain text citation
fred_cite_series("UNRATE", format = "text")
# YAML manifest with MD5 hash per object - save alongside paper code
gdp <- fred_series("GDPC1", from = "2020-01-01")
ur <- fred_series("UNRATE", from = "2020-01-01")
m <- fred_manifest(gdp = gdp, unrate = ur,
file = "data/manifest.yml")
# Per-observation revision statistics
fred_vintage_revisions("GDPC1", from = "2018-01-01")vignette("multi-series-workflows", "fred")- fetch, transform, widen, plot.vignette("nowcasting-with-fred", "fred")- pseudo-real-time GDP nowcasting with monthly indicators (pairs with thenowcastpackage).vignette("inflation-revisions", "fred")- tracking core inflation revisions across FOMC SEP meeting vintages.
Data fetching
| Function | Description |
|---|---|
fred_series() |
Fetch observations for one or more series (long or wide) |
fred_info() |
Get series metadata |
fred_request() |
Raw API request (power users) |
Real-time and vintages (ALFRED)
| Function | Description |
|---|---|
fred_as_of() |
Fetch a series as it appeared on a specific vintage date |
fred_first_release() |
Fetch only the initial release of each observation |
fred_all_vintages() |
Fetch every vintage in the revision history |
fred_real_time_panel() |
Fetch a panel of selected vintage snapshots |
fred_vintages() |
Get revision dates for a series |
fred_vintage_revisions() |
Per-observation revision summary statistics |
Discoverability
| Function | Description |
|---|---|
fred_catalogue() |
Curated offline catalogue of ~50 popular series |
fred_browse() |
Pretty-print the FRED category tree |
fred_search() |
Search for series by keyword or ID |
fred_recession_dates() |
NBER recession reference dates (1857-2020) + flagger |
fred_fomc_dates() |
FOMC scheduled meeting dates 2017-2025 with SEP flags |
Catalogue browsing
| Function | Description |
|---|---|
fred_category() |
Get category information |
fred_category_children() |
List child categories |
fred_category_series() |
List series in a category |
fred_releases() |
List all data releases |
fred_release_series() |
List series in a release |
fred_release_dates() |
Get release publication dates |
fred_sources() |
List all data sources |
fred_source_releases() |
List releases from a source |
fred_tags() |
List or search tags |
fred_related_tags() |
Find related tags |
fred_updates() |
List recently updated series |
Workflow utilities
| Function | Description |
|---|---|
fred_event_window() |
Extract data around event dates |
fred_aggregate() |
Collapse to coarser frequency (week/month/quarter/year) |
fred_interpolate() |
Fill NAs via locf or linear interpolation |
plot.fred_tbl() |
Default plot with NBER recession shading |
summary.fred_tbl() |
Query metadata + dimensions + ranges |
Reproducibility
| Function | Description |
|---|---|
fred_cite_series() |
BibTeX, plain text, or bibentry citation, vintage-pinned |
fred_manifest() |
YAML snapshot with MD5 hash per object |
Configuration
| Function | Description |
|---|---|
fred_set_key() |
Set API key for session |
fred_get_key() |
Get current API key |
fred_cache_info() |
Inspect the local cache |
clear_cache() |
Clear local cache |
| Package | Description |
|---|---|
boe |
Bank of England data (peer central bank) |
readecb |
European Central Bank data (peer central bank) |
readoecd |
OECD international data |
yieldcurves |
Yield curve fitting (Nelson-Siegel, Svensson) |
mpshock |
Monetary policy shock series (US/UK/AU) |
inflationkit |
Inflation analysis (decomposition, persistence, Phillips curve) |
nowcast |
Economic nowcasting (bridge, MIDAS, DFM) |
debtkit |
Debt sustainability analysis |
This product uses the FRED® API but is not endorsed or certified by the Federal Reserve Bank of St. Louis.
FRED, Federal Reserve, economic data, macroeconomic data, time series, US economy, interest rates, inflation, GDP, unemployment, monetary policy, St. Louis Fed, API, R package