How to use the IMF API with Python

This guide is designed to walk you through the process of retrieving datasets from the International Monetary Fund (IMF) API using Python. Prerequisites for this tutorial include a working installation of Python as well as the following libraries:

import requests
import json
import pandas as pd

Please note, in the subsequent steps, Python’s type notations will be used. The notation str | None stands for string values that might be absent (nullable) and str for values that are always present (non-nullable).

Indicators

The indicators endpoint allows access to a variety of economic measures. You can fetch the available indicators from the URL https://www.imf.org/external/datamapper/api/v1/indicators.

Here is how to fetch the data from the endpoint and create a Pandas Data Frame from it:

def get_imf_indicators():
    response = requests.get(
        url="https://www.imf.org/external/datamapper/api/v1/indicators"
    )
    response_body = json.loads(response.text)
    indicators = [
        {"id": key, **values} for key, values in response_body["indicators"].items()
    ]
    indicators_df = pd.DataFrame.from_records(indicators)
    return indicators_df

This is what the schema of the resulting Data Frame looks like:

ColumnTypeDescriptionExample
idstrThe indicator’s unique IDNGDP_RPCH
labelstr | NoneThe nameReal GDP growth
descriptionstr | NoneA short explanation of the indicatorGross domestic product is the most commonly us…
sourcestr | NoneThe dataset’s original sourceWorld Economic Outlook (April 2023)
unitstr | NoneThe datapoints’ unit of measurementAnnual percent change
datasetstr | NoneAn identifier for the indicator’s source.WEO

Countries, Geographical Regions, and Analytical Groups

The IMF API classifies its data into countries, geographical regions, and analytical groups. The URLs to access them follow the following pattern https://www.imf.org/external/datamapper/api/v1/<groups | regions | countries>.

Here is a function to fetch the group you need. The group_type can be either 'groups' for analytical groups, 'regions' or 'countries'.

def get_imf_groups(group_type: str):
    response = requests.get(
        url=f"https://www.imf.org/external/datamapper/api/v1/{group_type}"
    )
    response_body = json.loads(response.text)
    results = [
        {"id": key, **values} for key, values in response_body[group_type].items()
    ]
    df = pd.DataFrame.from_records(results)
    return df

This is what the schema of the resulting Data Frame looks like:

ColumnTypeDescriptionExample
idstrThe group’s unique IDFRA
labelstr | NoneThe nameFrance

Indicator Data

You can retrieving specific indicator data from https://www.imf.org/external/datamapper/api/v1/<indicator_id>. You need to specify an indicator’s id to fetch a given dataset.

Here's a function to fetch the data from the endpoint and create a Pandas Data Frame from it. The indicator_id is the one we can find in the indicators dataset and the group_ids we can find in the group’s dataset.

def get_imf_indicator_data(
    indicator_id: str, group_ids: list[str] = [], years: list[str] = []
):
    indicator_url = "https://www.imf.org/external/datamapper/api/v1"
    groups_url_path = "/".join(group_ids)
    years_query_param = "?periods=" + ",".join(years)

    response = requests.get(
        url=f"{indicator_url}/{indicator_id}/{groups_url_path}{years_query_param}"
    )
    response_body = json.loads(response.text)
    response_values = response_body.get("values")

    if not response_values:
        return pd.DataFrame()

    indicator_df = pd.DataFrame.from_records(
        response_body["values"][indicator_id]
    ).sort_index()

    return indicator_df

The resulting Data Frame schema is dynamic:

Limiting the request to certain groups and years is optional. By not specifying any you can request the complete dataset. If you specify groups and/or years not existing in the requested indicator the resulting Data Frame will be empty.

Be aware that the indicators often only include a subset of the available countries, geographical regions and analytical groups.

You can request data using all three different groups in the same request, for example data from the US (country), as well as Central America (geographical region).

Putting it into Practice

Here an example for how to fetch the indicator “GDP, current prices” ('NGDPD') for the United States ('USA') and France ('FRA') for the years 2022 and 2023:

# 1st step: fetch indicator codes
indicators = get_imf_indicators()

# 2nd step: fetch country codes
countries = get_imf_groups('countries')

# Find the entry for 'GDP, current prices'
indicator = indicators.loc[indicators.label == 'GDP, current prices'].iloc[0]

# Find the entries for the United States and France
selected_countries = countries.loc[countries.label.isin(['United States', 'France'])]

# 3rd step: fetch indicator data
indicator_data = get_imf_indicator_data(indicator.id, selected_countries.id, ['2022', '2023'])

indicator_data

If you run the code in a notebook it will return the following Data Frame:

USAFRA
202225464.4752784.020
202326854.5992923.489