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
localStoragewith a 24h expiry key - CDN edge: Add
Cache-Control: public, max-age=86400to 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