Skip to content
GuidesBlogPlaygroundDashboard

Migrating from Nominatim

Upgrade from Nominatim to Plaza for faster geocoding, structured responses, and additional APIs.

Plaza includes the same OpenStreetMap data as Nominatim — plus curated open datasets, custom data support, and a full suite of geospatial APIs beyond geocoding.

NominatimPlaza
Rate limit1 req/sec (absolute)10–10,000 req/min depending on plan
Response formatCustom JSON/XMLGeoJSON
Data sourceOpenStreetMapOpenStreetMap + curated datasets + custom data
Reverse geocodingYesYes
AutocompleteNoYes
Batch geocodingNoYes
RoutingNoYes
Feature searchNoYes
AuthNone (IP-based rate limit)API key
Nominatim endpointNominatim pathPlaza endpoint
Search/search?q=POST /geocode with {"q": "..."}
Reverse/reverse?lat=&lon=POST /geocode/reverse with {"geometry": {"type": "Point", ...}}
Lookup/lookup?osm_ids=GET /features/:type/:id

All Plaza endpoints are under https://plaza.fyi/api/v1.

Nominatim rate-limits by IP with no auth. Plaza uses an API key:

Terminal window
curl -H "x-api-key: pk_live_abc123" \
"https://plaza.fyi/api/v1/geocode?q=Berlin"

Sign up at plaza.fyi for a free key. No credit card required.

[
{
"place_id": 279641937,
"licence": "Data © OpenStreetMap contributors, ODbL 1.0.",
"osm_type": "relation",
"osm_id": 62422,
"lat": "52.5170365",
"lon": "13.3888599",
"display_name": "Berlin, Germany",
"class": "boundary",
"type": "administrative",
"importance": 0.8544,
"address": {
"city": "Berlin",
"state": "Berlin",
"ISO3166-2-lvl4": "DE-BE",
"country": "Germany",
"country_code": "de"
},
"boundingbox": ["52.338", "52.675", "13.089", "13.761"]
}
]
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [13.3889, 52.5170]
},
"properties": {
"osm_id": 62422,
"osm_type": "relation",
"name": "Berlin",
"city": "Berlin",
"state": "Berlin",
"country": "Germany",
"country_code": "de",
"confidence": 0.98
}
}
]
}

Key differences:

  • GeoJSON standard. No more parsing lat/lon strings into numbers.
  • Coordinates in the geometry, not separate top-level fields.
  • No display_name. Address components are structured properties.
  • No licence field per response. The data is still open (ODbL) — see Plaza’s attribution docs.
Nominatim parameterPlaza parameterNotes
qqSame
limitlimitSame (Plaza max: 1,000)
countrycodescountry_codeSingle country, not comma-separated
viewboxwithinGeoJSON Polygon geometry
bounded=1Use withinPlaza always bounds when within is set
accept-languagelangBCP 47 tag
formatAlways GeoJSON
addressdetails=1Always included
extratags=1Always included
Nominatim parameterPlaza parameterNotes
latlatSame
lonlngNote: lng, not lon
zoomNot needed. Plaza returns the most specific match.
import httpx
import time
def geocode_nominatim(query):
time.sleep(1) # Required: 1 req/sec limit
response = httpx.get(
"https://nominatim.openstreetmap.org/search",
params={
"q": query,
"format": "jsonv2",
"limit": 5,
"addressdetails": 1,
},
headers={"User-Agent": "MyApp/1.0"},
)
results = response.json()
for r in results:
print(f"{r['display_name']}: {r['lat']}, {r['lon']}")
import plaza
client = plaza.Client()
def geocode_plaza(query):
results = client.v1.geocode.forward(q=query, limit=5)
for f in results.features:
coords = f.geometry.coordinates
print(f"{f.properties['name']}: {coords[1]}, {coords[0]}")

No sleep. No user-agent requirement. No parsing lat/lon strings.

# Nominatim: 100 addresses = 100 seconds minimum
for address in addresses:
geocode_nominatim(address)
time.sleep(1)

Plaza supports batch geocoding in a single request:

results = client.v1.geocode.batch(addresses=[
"1600 Pennsylvania Ave NW, Washington DC",
"10 Downing Street, London",
"Élysée Palace, Paris",
])
# Returns a list of FeatureCollections, one per address

Routing. Turn-by-turn directions with distance and duration.

route = client.v1.route(
origin={"type": "Point", "coordinates": [13.388, 52.517]},
destination={"type": "Point", "coordinates": [13.397, 52.529]},
mode="bicycle",
)

Isochrones. “Everywhere reachable within 10 minutes on foot.”

iso = client.v1.isochrone(
location={"type": "Point", "coordinates": [13.388, 52.517]},
mode="foot",
time="300,600,900",
)

Feature search. Find features by tag, bounding box, or proximity — not just addresses.

cafes = client.v1.features.nearby(
location={"type": "Point", "coordinates": [13.388, 52.517]},
radius=500,
tags={"amenity": "cafe"},
)

Distance matrix. Calculate travel times between multiple origins and destinations.

matrix = client.v1.matrix(
origins=[
{"type": "Point", "coordinates": [13.388, 52.517]},
{"type": "Point", "coordinates": [13.405, 52.520]},
],
destinations=[
{"type": "Point", "coordinates": [13.397, 52.529]},
{"type": "Point", "coordinates": [13.412, 52.523]},
],
mode="auto",
)

PlazaQL. Plaza’s purpose-built query language for geospatial data — expressive, type-safe, and without public server limits.

Nominatim: 1 req/sec (60/min). Plaza’s free tier: 10 req/min with instant upgrades:

PlanRequests/minMonthly includedPrice
Free10500 std/day + 10 prm/day$0
Pro 100K300100,000$50/mo
Pro 300K1,000300,000$150/mo
Pro 1M2,0001,000,000$500/mo

Self-hosting Nominatim requires 64GB+ RAM and 1TB+ SSD for the full planet. Plaza eliminates that infrastructure.