Cover image

Using IMF's Data Services API

A quick guide to using IMF's Data Services API

I recently worked on a project that requires the use of IMF's Data Services. Although the data is very good, the documentation for the API is a bit lacking.1 When asked, IMF staff points to this tutorial, which goes into details on how to use the API using Python. I thought it would be useful to have a more conceptual explanation of how the API works, so here it is.

Find your Dataflow

IMF's Data Services has a number of "dataflows" available. These are simply IMF's lingo for "databases". Examples are:

To get the list of available dataflows, make a request to the URL below:

http://dataservices.imf.org/REST/SDMX_JSON.svc/Dataflow
http://dataservices.imf.org/REST/SDMX_JSON.svc/Dataflow
Note

For the remainder of this article, we'll replace the first part of the URL

http://dataservices.imf.org/REST/SDMX_JSON.svc
http://dataservices.imf.org/REST/SDMX_JSON.svc

with .... So the above URL becomes .../Dataflow.

Let's say we're looking for data on international reserves. We can simply find the key word and we'll have the following:

{
  "@id": "DS-IRFCL",
  "@version": "1.0",
  "@agencyID": "IMF",
  "@isFinal": "true",
  "@xmlns": "http://www.SDMX.org/resources/SDMXML/schemas/v2_0/structure",
  "Name": {
    "@xml:lang": "en",
    "#text": "International Reserves and Foreign Currency Liquidity (IRFCL)"
  },
  "KeyFamilyRef": {
    "KeyFamilyID": "IRFCL",
    "KeyFamilyAgencyID": "IMF"
  }
},
{
  "@id": "DS-IRFCL",
  "@version": "1.0",
  "@agencyID": "IMF",
  "@isFinal": "true",
  "@xmlns": "http://www.SDMX.org/resources/SDMXML/schemas/v2_0/structure",
  "Name": {
    "@xml:lang": "en",
    "#text": "International Reserves and Foreign Currency Liquidity (IRFCL)"
  },
  "KeyFamilyRef": {
    "KeyFamilyID": "IRFCL",
    "KeyFamilyAgencyID": "IMF"
  }
},

Note the KeyFamilyID field (IRFCL in this case). This is the database ID we're looking for.

Find your Dimensions

Once you have the dataflow ID, you can find out more about the data structure by looking at .../DataStructure/IRFCL. More specifically, what we need are the dimensions of the dataset. Take a look in Structure > KeyFamilies > KeyFamily > Components > Dimension and we'll see something like this

[
  {
    "@conceptRef": "FREQ",
    "@conceptVersion": "1.0",
    "@conceptSchemeRef": "IRFCL",
    "@conceptSchemeAgency": "IMF",
    "@codelist": "CL_FREQ",
    "@codelistVersion": "1.0",
    "@codelistAgency": "IMF",
    "@isFrequencyDimension": "true"
  },
  {
    "@conceptRef": "REF_AREA",
    "@conceptVersion": "1.0",
    "@conceptSchemeRef": "IRFCL",
    "@conceptSchemeAgency": "IMF",
    "@codelist": "CL_AREA_IRFCL",
    "@codelistVersion": "1.0",
    "@codelistAgency": "IMF"
  },
  {
    "@conceptRef": "INDICATOR",
    "@conceptVersion": "1.0",
    "@conceptSchemeRef": "IRFCL",
    "@conceptSchemeAgency": "IMF",
    "@codelist": "CL_INDICATOR_IRFCL",
    "@codelistVersion": "1.0",
    "@codelistAgency": "IMF"
  },
  {
    "@conceptRef": "REF_SECTOR",
    "@conceptVersion": "1.0",
    "@conceptSchemeRef": "IRFCL",
    "@conceptSchemeAgency": "IMF",
    "@codelist": "CL_SECTOR_IRFCL",
    "@codelistVersion": "1.0",
    "@codelistAgency": "IMF"
  }
]
[
  {
    "@conceptRef": "FREQ",
    "@conceptVersion": "1.0",
    "@conceptSchemeRef": "IRFCL",
    "@conceptSchemeAgency": "IMF",
    "@codelist": "CL_FREQ",
    "@codelistVersion": "1.0",
    "@codelistAgency": "IMF",
    "@isFrequencyDimension": "true"
  },
  {
    "@conceptRef": "REF_AREA",
    "@conceptVersion": "1.0",
    "@conceptSchemeRef": "IRFCL",
    "@conceptSchemeAgency": "IMF",
    "@codelist": "CL_AREA_IRFCL",
    "@codelistVersion": "1.0",
    "@codelistAgency": "IMF"
  },
  {
    "@conceptRef": "INDICATOR",
    "@conceptVersion": "1.0",
    "@conceptSchemeRef": "IRFCL",
    "@conceptSchemeAgency": "IMF",
    "@codelist": "CL_INDICATOR_IRFCL",
    "@codelistVersion": "1.0",
    "@codelistAgency": "IMF"
  },
  {
    "@conceptRef": "REF_SECTOR",
    "@conceptVersion": "1.0",
    "@conceptSchemeRef": "IRFCL",
    "@conceptSchemeAgency": "IMF",
    "@codelist": "CL_SECTOR_IRFCL",
    "@codelistVersion": "1.0",
    "@codelistAgency": "IMF"
  }
]

