Determine the ISO codes for a location

The problem

You have geographic coordinates (longitude and latitude) or an address and you want to know the ISO 3166 codes that correspond with the location.

Overview

ISO 3166 (see Wikipedia entry) defines an international standard of codes for the countries/territories and their main subdivisions (states, provinces, etc). Because ISO codes are unambugious (unlike placenames, which vary depending on language) many systems use these codes as a way to refer to these locations particularly within databases.

There are three types of ISO 3166 codes:

  • ISO 3166-1 alpha-2 two-letter country codes, for example: DE for Germany.
  • ISO 3166-1 alpha-3 three-letter country code, for example DEU for Germany.
  • ISO 3166-2 country subdivision codes, for example DE-NI for the Bundesland (state) of Niedersachsen in Germany.

You can use the OpenCage geocoding API for forward (address to coordinates) or reverse (coordinates to address) geocoding. With each result we return the corresponding ISO 3166 codes for the location.

Background

When you send a request to the OpenCage geocoding API with each result we return various ISO codes (if possible, see the note below about locations that are not part of any country) various fields about the country of the result.

Specifically, within the components portion of each result we return
  • ISO_3166-1_alpha-3
    the ISO 3116-1 alpha-3 code for the territory. Example value: DEU
  • ISO_3166-1_alpha-2
    the ISO 3116-1 alpha-2 code for the territory. Example value: DE
  • ISO_3166-2
    a list of ISO 3116-2 codes for the territory. Example value: [ 'DE-NI' ]

    Please note:
    • Note that while most countries have only a single unique ISO 3166-2 value for each location, some countries have multiple levels. Examples include Great Britain, Spain, and France.

      For example a location in Barcelona, Spain returns [ 'ES-CT', 'ES-B' ].

      ES-CT is the code for the autonomous community (state) of Catalonia, ES-B is the code for the province (county) of Barcelona.
    • Not all countries have ISO 3116-2 codes.
    • In some countries some territories have ISO 3166-2 codes, while others do not. As an example, in Australia the Northern Territory has the code AU-NT, while the Jervis Bay Territory has no ISO 3166-2 code.
  • country_code
    a two-letter code for the country. Example value: de

You may ask why we return both the alpha-2 code and the country_code? For historical reasons many territories have their own ISO 3116-1 codes, despite legally being part of another country. An example is Puerto Rico which has alpha-2 code PR, despite being part of the United States US.

Disputed territories

Many areas of the world have disputed ownership or are claimed by more than one country. In this case our geocoding API returns whatever is in OpenStreetMap. You can see a list of disputed territories on the OpenStreetMap wiki. Our API returns whichever country OpenStreetMap deams to be valid.

It's worth noting that the process of assigning ISO codes is not particularly quick, it may be some time before a "new" country has an official ISO code. As an example, Kosovo, recognized as a sovereign state by a bit more than 50% of UN member states, does not yet have an official ISO code. In this case we return just a country_code.

Locations that belong to no country

Most of the world - the oceans and Antartica - does not belong to any country. For these locations our geocoding API will return neither a country value, nor ISO_3166-1_alpha-2, ISO_3166-1_alpha-3, or country_code values in the components portion of the API result.

Code Example

Here's a small example of making a reverse geocoding request to the OpenCage API in javascript to determine the ISO codes of the location.
We also have SDKs for over 30 other programming languages.

<script>
  var api_key = 'YOUR-API-KEY';
  var coords = '50.97755,11.32860';  // lat,lng

  var api_url = 'https://api.opencagedata.com/geocode/v1/json'

  var request_url = api_url
    + '?'
    + 'key=' + api_key
    + '&q=' + encodeURIComponent(coords)
    + '&pretty=1'
    + '&no_annotations=1';

  // see full list of required and optional parameters:
  // https://opencagedata.com/api#required-params

  var request = new XMLHttpRequest();
  request.open('GET', request_url, true);

  request.onload = function() {
      // see full list of possible response codes:
      // https://opencagedata.com/api#codes
      var data = JSON.parse(request.responseText);
      if (request.status === 200){  // Success!
          var iso_a2 = 'no country returned';
          if (data.results[0].components.ISO_3166-1_alpha-2 != null){
              iso_a2 = data.results[0].components.ISO_3166-1_alpha-2;
          }
          console.log('iso_alpha2: ' + iso_a2);
      } else {
          console.log("unable to geocode! Response code: " + request.status);
          console.log('error msg: ' + data.status.message);
      }
  };

  request.onerror = function() {
      // There was a connection error of some sort
      console.log("unable to connect to server");
  };
  request.send();  // make the request
</script>

Further Reading

Happy geocoding!

Start your free trial

2,500 geocoding API requests per day.

No credit card required.