Geocoding Scraper — Address ↔ Coordinates (OpenStreetMap) avatar

Geocoding Scraper — Address ↔ Coordinates (OpenStreetMap)

Pricing

from $0.70 / 1,000 result items

Go to Apify Store
Geocoding Scraper — Address ↔ Coordinates (OpenStreetMap)

Geocoding Scraper — Address ↔ Coordinates (OpenStreetMap)

Free geocoding for agents and CRMs via OpenStreetMap: address or place → lat/lon with full address breakdown, structured queries (street/city/postcode), reverse geocoding with zoom levels, OSM id lookup, bounded POI search, boundary polygons, multilingual names. Nominatim or Photon (fuzzy).

Pricing

from $0.70 / 1,000 result items

Rating

0.0

(0)

Developer

Samat Makatov

Samat Makatov

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

15 hours ago

Last modified

Share

Geocoding Scraper — address ↔ coordinates, POI search, boundaries (OpenStreetMap)

Free, key-less geocoding on OpenStreetMap data for agents, CRMs and data pipelines. Forward (address or place → lat/lon + full address breakdown), structured queries (street/city/postcode fields for messy CRM data), reverse (lat,lon → address at the zoom level you need), OSM id lookup, bounded POI search inside a box, boundary polygons as GeoJSON and names in any language. Two engines: Nominatim (exact, rich) and Photon (typo-tolerant). Worldwide, no API key, no proxy.

Use cases

  • CRM address cleaning — geocode 500 customer addresses with structuredQueries, keep found, lat/lon, normalized postcode/city; with emitNotFound: true rows stay 1:1 with input.
  • Store / branch enrichmentreverseZoom: 10 turns delivery GPS points into city names for territory reports.
  • Local lead listsqueries: ["pharmacy"] + viewbox + bounded: true lists every mapped pharmacy in a district with street and house number; extraTags adds opening hours and websites where mapped.
  • Service-area mapspolygon: true gives district/city boundaries as GeoJSON for coverage checks.
  • Multilingual labelslang: "ru" or nameDetails: true for Cyrillic / Kazakh / local names on the same object.
  • Dedupe & entity resolution — stable osmType+osmId, placeRank, importance and bestMatch to pick the right candidate among ambiguous names.

Input

FieldTypeDefaultNotes
queriesstring[]Text address/place → forward; lat,lon → reverse; R62422 / N1,W2 → lookup.
structuredQueriesobject[]{ amenity, street, city, county, state, country, postalcode, label } (Nominatim).
modeselectautoauto, forward, reverse, lookup.
engineselectnominatimnominatim or photon (structured & lookup always use Nominatim).
langstringenAccept-Language, e.g. ru, kk, de, ru,en. Photon: en/de/fr only.
countryCodesstringkz,ru — ISO-3166 alpha-2, comma-separated.
viewboxstringminLon,minLat,maxLon,maxLat, e.g. Almaty 76.75,43.15,77.10,43.40.
boundedboolfalseOnly results inside viewbox (enables area POI search).
featureTypeselectcountry, state, city, settlement.
layersmultiaddress, poi, railway, natural, manmade.
limitint1Results per query; Nominatim max 40, Photon max 50.
reverseZoomint1818 building · 17 street · 16 major street · 14 suburb · 12 town · 10 city · 8 county · 5 state · 3 country.
addressDetailsbooltrueaddress object + derived columns.
extraTagsboolfalseextraTags: website, opening_hours, wikidata, population…
nameDetailsboolfalsenameDetails: name:ru, name:kk, official_name
polygonboolfalsegeojson outline.
polygonThresholdnumber0Simplification tolerance in degrees (0.005 ≈ city level).
dedupebooltrueNominatim result dedupe.
emitNotFoundboolfalseEmit found: false rows to keep 1:1 alignment. Such rows are charged like hits, so this is opt-in; not-found queries are always listed free in SUMMARY.notFoundInputs.
outputFieldsstring[]Projection, e.g. ["query","lat","lon","countryCode"].
maxItemsint10000Hard cap.
osmTagstringPhoton: amenity:cafe, shop, !amenity:parking.
photonLayersmultiPhoton: house, street, locality, district, city, county, state, country, other.
biasLat, biasLonnumberPhoton: prefer results near this point.

Reference

Nominatim vs Photon

NominatimPhoton
Matchingexact tokens, structured fieldsfuzzy / prefix (typos OK)
Address breakdownfull (address object, 20+ keys)street, housenumber, district, city, state, postcode, country
Reverseyes, zoom-controlledyes (nearest object)
OSM id lookup, polygons, extra tags, name detailsyesno
Languageany (accept-language)en / de / fr
POI filterlayers, featureType, bounded boxosm_tag, layer, bbox, location bias
Policy1 request/s, identify app (the actor does both)fair use

reverseZoom levels

zoomreturns
3country
5state
8county
10city
12town / borough
13village / suburb
14neighbourhood
16major streets
17major and minor streets
18building

Common type / category values

