#install.packages("devtools") library(devtools)Accessing IMF Data with imfidatar
This tutorial shows how to use the imfidatar package to access IMF’s iData platform. It simplifies SDMX queries, making authentication and data retrieval easier. Compared to older wrappers, it gives you more control while hiding the messy details.
We’ll cover installing it, finding datasets, building query keys, getting data (public and restricted), and handling labeled results.
Pre-requisites
You first need to the install the rsdmx package. You cannot install it the usual way. You need to install the latest version from Github. Before you can install it, you first need to load (or install) the devtools package.
You then can install the rsdmx package from Github. Please note the force=TRUE argument, which helps prevent installation problems.
install_github("opensdmx/rsdmx", force = TRUE)Installation and Setup
The imfidatar package is hosted on GitHub rather than CRAN, so you need to install it from source. You must also install the latest version of rsdmx (which handles low‑level SDMX requests).
# Install remotes only once
# install.packages("remotes")
library(remotes)
# Install rsdmx from GitHub using devtools
# install.packages("devtools")
devtools::install_github("opensdmx/rsdmx", force = TRUE)
# Option 1: install imfidatar directly from GitHub (requires Git installed and typically does not work on Fund machines)
remotes::install_git('https://github.com/BasBBakkerIMF/imfidatar.git')
# Option 2: download the imfidatar source tarball and install locally
url <- "https://codeload.github.com/BasBBakkerIMF/imfidatar/tar.gz/HEAD"
tf <- tempfile(fileext = ".tar.gz")
curl::curl_download(url, tf)
remotes::install_local(tf)The imfidatar package exports an object named idata with three main components:
- metadata – functions for exploring datasets and their dimensions;
- retrieval – functions to download data;
- utils – helper functions, such as for constructing keys.
# Load the package once installed
library(imfidatar)imfidatar loaded.
Exploring available datasets
Before querying data you often need to know which datasets are available. imfidatar provides a helper to list all public datasets exposed via the IMF’s SDMX API:
# Show publicly available datasets
datasets <- idata$metadata$imfdata_show_datasets()
head(datasets) id agencyID Name.en
1 MFS_IR IMF.STA Monetary and Financial Statistics (MFS), Interest Rate
2 WHDREO IMF.WHD Western Hemisphere Regional Economic Outlook (WHDREO)
3 QGFS IMF.STA Quarterly Government Finance Statistics (QGFS)
4 GFS_SSUC IMF.STA GFS Statement of Sources and Uses of Cash
5 SPE IMF.STA Special Purpose Entities (SPEs)
6 QNEA IMF.STA National Economic Accounts (NEA), Quarterly Data
version uri
1 8.0.1 <NA>
2 5.0.0 <NA>
3 12.0.0 <NA>
4 10.0.0 <NA>
5 13.0.0 <NA>
6 7.0.0 <NA>
urn
1 urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IMF.STA:MFS_IR(8.0.1)
2 urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IMF.WHD:WHDREO(5.0.0)
3 urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IMF.STA:QGFS(12.0.0)
4 urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IMF.STA:GFS_SSUC(10.0.0)
5 urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IMF.STA:SPE(13.0.0)
6 urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IMF.STA:QNEA(7.0.0)
isExternalReference isFinal validFrom validTo dsdRef Name.fr Name.ar Name.es
1 FALSE TRUE <NA> <NA> <NA> <NA> <NA> <NA>
2 FALSE TRUE <NA> <NA> <NA> <NA> <NA> <NA>
3 FALSE TRUE <NA> <NA> <NA> <NA> <NA> <NA>
4 FALSE TRUE <NA> <NA> <NA> <NA> <NA> <NA>
5 FALSE TRUE <NA> <NA> <NA> <NA> <NA> <NA>
6 FALSE TRUE <NA> <NA> <NA> <NA> <NA> <NA>
Name.pt Name.ja Name.zh Name.ru
1 <NA> <NA> <NA> <NA>
2 <NA> <NA> <NA> <NA>
3 <NA> <NA> <NA> <NA>
4 <NA> <NA> <NA> <NA>
5 <NA> <NA> <NA> <NA>
6 <NA> <NA> <NA> <NA>
# Show all datasets, including restricted ones (requires authentication)
datasets_auth <- idata$metadata$imfdata_show_datasets(needs_auth = T)Using authorization_code flow
Loading cached token
head(datasets_auth) id agencyID
1 GEE_LIVE_2024_OCT_FINAL_VINTAGE IMF.RES.GEE
2 DF_EAP_TEA1_SEX_AGE_NB ILO
3 WEO_LIVE_2013_OCT_ICP2011PPP_VINTAGE IMF.RES.WEO
4 WEO_LIVE_2012_OCT_VINTAGE IMF.RES.WEO
5 GEE_LIVE_2014_JAN_GAS1_VINTAGE IMF.RES.GEE
6 SPE IMF.STA
Name.en version
1 GEE Live 2024 October Final 1.0.0
2 Labour force by sex and age, seasonally adjusted series (Sub-annual) 1.0
3 WEO Live 2013 October (ICP2011PPP Weights) 1.0.0
4 WEO Live 2012 October 1.0.0
5 GEE Live 2014 January GAS1 1.0.0
6 Special Purpose Entities (SPEs) 13.0.0
uri
1 <NA>
2 <NA>
3 <NA>
4 <NA>
5 <NA>
6 <NA>
urn
1 urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IMF.RES.GEE:GEE_LIVE_2024_OCT_FINAL_VINTAGE(1.0.0)
2 urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=ILO:DF_EAP_TEA1_SEX_AGE_NB(1.0)
3 urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IMF.RES.WEO:WEO_LIVE_2013_OCT_ICP2011PPP_VINTAGE(1.0.0)
4 urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IMF.RES.WEO:WEO_LIVE_2012_OCT_VINTAGE(1.0.0)
5 urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IMF.RES.GEE:GEE_LIVE_2014_JAN_GAS1_VINTAGE(1.0.0)
6 urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IMF.STA:SPE(13.0.0)
isExternalReference isFinal validFrom validTo dsdRef
1 FALSE TRUE <NA> <NA> <NA>
2 FALSE TRUE <NA> <NA> <NA>
3 FALSE TRUE <NA> <NA> <NA>
4 FALSE TRUE <NA> <NA> <NA>
5 FALSE TRUE <NA> <NA> <NA>
6 FALSE TRUE <NA> <NA> <NA>
Name.fr
1 <NA>
2 Main-d'oeuvre par sexe et âge, series corrigées des variations saisonnières (Sub-annual)
3 <NA>
4 <NA>
5 <NA>
6 <NA>
Name.es
1 <NA>
2 Fuerza de trabajo según sexo y edad, series desestacionalizadas (Sub-annual)
3 <NA>
4 <NA>
5 <NA>
6 <NA>
Name.de Name.ar Name.pt Name.ja Name.zh Name.ru
1 <NA> <NA> <NA> <NA> <NA> <NA>
2 <NA> <NA> <NA> <NA> <NA> <NA>
3 <NA> <NA> <NA> <NA> <NA> <NA>
4 <NA> <NA> <NA> <NA> <NA> <NA>
5 <NA> <NA> <NA> <NA> <NA> <NA>
6 <NA> <NA> <NA> <NA> <NA> <NA>
The returned object is a data frame listing dataset identifiers. When you set needs_auth = TRUE, additional restricted datasets (those that require IMF credentials) will appear in the list. You will be prompted to log in when you first attempt to access those datasets.
Querying data by key
The core function for data retrieval is idata$retrieval$imfdata_by_key(). You must specify the dataset and a key that filters your request across different dimensions (e.g., countries, indicators, frequencies). The key can be provided either as a string (using + and . separators) or as a list. The following example pulls unemployment rates (LUR) and consumer prices (PCPI) from the World Economic Outlook (WEO) database for the United States and the Netherlands:
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
weodata <- idata$retrieval$imfdata_by_key(
dataset = "IMF.RES:WEO",
key = "USA+NLD.LUR+PCPI.A" # Countries (USA, NLD), indicators (LUR, PCPI), annual frequency
)[rsdmx][INFO] Fetching 'https://api.imf.org/external/sdmx/2.1/data/IMF.RES,WEO/USA+NLD.LUR+PCPI.A/all/'
# Select a few columns and inspect the tail of the data
weodata %>%
select(COUNTRY, INDICATOR, TIME_PERIOD, value) %>%
tail() COUNTRY INDICATOR TIME_PERIOD value
199 USA PCPI 2025 322.214
200 USA PCPI 2026 330.060
201 USA PCPI 2027 337.271
202 USA PCPI 2028 344.711
203 USA PCPI 2029 352.305
204 USA PCPI 2030 360.023
Notice that dataset uses the prefix IMF.RES to indicate the department (Research, RES) combined with the dataset code (WEO). The key string is composed of dimensions separated by periods: countries (USA+NLD), indicators (LUR+PCPI), and frequency (A for annual).
Building a key programmatically
Constructing keys manually can be error‑prone, especially for datasets with many dimensions. The metadata component helps you discover dimension names and their valid values, and the utils component helps assemble a key in list form.
Retrieve dimension names
To see which dimensions a dataset exposes, call get_dimension_names() on its code:
# Get dimension names for the WEO dataset
dims <- idata$metadata$get_dimension_names("IMF.RES:WEO")[rsdmx][INFO] Fetching 'https://api.imf.org/external/sdmx/2.1/datastructure/all/DSD_WEO/latest/?references=descendants'
Dimension
1 COUNTRY
2 INDICATOR
3 FREQ
print(dims) Dimension
1 COUNTRY
2 INDICATOR
3 FREQ
For WEO you will typically see COUNTRY, INDICATOR, and FREQ. More complex datasets have additional dimensions.
Explore dimension values
Use make_dimension_env() to create an environment containing all possible values for a given dimension. You can then reference values by their descriptive names. For example:
# Get environments for dimensions
countries <- idata$metadata$make_dimension_env("IMF.RES:WEO", "COUNTRY")
indicators <- idata$metadata$make_dimension_env("IMF.RES:WEO", "INDICATOR")
frequencies <- idata$metadata$make_dimension_env("IMF.RES:WEO", "FREQ")
# Inspect codes for specific labels
countries$`United States` # Country code for the United States[1] "USA"
indicators$`Unemployment rate` # Code for the unemployment rate series[1] "LUR"
frequencies$Annual # Code for annual frequency[1] "A"
Assemble and convert keys
After identifying the appropriate codes, you can assemble them into a list. Each element of the list should itself be a list when you have multiple selections for a given dimension. You can then convert that list into a key string using make_key_str(), though passing the list directly to imfdata_by_key() also works.
# Assemble key components
mycountries <- list(countries$`Netherlands, The`, countries$`United States`)
myindicators <- list(
indicators$`Unemployment rate`,
indicators$`Gross domestic product (GDP), Constant prices, Domestic currency`
)
myfrequencies <- list(frequencies$Annual)
# Combine into a key list
mykey <- list(mycountries, myindicators, myfrequencies)
# Optional: build a key string from the list
mykeystr <- idata$utils$make_key_str(mykey)
print(mykeystr)[1] "NLD+USA.LUR+NGDP_R.A"
# Fetch data using the list key
weo_data <- idata$retrieval$imfdata_by_key(
dataset = "IMF.RES:WEO",
key = mykey
)[rsdmx][INFO] Fetching 'https://api.imf.org/external/sdmx/2.1/data/IMF.RES,WEO/NLD+USA.LUR+NGDP_R.A/all/'
weo_data %>%
select(COUNTRY, INDICATOR, TIME_PERIOD, value) %>%
tail() COUNTRY INDICATOR TIME_PERIOD value
199 USA NGDP_R 2025 2.382945e+13
200 USA NGDP_R 2026 2.433036e+13
201 USA NGDP_R 2027 2.483038e+13
202 USA NGDP_R 2028 2.534996e+13
203 USA NGDP_R 2029 2.582669e+13
204 USA NGDP_R 2030 2.627947e+13
Using this approach ensures that your keys reflect valid codes and reduces the risk of misspelling a dimension value.
Accessing restricted data
Some datasets require authentication. When you attempt to access them, imfidatar uses your IMF login through Azure to request a token. To discover restricted datasets and their dimensions, first create a dataset environment with needs_auth = TRUE:
# Create an environment of all datasets (requires login)
mydatasets <- idata$metadata$make_dataset_env(needs_auth = TRUE)
# Select a specific dataset, e.g., the Bloomberg Data License
bloomberg <- mydatasets$`Bloomberg Data License `
# Check its dimensions
dims <- idata$metadata$get_dimension_names(bloomberg)[rsdmx][INFO] Fetching 'https://api.imf.org/external/sdmx/2.1/datastructure/all/DSD_BBGDL/latest/?references=descendants'
Dimension
1 TICKER
2 MARKET_FIELD
3 FREQ
print(dims) Dimension
1 TICKER
2 MARKET_FIELD
3 FREQ
# Build dimension environments
tickers <- idata$metadata$make_dimension_env(dataset_or_db = bloomberg, dimension = "TICKER")
fields <- idata$metadata$make_dimension_env(dataset_or_db = bloomberg, dimension = "MARKET_FIELD")
freqs <- idata$metadata$make_dimension_env(dataset_or_db = bloomberg, dimension = "FREQ")
# Assemble a key for the Bloomberg dataset
bb_key <- list(
c(tickers$`ALBANIAN LEK SPOT`),
c(fields$`Ask Price`, fields$`Bid Price`),
c(freqs$Daily)
)
# Fetch the data (requires authentication)
bb_data <- idata$retrieval$imfdata_by_key(
dataset = bloomberg,
needs_auth = TRUE,
key = bb_key,
needs_labels = FALSE
)[rsdmx][INFO] Fetching 'https://api.imf.org/external/sdmx/2.1/data/IMF.CSF,BBGDL/ALL_CURNCY.PX_ASK+PX_BID.D/all/'
tail(bb_data) TICKER FIELD FREQUENCY SCALE TIME_PERIOD OBS_VALUE value
14546 ALL_CURNCY PX_BID D 0 2026-02-17 80.76 80.76
14547 ALL_CURNCY PX_BID D 0 2026-02-18 81.34 81.34
14548 ALL_CURNCY PX_BID D 0 2026-02-19 81.5 81.50
14549 ALL_CURNCY PX_BID D 0 2026-02-20 81.4 81.40
14550 ALL_CURNCY PX_BID D 0 2026-02-23 81.26 81.26
14551 ALL_CURNCY PX_BID D 0 2026-02-24 81.34 81.34
If you are not already logged in, a browser window will open prompting you to enter your IMF credentials. Once authenticated, your token will be cached for subsequent requests.
Retrieving labelled data
For human‑readable outputs, set needs_labels = TRUE. This instructs imfidatar to include descriptive labels for each dimension in the returned data frame. The following example pulls balance of payments data (BOP) for several Central American countries and selects both the code and English label for the indicator:
library(dplyr)
keystr <- "CRI+HND+GTM+NIC+PAN+DOM+SLV.CD_T.S+SA+SB+SC+SD+SE+SF+SG+SH+SI+SJ+SK+SL.USD.A"
df <- idata$retrieval$imfdata_by_key(
dataset = "IMF.STA:BOP",
needs_auth = FALSE,
key = keystr,
needs_labels = TRUE
)[rsdmx][INFO] Fetching 'https://api.imf.org/external/sdmx/2.1/data/IMF.STA,BOP/CRI+HND+GTM+NIC+PAN+DOM+SLV.CD_T.S+SA+SB+SC+SD+SE+SF+SG+SH+SI+SJ+SK+SL.USD.A/all/'
[rsdmx][INFO] Attempt to fetch DSD ref from dataflow description
[rsdmx][INFO] Fetching 'https://api.imf.org/external/sdmx/2.1/dataflow/all/IMF.STA,BOP/latest/'
[rsdmx][INFO] Fetching 'https://api.imf.org/external/sdmx/2.1/datastructure/all/DSD_BOP/latest/?references=descendants'
[rsdmx][INFO] DSD fetched and associated to dataset!
# Select columns with labels
df2 <- df %>%
select(COUNTRY, INDICATOR, INDICATOR_label.en.label, TIME_PERIOD, value)
tail(df2) COUNTRY INDICATOR INDICATOR_label.en.label TIME_PERIOD
3508 SLV SL Government goods and services n.i.e. 2019
3509 SLV SL Government goods and services n.i.e. 2020
3510 SLV SL Government goods and services n.i.e. 2021
3511 SLV SL Government goods and services n.i.e. 2022
3512 SLV SL Government goods and services n.i.e. 2023
3513 SLV SL Government goods and services n.i.e. 2024
value
3508 109168831
3509 104664550
3510 128046584
3511 173681317
3512 167231356
3513 159268868
The resulting df2 includes an additional column INDICATOR_label.en.label containing an English description of each indicator. Similar language codes (e.g., .fr.label) are available for other languages.
Troubleshooting common errors
If you run into errors with imfdata_by_key(), like wrong dataset names or bad keys, check your spelling and make sure all dimensions are correct. If data is missing columns, verify your key has valid codes.
imfidatar offers a flexible and powerful way to interact with IMF data via SDMX. By exploring metadata programmatically and constructing keys carefully, you can assemble complex queries without having to build URLs by hand.