Countries APIREST APITutorial

Countries REST API: Get Country Data, Flags, Currencies, and More

ApogeoAPI5 min read

The countries endpoint

ApogeoAPI provides a countries endpoint that returns structured data for all ~250 countries and territories:

# Single country by ISO 2 code
GET https://api.apogeoapi.com/v1/countries/DE?apikey=YOUR_KEY

# All countries
GET https://api.apogeoapi.com/v1/countries?apikey=YOUR_KEY

# Search by name
GET https://api.apogeoapi.com/v1/countries?search=germany&apikey=YOUR_KEY

Country object fields

{
  "iso2": "DE",
  "iso3": "DEU",
  "commonName": "Germany",
  "officialName": "Federal Republic of Germany",
  "nativeName": "Deutschland",
  "capital": "Berlin",
  "region": "Europe",
  "subregion": "Western Europe",
  "continentCode": "EU",
  "flagUrl": "https://flagcdn.com/de.svg",
  "flagEmoji": "๐Ÿ‡ฉ๐Ÿ‡ช",
  "dialCode": "+49",
  "currencyCode": "EUR",
  "currencyName": "Euro",
  "currencySymbol": "โ‚ฌ",
  "languages": ["German"],
  "population": 83200000,
  "area": 357114,
  "timezones": ["Europe/Berlin"],
  "tld": ".de",
  "callingCode": "49",
  "independent": true,
  "unMember": true
}

JavaScript examples

Get a single country

async function getCountry(iso2) {
  const res = await fetch(
    `https://api.apogeoapi.com/v1/countries/${iso2}?apikey=${process.env.APOGEO_KEY}`
  );
  return res.json();
}

const germany = await getCountry('DE');
console.log(germany.nativeName);    // "Deutschland"
console.log(germany.currencyCode);  // "EUR"
console.log(germany.flagUrl);       // "https://flagcdn.com/de.svg"
console.log(germany.dialCode);      // "+49"

Get all countries โ€” build a selector

interface Country {
  iso2: string;
  commonName: string;
  flagUrl: string;
  dialCode: string;
  currencyCode: string;
  currencySymbol: string;
}

// Cache the full list โ€” it changes rarely
let countriesCache: Country[] | null = null;

async function getAllCountries(): Promise<Country[]> {
  if (countriesCache) return countriesCache;

  const res = await fetch(
    `https://api.apogeoapi.com/v1/countries?apikey=${process.env.NEXT_PUBLIC_APOGEO_KEY}`
  );
  const data = await res.json();
  countriesCache = data;
  return data;
}

// React phone number selector with dial codes
import { useEffect, useState } from 'react';

export function PhoneInput() {
  const [countries, setCountries] = useState<Country[]>([]);
  const [selectedDial, setSelectedDial] = useState('+1');
  const [phone, setPhone] = useState('');

  useEffect(() => {
    getAllCountries().then(setCountries);
  }, []);

  return (
    <div className="flex gap-2">
      <select
        value={selectedDial}
        onChange={e => setSelectedDial(e.target.value)}
        className="border rounded px-2 py-1 w-28"
      >
        {countries.map(c => (
          <option key={c.iso2} value={c.dialCode}>
            {c.iso2} {c.dialCode}
          </option>
        ))}
      </select>
      <input
        type="tel"
        value={phone}
        onChange={e => setPhone(e.target.value)}
        placeholder="Phone number"
        className="border rounded px-3 py-1 flex-1"
      />
    </div>
  );
}

Search countries

async function searchCountries(query: string): Promise<Country[]> {
  const res = await fetch(
    `https://api.apogeoapi.com/v1/countries?search=${encodeURIComponent(query)}&apikey=${APOGEO_KEY}`
  );
  return res.json();
}

const results = await searchCountries('ger');
// Returns: Germany, Niger, Algeria, ...
results.forEach(c => console.log(c.commonName, c.iso2));

Get all currencies from countries

async function getUniqueCurrencies() {
  const countries = await getAllCountries();

  const currencies = new Map<string, { name: string; symbol: string; countries: string[] }>();

  for (const country of countries) {
    if (!currencies.has(country.currencyCode)) {
      currencies.set(country.currencyCode, {
        name: country.currencyName ?? country.currencyCode,
        symbol: country.currencySymbol ?? country.currencyCode,
        countries: [],
      });
    }
    currencies.get(country.currencyCode)!.countries.push(country.iso2);
  }

  return Object.fromEntries(currencies);
}

// Result:
// { "USD": { name: "US Dollar", symbol: "$", countries: ["US", "EC", "SV", ...] },
//   "EUR": { name: "Euro", symbol: "โ‚ฌ", countries: ["DE", "FR", "IT", ...] }, ... }

Python example

import requests
import json

APOGEO_KEY = "your_api_key"

def get_country(iso2: str) -> dict:
    r = requests.get(
        f"https://api.apogeoapi.com/v1/countries/{iso2}",
        params={"apikey": APOGEO_KEY},
        timeout=3,
    )
    r.raise_for_status()
    return r.json()

def get_all_countries() -> list:
    r = requests.get(
        "https://api.apogeoapi.com/v1/countries",
        params={"apikey": APOGEO_KEY},
        timeout=5,
    )
    r.raise_for_status()
    return r.json()

# Usage
de = get_country("DE")
print(f"Capital: {de['capital']}")          # Berlin
print(f"Currency: {de['currencyCode']}")    # EUR
print(f"Languages: {de['languages']}")      # ['German']
print(f"Population: {de['population']:,}")  # 83,200,000

Caching recommendations

  • Single country: Cache for 24 hours in Redis or in-memory Map
  • All countries list: Cache for 24+ hours โ€” country data changes rarely
  • Browser: Store in localStorage with a 24h expiry key
  • CDN edge: Add Cache-Control: public, max-age=86400 to your API proxy route

vs. RestCountries

RestCountries is free and open source but has been unreliable (multiple domain changes, API breakage). ApogeoAPI's countries endpoint provides the same data with a stable, paid SLA โ€” plus IP geolocation and exchange rates in the same API key. Full comparison โ†’

Full docs: api.apogeoapi.com/api/docs. Get a free key: app.apogeoapi.com/register.

Try ApogeoAPI free

1,000 requests/month forever. 14-day full-access trial. No credit card.

Get your free API key