boundary/administrative (countries, regions, cities, districts) · place/city|town|village|suburb|neighbourhood · highway/residential|primary|… (streets) · building/yes|office|apartments|… · amenity/pharmacy|cafe|bank|school|… · shop/* · tourism/* · office/*. Full tag catalogue: https://wiki.openstreetmap.org/wiki/Map_features

Examples

Batch-geocode CRM addresses (1:1 rows)

{
"structuredQueries": [
{ "street": "Nauryzbai Batyr 154A", "city": "Almaty", "country": "Kazakhstan", "label": "Kaspi HQ" },
{ "street": "Mangilik El 55", "city": "Astana", "country": "Kazakhstan", "label": "Client 2" }
],
"lang": "ru",
"emitNotFound": true,
"outputFields": ["query", "found", "lat", "lon", "displayName", "postcode", "city", "osmUrl"]
}

All pharmacies in a district (POI lead list)

{ "queries": ["pharmacy"], "viewbox": "76.85,43.20,77.00,43.30", "bounded": true, "limit": 40, "extraTags": true, "lang": "ru" }

GPS points → city names for reporting

{ "queries": ["43.2363,76.9457", "51.1282,71.4307", "42.3417,69.5901"], "reverseZoom": 10, "outputFields": ["query", "city", "state", "countryCode"] }

City boundaries as GeoJSON

{ "queries": ["Almaty", "Astana"], "featureType": "city", "countryCodes": "kz", "polygon": true, "polygonThreshold": 0.005 }

Fuzzy search of user-typed input (Photon)

{ "queries": ["Almty Nauryzbai Batyr 154"], "engine": "photon", "limit": 3, "biasLat": 43.24, "biasLon": 76.95 }

Output

{
"query": "Nauryzbai Batyr 154A, Almaty",
"mode": "forward",
"engine": "nominatim",
"rank": 1,
"bestMatch": true,
"found": true,
"placeId": 213728564,
"osmType": "way",
"osmId": 51267846,
"osmUrl": "https://www.openstreetmap.org/way/51267846",
"displayName": "Kaspi.kz, 154А, Nauryzbai Batyr Street, Керемет, Көктем, Bostandıq District, Almaty, 050013, Kazakhstan",
"name": "Kaspi.kz",
"lat": 43.2399856,
"lon": 76.9388247,
"category": "building",
"type": "office",
"addressType": "building",
"placeRank": 30,
"importance": 0.0000743,
"boundingBox": [43.2398836, 43.2400877, 76.9383802, 76.9392699],
"country": "Kazakhstan",
"countryCode": "KZ",
"state": null,
"county": null,
"city": "Almaty",
"district": "Bostandıq District",
"suburb": "Көктем",
"postcode": "050013",
"road": "Nauryzbai Batyr Street",
"houseNumber": "154А",
"address": { "building": "Kaspi.kz", "house_number": "154А", "road": "Nauryzbai Batyr Street", "city": "Almaty", "ISO3166-2-lvl4": "KZ-75", "postcode": "050013", "country": "Kazakhstan", "country_code": "kz" },
"extraTags": { "building:levels": "7" },
"nameDetails": null,
"geojson": null,
"licence": "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
"sourceUrl": "https://nominatim.openstreetmap.org/search?q=…",
"fetchedAt": "2026-09-12T23:50:01.000Z"
}
FieldDescription
query, mode, engineInput label (or structured label), detected mode, engine used.
rank, bestMatch, found1-based rank; rank 1 is bestMatch; found: false rows carry nulls.
placeId, osmType, osmId, osmUrlStable OSM identity (use osmType+osmId as key; placeId changes between Nominatim imports).
displayName, nameFull label and object name.
lat, lon, boundingBoxWGS84; bbox as [minLat, maxLat, minLon, maxLon] (Nominatim order).
category, type, addressType, placeRank, importanceOSM class/type, address level, 0–1 relevance.
countryhouseNumberNormalized address columns; raw parts in address.
extraTags, nameDetails, geojsonOnly when requested.
structuredEcho of the structured query object (structured rows only).

SUMMARY key-value record: { queries, found, notFound, rows, errors[{query, error}], engine, errorCount, notFoundCount, notFoundInputs[], notFoundRowsEmitted }.

Use it from code / agents

curl -X POST "https://api.apify.com/v2/acts/yadroo~osm-geocode/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H 'Content-Type: application/json' -d '{"queries":["Almaty, Kazakhstan","43.2363,76.9457"],"lang":"ru"}'
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('yadroo/osm-geocode').call({ structuredQueries: [{ street: 'Nauryzbai Batyr 154A', city: 'Almaty', country: 'Kazakhstan' }] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("yadroo/osm-geocode").call(run_input={"queries": ["pharmacy"], "viewbox": "76.85,43.20,77.00,43.30", "bounded": True, "limit": 40})
items = client.dataset(run["defaultDatasetId"]).list_items().items

MCP: connect https://mcp.apify.com and call the yadroo/osm-geocode tool with the same JSON.

Pricing

Pay per event: $0.001 per run start + $0.001 per result row (not-found rows are included only when you turn emitNotFound on; failed queries are never charged). 100 addresses at limit: 1 ≈ $0.10; a bounded POI search returning 40 rows ≈ $0.041.

Limits & FAQ

  • Speed. Nominatim's usage policy allows 1 request per second; the actor enforces a 1.1 s gap, so 300 queries ≈ 5.5 minutes. Split big batches into parallel runs of ≤ 500 queries.
  • Accuracy. OSM coverage varies: exact house numbers exist for most cities in Europe/CIS/US; rural addresses may resolve to the street or village (check addressType/placeRank).
  • Ambiguity. Use countryCodes, viewbox, featureType or structuredQueries; inspect importance and rank when limit > 1.
  • Errors. HTTP 429/5xx → 3 retries with backoff; a failing query is listed in SUMMARY.errors (no row, not charged) and the run continues. Nothing fetched at all → run fails with the reason.
  • Licence. Data © OpenStreetMap contributors, ODbL — attribution required when you display it; Nominatim results may not be used for autocomplete-as-you-type (use Photon for that).
  • Roadmap. Batch mode with your own Nominatim/Photon endpoint, distance/nearest computation between rows.

Made by Yadroo · Sibling actors: open-meteo-weather · ip-intel · public-holidays · krisha-kz