Use R and Narwhal API to pull holidays, release dates, economics, commodity spot prices, FX rates and prediction-market odds with one API key. Keep the key in .Renviron, read the responses with httr2, and use the returned fields in your R script.
What you'll set up
R can call the Narwhal REST API through httr2 and read the JSON response. You will have a reusable narwhal() helper, calls for all six data areas, and a script you can schedule as pull.R. The helper uses https://api.narwhalapi.com as its base URL and adds the path and query parameters for each request. Narwhal economics data includes CPI, inflation, GDP and yields; the economics call here selects CPI observations.
The examples keep each response area in its own R object. Holidays and release dates come back as lists of records, as do CPI observations, exchange rates and prediction-market meetings. The commodity example reads a single price field. Keep those response shapes in mind when you select fields for calculations or turn records into a data frame.
Set your API key
- Create a free key Create your key at narwhalapi.com/signup. Narwhal uses one account and one API key across its data APIs.
- Store the key in .Renviron Put your key in
.Renvironwith the environment variable nameNARWHAL_API_KEY. Replace the placeholder with your key and keep the key out ofpull.R. The variable name must match the name passed toSys.getenv()in the helper. The...in the environment-variable example is the placeholder for your key.Environment variableNARWHAL_API_KEY=... - Install the R packages Install
httr2andjsonlitewith the command here. The request helper useshttr2to make the GET requests and read their JSON bodies.Install packagesinstall.packages(c("httr2", "jsonlite"))
Pull data with code
Save this code in pull.R. The helper reads NARWHAL_API_KEY with Sys.getenv() and sends the key as a bearer token, using the Authorization: Bearer YOUR_KEY header. Each call supplies a path; calls that need a date range or currency selection also supply query parameters. Use the same helper for the area samples that follow.
library(httr2)
narwhal <- function(path, ...) {
request("https://api.narwhalapi.com") |>
req_url_path_append(path) |>
req_url_query(...) |>
req_auth_bearer_token(Sys.getenv("NARWHAL_API_KEY")) |>
req_perform() |>
resp_body_json()
}
holidays <- narwhal("v1/calendars/holidays/USA/2026")$holidays
releases <- narwhal("v1/economics/calendar", countries = "USA",
start_date = "2026-11-01", end_date = "2026-11-30", limit = 100)$releases
cpi <- narwhal("v1/economics/USA/cpi/observations", start = "2025-09")$observations
brent <- as.numeric(narwhal("v1/commodities/spot/BRENT/USD")$price)
fx <- narwhal("v1/fx/rates/USD", currencies = "EUR,IDR")$rates
fed <- narwhal("v1/predictions/policy-paths/federal-reserve")$meetings
cpi_values <- vapply(cpi, function(row) as.numeric(row$value), numeric(1))
n <- length(cpi_values)
mom <- cpi_values[n] / cpi_values[n - 1] - 1
print(round(mom * 100, 2)) # month-on-month change in percent
Inside the helper, req_url_path_append(path) adds the endpoint path to the base URL, and req_url_query(...) adds the query arguments. req_auth_bearer_token() takes the key read from the environment. The call then uses req_perform() and resp_body_json() to return the response body to R. Read the named field from that body with $, as each area example does.
The CPI calculation reads each observation's value as a number. It divides the final value in the returned list by the preceding value, subtracts one, and prints the month-on-month change in percent. The period field belongs with each observation when you use its value outside the calculation.
To turn a list of records into a data frame, use dplyr::bind_rows or do.call(rbind, lapply(x, as.data.frame)). Here, x is the list you want to convert, such as holidays, releases or cpi. Select the response field first so that the conversion receives the records for that area.
The path and query arguments stay separate in these calls. For CPI, the path selects USA CPI observations and start supplies the starting period. For FX, the path selects USD and currencies supplies EUR and IDR. Both calls use the helper's base URL and bearer authentication.
Schedule a daily pull
Schedule Rscript pull.R once a day with cron or Windows Task Scheduler. The cronR package can write the cron line for you. Keep the requests you want in pull.R, with the helper and its environment-variable lookup, so the scheduled command calls the same script.
Rscript pull.RThe dates and currency choices remain the ones written in the script. For example, the release-date call asks for November 2026, and the holiday call asks for USA holidays in 2026. A daily schedule repeats those requests. See schedule a daily data pull for the scheduling path.
Holidays in R
Read USA holidays for 2026 from holidays. Each record has a date and name, so retain both fields when you turn the records into a data frame. This call uses the country and year in its path and reads the holiday list from the response.
response <- narwhal("v1/calendars/holidays/USA/2026")
holidays <- response$holidays
holidaysRelease dates in R
Read USA economic release dates for November 2026 from releases. The request includes the country, start date, end date and limit. Each release has at, period, topic and status; keep those fields together when you use the release records in R.
response <- narwhal("v1/economics/calendar", countries = "USA",
start_date = "2026-11-01", end_date = "2026-11-30", limit = 100)
releases <- response$releases
releasesEconomics in R
Read USA CPI observations with a start period of September 2025 from observations. Each observation has period and value. The helper example uses these values for a month-on-month calculation; keep the period alongside the value when you present an observation or a result from it.
response <- narwhal("v1/economics/USA/cpi/observations", start = "2025-09")
cpi <- response$observations
cpiCommodity spot prices in R
Read the Brent spot price in USD from price. This call selects the commodity and currency in the path, then converts the returned price with as.numeric(). Commodity spot codes include, for example, XAU, XAG, XPT, XPD, XCU, BRENT and WTI.
response <- narwhal("v1/commodities/spot/BRENT/USD")
brent <- as.numeric(response$price)
brentFX rates in R
Read exchange rates with USD as the base and EUR and IDR as the requested currencies. The response field is rates, and each record has currency and rate. Keep the currency field with its rate when you convert the list to a data frame.
response <- narwhal("v1/fx/rates/USD", currencies = "EUR,IDR")
fx <- response$rates
fxPrediction-market odds in R
Read the Federal Reserve policy-path response from meetings. Each meeting has resolves_at, p_cut, p_hold and p_hike. Keep the meeting fields together when you read the probabilities into R, with the resolution time alongside the cut, hold and hike fields.
response <- narwhal("v1/predictions/policy-paths/federal-reserve")
fed <- response$meetings
fedWhere do I put the key?
Put the key in .Renviron, never in the script. The helper reads Sys.getenv("NARWHAL_API_KEY") for bearer authentication. REST and MCP share that key, so you use the same account and key when accessing Narwhal through either path.
Why is price a string?
Decimals are returned as strings. Use as.numeric() to turn price into a number for R calculations, as the Brent example does. The CPI calculation also converts each observation's value before dividing the values to calculate the change.
Published .
