countries.dev API
A free, no-auth REST API for country, city, postal-code, and IP-geolocation
data. Base URL: https://countries.dev
- No API key, no signup, no documented rate limits. Just send GET requests.
- All responses are JSON (errors like "Country not found" come back as plain text with a 404 status — always check the HTTP status code).
- CORS is enabled, so it works from browsers as well as
curl/server code. - Data sources: country data plus GeoNames (~34k cities, ~12M places, ~1.8M postal codes across ~121 countries).
Quick start
# One country by ISO code (alpha-2 or alpha-3, case-insensitive)
curl https://countries.dev/alpha/JP
# Search by name (substring match, returns an array)
curl "https://countries.dev/name/japan?fields=name,capital,population"
# All countries, top 10 by population
curl "https://countries.dev/countries?fields=name,population&sort=population&order=desc&limit=10"
# Find a city and its coordinates
curl "https://countries.dev/cities?q=taipei&limit=5"
# Geolocate an IP
curl https://countries.dev/ip/8.8.8.8
Choosing the right endpoint
| You need... | Use |
|---|---|
| One country, and you have its ISO code | /alpha/{code} (most reliable — prefer this) |
| One country by name | /name/{name} (substring match — may return several; pick the best match) |
| Lists filtered by region/currency/language/etc. | /region/…, /currency/…, /lang/…, etc. |
| Countries in a population or area range | /population?min=&max=, /area?min=&max= |
| A country's neighbours (full records) | /borders/{country name} — takes a name like germany, NOT an ISO code |
| City search / coordinates | /cities?q=… (ranked by population) |
| Any geographic feature (mountains, rivers…) | /places?q=…&class=… |
| Nearest city/place to coordinates | /cities/near?lat=&lng=, /places/near?lat=&lng= |
| ZIP/postal code → place + coordinates | /postal/{alpha2}/{code} |
| IP → country | /ip (caller), /ip/{ip}, or POST /ip for batches |
| Distance between two points | /distance?lat1=&lng1=&lat2=&lng2= or ?from=&to= (GeoNames IDs, not names) |
For the complete endpoint list, every query parameter, response schemas, and verified examples, read references/endpoints.md.
Key conventions (learned from live testing — trust these)
- Single-lookup endpoints return an object; search/filter endpoints return
an array — even when only one item matches.
/alpha/JP→ object;/name/japan→[ {...} ]. - Use
fields=aggressively. Full country records are large. Request only what you need:?fields=name,capital,population. Use?fields=fullto get everything includingaltSpellings,maps,translations, andregionalBlocs(these four are omitted by default). - List endpoints support
sort,order(asc/desc),limit,offsetfor sorting and pagination. - Name search is substring-based:
/name/unitedreturns every country containing "united". Don't assume the first result is the intended one — match on thenamefield or fall back to/alpha/{code}when you know the code. /borderstakes a country name (/borders/germanyworks;/borders/DEand/borders/DEUreturn 404 "Country not found"). To get just neighbour codes, read thebordersarray (alpha-3 codes) from the country record instead./distancedoes not accept city names or country codes — onlylat1/lng1/lat2/lng2coordinates or GeoNames IDs viafrom/to. To get the distance between two named cities, first resolve each via/cities?q=nameto get itsgeonameId, then call/distance?from=ID&to=ID.- URL-encode special characters: timezone lookups need the
+encoded, e.g./timezone/UTC%2B08:00. - Flags: the
flagfield is an emoji (🇹🇼); image URLs live inflags.png/flags.svg(hosted on flagcdn.com).
