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.