Skip to content
Historical Gazetteers & Place Data

When GeoNames returns the wrong place for a historical name, the root cause is almost always that GeoNames is a modern gazetteer: it ranks by present-day population and administrative class and has no concept of period. The fix is to constrain every query with a country and feature-class filter, verify against a dated source, and fall back to Pleiades or the World Historical Gazetteer for pre-modern places. Below are the errors you will actually hit and how to clear them fast.

Why does GeoNames keep returning the wrong place? ​

GeoNames sorts candidates by modern relevance, so a search for Lincoln surfaces Lincoln, Nebraska before Lincoln, England if no country is set. It also lacks any historical layer — a deserted medieval village simply is not there. Treat GeoNames as a modern cross-check, never as the authority for historical location.

How do I fix rate-limit and quota errors? ​

The message the hourly limit has been exceeded or the daily limit has been exceeded means the throttle hit. Two fixes:

python
import requests

params = {"q": "Lincoln", "country": "GB",
          "featureClass": "P", "maxRows": 5,
          "username": "your_registered_user"}   # NOT 'demo'
r = requests.get("http://api.geonames.org/searchJSON", params=params)
print(r.json().get("status", "ok"))

Register a real username and enable web services in your account; the demo user is throttled within a handful of calls. For volume work, drop the API entirely and query a local dump.

How do I stop rivers and regions polluting results? ​

Filter on featureClass and featureCode. The class/code system is the single most effective control:

featureClassMeaningKeep for places?
PPopulated place (PPL, PPLA…)yes
AAdministrative regionusually no
HHydrography (rivers, lakes)no
LParks, areasno
SSpot, building, farmsometimes
TMountain, terrainno

Pass featureClass=P to cut the noise immediately, then refine by code.

Why are diacritics and casing wrong? ​

GeoNames separates the canonical name, an ASCII asciiname, and an alternatenames list. A failed match is usually an encoding or transliteration gap, not a missing record. Search alternate names and normalise on your side:

python
import unicodedata
def fold(s):
    return "".join(c for c in unicodedata.normalize("NFKD", s)
                   if not unicodedata.combining(c)).lower()
# compare fold("Köln") == fold("Koln")  -> True

How do I avoid rate limits entirely? ​

Download the bulk data and match locally — this is the right approach for any batch historical project:

bash
curl -O https://download.geonames.org/export/dump/GB.zip
unzip GB.zip          # yields GB.txt, tab-separated
# columns: geonameid, name, asciiname, alternatenames, lat, lng, fclass, fcode ...

Load GB.txt into pandas or SQLite, filter by feature code, and match offline. No quotas, full reproducibility, and you can pin a dated snapshot.

When should I not use GeoNames at all? ​

For ancient and medieval places, switch authorities. GeoNames coordinates are modern centroids and will silently misplace a Roman fort or a vanished hamlet. Use Pleiades for the ancient world and the World Historical Gazetteer for cross-period coverage, reserving GeoNames for modern names and sanity checks.

Key Takeaways ​

  • GeoNames ranks by modern relevance and has no historical layer — always constrain by country and feature class.
  • Register a real username and enable web services; the demo account hits quotas almost instantly.
  • Filter on featureClass P plus specific codes to remove rivers, regions and terrain.
  • Diacritic and casing mismatches are encoding issues — search alternate names and Unicode-fold.
  • For batch work, download the bulk dumps and match locally to escape rate limits entirely.
  • Do not trust GeoNames for pre-modern locations; use Pleiades or the World Historical Gazetteer.

Frequently Asked Questions ​

Why does GeoNames return the wrong place for a historical name? ​

GeoNames is a modern gazetteer keyed to present-day administrative geography, so it ranks by modern population and feature class. Add a country and feature-class filter, and verify against a period source, because it has no sense of historical context.

What does the 'the hourly limit has been exceeded' error mean? ​

Your application account has hit the free hourly or daily quota. Register a username, enable the free web services, and throttle requests; the demo account is throttled almost immediately.

How do I stop rivers and regions polluting my results? ​

Filter on featureClass and featureCode. Use P for populated places and codes like PPL or PPLA, and exclude H (water) and L (regions) unless you want them.

Does GeoNames have historical coordinates? ​

No. GeoNames coordinates are modern centroids. For anything before roughly 1500, prefer Pleiades or the World Historical Gazetteer and use GeoNames only as a fallback or for cross-checking.

Why are some of my matches missing diacritics or wrong-cased? ​

GeoNames stores ASCII and alternate-name variants separately. Search the alternateNames field and normalise encoding on your side; a mismatch is usually an encoding or transliteration issue, not a missing record.

Can I download GeoNames instead of using the API? ​

Yes. The full country dumps and allCountries.txt are free under CC-BY and avoid all rate limits. For batch historical work, local matching against the dump is far more reliable than the API.