This tells us that this dataset has four dimensions:

  1. FREQ
  2. REF_AREA
  3. INDICATOR
  4. REF_SECTOR

Find your CodeList

For each of these dimensions (aside from FREQ), you can find which values are available by looking at the corresponding codelist at .../CodeList/[@codelist]. For example, you can view which indicators are in this dataset by going to .../CodeList/CL_INDICATOR_IRFCL. The applicable values could be found under Structure > CodeLists > CodeList > Code.

[
  {
    "@value": "IARO_BP6_EUR",
    "Description": {
      "@xml:lang": "en",
      "#text": "Assets, Reserve assets, Other reserve assets, Euro"
    }
  },
  {
    "@value": "IARO_BP6_XDC",
    "Description": {
      "@xml:lang": "en",
      "#text": "Assets, Reserve assets, Other reserve assets, National Currency"
    }
  },
  {
    "@value": "IARO_BP6_USD",
    "Description": {
      "@xml:lang": "en",
      "#text": "Assets, Reserve assets, Other reserve assets, US Dollars"
    }
  },
  // ...
]
[
  {
    "@value": "IARO_BP6_EUR",
    "Description": {
      "@xml:lang": "en",
      "#text": "Assets, Reserve assets, Other reserve assets, Euro"
    }
  },
  {
    "@value": "IARO_BP6_XDC",
    "Description": {
      "@xml:lang": "en",
      "#text": "Assets, Reserve assets, Other reserve assets, National Currency"
    }
  },
  {
    "@value": "IARO_BP6_USD",
    "Description": {
      "@xml:lang": "en",
      "#text": "Assets, Reserve assets, Other reserve assets, US Dollars"
    }
  },
  // ...
]

Get your data

Now that we know the dimensions and the possible values for each dimension, we can finally get the data. IMF's Data Services has a method called CompactData. Here's a template:

.../CompactData/[@dataflow]/[@dimension1].[@dimension2].….[@dimensionN]
.../CompactData/[@dataflow]/[@dimension1].[@dimension2].….[@dimensionN]

For the last part, we need to put in a code for each dimension, separated by a dot (.). The order of the dimension has to follow the dimensions found earlier.

Basic usage

For the most basic usage (although not the most common one), specify one item per dimension. For example, to get a monthly data on foreign exchange reserves for Thailand whose source is the monetary authority, use the following link:

.../CompactData/IRFCL/M.TH.RAFA_USD.S1X
                      ^ ^  ^        ^
    Dimension         1 2  3        4
.../CompactData/IRFCL/M.TH.RAFA_USD.S1X
                      ^ ^  ^        ^
    Dimension         1 2  3        4

More than one item in a dimension

To add more than one code in a dimension, use the plus sign (+) to separate each item within a dimension. For example, to get the aforementioned data for both Thailand and Malaysia, use the following link:

.../CompactData/IRFCL/M.TH+MY.RAFA_USD.S1X
                          ———
.../CompactData/IRFCL/M.TH+MY.RAFA_USD.S1X
                          ———

All items in the dimension

To include all codes in that dimension, don't put anything in that dimension. For example, to get the data for all countries, use the following link:

.../CompactData/IRFCL/M..RAFA_USD.S1X
                       ——
.../CompactData/IRFCL/M..RAFA_USD.S1X
                       ——
Note

We still need to put the dot (.) to indicate that we're skipping that dimension.

If the dimension you want to exclude is at the end, you can omit the last dot. In other words, .../CompactData/IRFCL/M.TH.RAFA_USD is equivalent to .../CompactData/IRFCL/M.TH.RAFA_USD..

You can, of course, combine these strategies. For example, to get annual data for all countries for two indicators, you use the following URL:

.../CompactData/IRFCL/M..RAFA_USD+RAFAGOLD_USD
.../CompactData/IRFCL/M..RAFA_USD+RAFAGOLD_USD

Specifying start and end periods

If we're only interested in data for a certain period, we can specify the start and end periods using the startPeriod and endPeriod parameters. (We can also specify only one of them.) These can be in the form of YYYY or YYYY-MM. For example, to get the data for Thailand from July 2010 to 2012, use the following link:

.../CompactData/IRFCL/M.TH.RAFA_USD?startPeriod=2010-07&endPeriod=2012
                                   ———————————————————————————————————
.../CompactData/IRFCL/M.TH.RAFA_USD?startPeriod=2010-07&endPeriod=2012
                                   ———————————————————————————————————

Limitations

IMF's Data Services has a rate limit of

  • 10 requests in 5 second window from one user (IP)
  • 50 requests per second overall on the application.

The request should also not return more than 3000 series. (This limit could be found by the GetMaxSeriesInResult method.)

Wrapping up

That's it! This should cover all the basics of using IMF's Data Services. There are more methods available to get things like metadata, but I'll leave that for some other time.

Footnotes

  1. There's another, perhaps more useful, article here which was not linked from the main page.