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.

#install.packages("devtools") library(devtools)

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
1                GFS_SSUC  IMF.STA
2                  FSICDM  IMF.STA
3                    QNEA  IMF.STA
4     PI_2026_JAN_VINTAGE  IMF.STA
5                     FDI  IMF.MCM
6 MFS_MA_2026_JAN_VINTAGE  IMF.STA
                                                                        Name.en
1                                     GFS Statement of Sources and Uses of Cash
2 Financial Soundness Indicators (FSI), Concentration and Distribution Measures
3                              National Economic Accounts (NEA), Quarterly Data
4                                          Production Indexes (PI) 2026 January
5                                             Financial Development Index (FDI)
6    Monetary and Financial Statistics (MFS), Monetary Aggregates 2026 January 
  version  uri
1  10.0.0 <NA>
2   7.0.0 <NA>
3   7.0.0 <NA>
4   1.0.0 <NA>
5   1.0.0 <NA>
6   1.0.0 <NA>
                                                                                        urn
1               urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IMF.STA:GFS_SSUC(10.0.0)
2                  urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IMF.STA:FSICDM(7.0.0)
3                    urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IMF.STA:QNEA(7.0.0)
4     urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IMF.STA:PI_2026_JAN_VINTAGE(1.0.0)
5                     urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IMF.MCM:FDI(1.0.0)
6 urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IMF.STA:MFS_MA_2026_JAN_VINTAGE(1.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
Server did not provide a refresh token: you will have to reauthenticate to refresh.
Add the 'offline_access' scope to obtain a refresh token.
head(datasets_auth)
                               id    agencyID
1         PI_WCA_2026_MAY_VINTAGE     IMF.STA
2                           COFER     IMF.STA
3  GAS_LIVE_2021_OCT_GAS2_VINTAGE IMF.RES.GAS
4 GAS_LIVE_2022_OCT_FINAL_VINTAGE IMF.RES.GAS
5       WEO_LIVE_2018_OCT_VINTAGE IMF.RES.WEO
6  GEE_LIVE_2016_JAN_GAS1_VINTAGE IMF.RES.GEE
                                                             Name.en version
1    Production Indexes, World and Country Group Aggregates 2026 May   1.0.0
2 Currency Composition of Official Foreign Exchange Reserves (COFER)   7.0.1
3                                         GAS Live 2021 October GAS2   1.0.0
4                                        GAS Live 2022 October Final   1.0.0
5                                              WEO Live 2018 October   1.0.0
6                                         GEE Live 2016 January GAS1   1.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.STA:PI_WCA_2026_MAY_VINTAGE(1.0.0)
2                               urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IMF.STA:COFER(7.0.1)
3  urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IMF.RES.GAS:GAS_LIVE_2021_OCT_GAS2_VINTAGE(1.0.0)
4 urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IMF.RES.GAS:GAS_LIVE_2022_OCT_FINAL_VINTAGE(1.0.0)
5       urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IMF.RES.WEO:WEO_LIVE_2018_OCT_VINTAGE(1.0.0)
6  urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IMF.RES.GEE:GEE_LIVE_2016_JAN_GAS1_VINTAGE(1.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 Composition monétaire des réserves officielles de change (COFER)
3                                                             <NA>
4                                                             <NA>
5                                                             <NA>
6                                                             <NA>
                                      Name.ar
1                                        <NA>
2 تكوين عملات احتياطيات النقد الأجنبي الرسمية
3                                        <NA>
4                                        <NA>
5                                        <NA>
6                                        <NA>
                                           Name.es
1                                             <NA>
2 Composición de las reservas oficiales de divisas
3                                             <NA>
4                                             <NA>
5                                             <NA>
6                                             <NA>
                                                      Name.pt
1                                                        <NA>
2 Composição por moeda das reservas cambiais oficiais (COFER)
3                                                        <NA>
4                                                        <NA>
5                                                        <NA>
6                                                        <NA>
                            Name.ja                         Name.zh
1                              <NA>                            <NA>
2 公的外貨準備の通貨別構成(COFER) 官方外汇储备的货币构成(COFER)
3                              <NA>                            <NA>
4                              <NA>                            <NA>
5                              <NA>                            <NA>
6                              <NA>                            <NA>
                                                   Name.ru Name.de
1                                                     <NA>    <NA>
2 Валютная структура официальных валютных резервов (ВСОВР)    <NA>
3                                                     <NA>    <NA>
4                                                     <NA>    <NA>
5                                                     <NA>    <NA>
6                                                     <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
203     USA      PCPI        2026 332.6629
204     USA      PCPI        2027 339.7862
205     USA      PCPI        2028 347.2060
206     USA      PCPI        2029 354.8027
207     USA      PCPI        2030 362.5722
208     USA      PCPI        2031 370.4915

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
203     USA    NGDP_R        2026 2.440727e+13
204     USA    NGDP_R        2027 2.491982e+13
205     USA    NGDP_R        2028 2.544314e+13
206     USA    NGDP_R        2029 2.592162e+13
207     USA    NGDP_R        2030 2.637606e+13
208     USA    NGDP_R        2031 2.683896e+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
14814 ALL_CURNCY PX_BID         D     0  2026-08-25     78.71 78.71
14815 ALL_CURNCY PX_BID         D     0  2026-08-26      78.8 78.80
14816 ALL_CURNCY PX_BID         D     0  2026-08-27     78.81 78.81
14817 ALL_CURNCY PX_BID         D     0  2026-08-28     79.19 79.19
14818 ALL_CURNCY PX_BID         D     0  2026-08-31     78.94 78.94
14819 ALL_CURNCY PX_BID         D     0  2026-09-01     79.25 79.25

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
3587     SLV        SL Government goods and services n.i.e.        2020
3588     SLV        SL Government goods and services n.i.e.        2021
3589     SLV        SL Government goods and services n.i.e.        2022
3590     SLV        SL Government goods and services n.i.e.        2023
3591     SLV        SL Government goods and services n.i.e.        2024
3592     SLV        SL Government goods and services n.i.e.        2025
         value
3587 104664550
3588 128046584
3589 173681317
3590 167231356
3591 159741166
3592 138979902

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.