OTHER

OpenStreetMap POI Search

Search for points of interest near any location using OpenStreetMap data via the Overpass API. Find restaurants, cafes, hotels, shops, museums, and more. Returns names, addresses, contact details, opening hours, and distance from search center.

2
Users (30d)
85
Runs (30d)
87
Well maintained
Maintenance Pulse
Free
Per event

Maintenance Pulse

87/100
Last Build
2d ago
Last Version
8d ago
Builds (30d)
5
Issue Response
N/A

Documentation

Search and extract points of interest (POIs) near any location worldwide using OpenStreetMap data via the Overpass API. Find restaurants, cafes, banks, pharmacies, hotels, museums, and more within a configurable radius. Returns structured data with addresses, phone numbers, websites, opening hours, and Haversine distance calculations -- no API key required.


Overview

OpenStreetMap POI Search queries the Overpass API to find nearby points of interest around any geographic coordinate. Choose from 13 built-in categories or supply your own custom OSM tag to search for virtually any type of location. Each result includes structured address data, contact information, accessibility details, and an accurate Haversine distance calculation from your search center. Key capabilities:

  • 13 built-in POI categories -- restaurants, cafes, bars, banks, pharmacies, hospitals, schools, gas stations, supermarkets, hotels, museums, libraries, and parking
  • Custom OSM tag support -- search for any OpenStreetMap tag (e.g., shop=bicycle, tourism=attraction, leisure=playground) for unlimited POI types
  • Radius-based search -- configurable from 100 to 10,000 meters around any latitude/longitude coordinate
  • Haversine distance sorting -- results sorted by precise great-circle distance from your search center
  • Rich structured output -- 18 fields per result including full address, phone, website, email, opening hours, cuisine, brand, wheelchair access, and complete OSM tags
  • No API key required -- uses the free and open Overpass API endpoint
  • Automatic retry logic -- handles rate limits (429) and server errors (504, 5xx) with exponential backoff
  • Up to 500 results per search

Input Parameters

ParameterTypeRequiredDefaultDescription
latitudeNumberYes51.5074Search center latitude coordinate
longitudeNumberYes-0.1278Search center longitude coordinate
radiusMetersIntegerNo1000Search radius in meters (100--10,000)
categoryStringNorestaurantPOI category to search for (see list below)
customTagStringNo--Custom OSM tag override in key=value format
maxResultsIntegerNo50Maximum results to return (1--500)

Built-in Categories

The category field accepts any of these 13 values plus a catch-all option:

CategoryOSM TagDescription
restaurantamenity=restaurantRestaurants and dining establishments
cafeamenity=cafeCoffee shops and cafes
baramenity=barBars and pubs
bankamenity=bankBanks and financial institutions
pharmacyamenity=pharmacyPharmacies and drugstores
hospitalamenity=hospitalHospitals and medical facilities
schoolamenity=schoolSchools and educational institutions
fuelamenity=fuelGas stations and fuel stops
supermarketshop=supermarketSupermarkets and grocery stores
hoteltourism=hotelHotels and accommodation
museumtourism=museumMuseums and exhibitions
libraryamenity=libraryPublic and private libraries
parkingamenity=parkingParking lots and garages
anyamenity=*All amenities within radius

Custom Tag Override

The customTag field lets you search for any POI type in the OpenStreetMap database by specifying a raw OSM tag in key=value format. When provided, it overrides the category selection entirely.

Examples: shop=bicycle, tourism=attraction, leisure=playground, shop=bakery, amenity=charging_station, amenity=post_office, shop=electronics, leisure=fitness_centre, amenity=dentist, amenity=veterinary.

Refer to the OpenStreetMap Map Features wiki for the complete list of available tags.


Output Format

Each result in the output dataset contains the following 18 fields:

FieldTypeDescription
osmIdNumberUnique OpenStreetMap element ID
osmTypeStringOSM element type (node or way)
nameStringName of the point of interest
latitudeNumberPOI latitude coordinate
longitudeNumberPOI longitude coordinate
categoryStringPOI category from amenity, shop, tourism, leisure, or office tags
addressObjectStructured address with street, houseNumber, city, postcode, country
phoneStringPhone number (from phone or contact:phone tags)
websiteStringWebsite URL (from website or contact:website tags)
emailStringEmail address (from email or contact:email tags)
openingHoursStringOpening hours in OSM format
wheelchairStringWheelchair accessibility status
cuisineStringCuisine type (for food-related POIs)
operatorStringOperating company or organization
brandStringBrand name
osmUrlStringDirect link to the element on openstreetmap.org
tagsObjectComplete set of raw OSM tags for the element
distanceMetersNumberHaversine distance in meters from search center
extractedAtStringISO 8601 timestamp of extraction

TypeScript Schema

{
    osmId: number,               // OpenStreetMap element ID
    osmType: string,             // "node" or "way"
    name: string | null,         // POI name
    latitude: number,            // POI latitude
    longitude: number,           // POI longitude
    category: string | null,     // Detected category tag value
    address: { street, houseNumber, city, postcode, country },
    phone: string | null,        // From phone or contact:phone
    website: string | null,      // From website or contact:website
    email: string | null,        // From email or contact:email
    openingHours: string | null, // OSM opening_hours format
    wheelchair: string | null,   // Accessibility status
    cuisine: string | null,      // Cuisine type
    operator: string | null,     // Operating organization
    brand: string | null,        // Brand name
    osmUrl: string,              // Link to openstreetmap.org
    tags: object,                // All raw OSM tags
    distanceMeters: number,      // Haversine distance from center
    extractedAt: string          // ISO 8601 timestamp
}

Example Output

{
    "osmId": 1234567890,
    "osmType": "node",
    "name": "The Wolseley",
    "latitude": 51.5076,
    "longitude": -0.1388,
    "category": "restaurant",
    "address": {
        "street": "Piccadilly",
        "houseNumber": "160",
        "city": "London",
        "postcode": "W1J 9EB",
        "country": "GB"
    },
    "phone": "+44 20 7499 6996",
    "website": "https://www.thewolseley.com",
    "email": null,
    "openingHours": "Mo-Fr 07:00-23:00; Sa 08:00-23:00; Su 08:00-22:00",
    "wheelchair": "yes",
    "cuisine": "european",
    "operator": null,
    "brand": null,
    "osmUrl": "https://www.openstreetmap.org/node/1234567890",
    "tags": { "amenity": "restaurant", "name": "The Wolseley", "cuisine": "european", "..." : "..." },
    "distanceMeters": 245,
    "extractedAt": "2026-02-21T14:30:00.000Z"
}

How It Works

  1. Query construction -- Builds an Overpass QL query searching both node and way elements matching the selected category or custom tag within the radius.
  2. Overpass API request -- Sends a POST request to https://overpass-api.de/api/interpreter with a 60-second timeout. Retries automatically on HTTP 429, 504, and 5xx with exponential backoff (10s, 20s, 30s).
  3. Coordinate extraction -- Reads lat/lon directly from node elements. For way elements, uses the center point via the out center body directive.
  4. Data transformation -- Normalizes each element into structured output. Contact info is extracted from both direct tags (phone, website, email) and namespaced tags (contact:phone, contact:website, contact:email).
  5. Distance calculation -- Haversine formula computes great-circle distance in meters from your search center. Results are sorted closest-first.
  6. Output limiting -- Caps results at maxResults (default 50, max 500) and pushes to the Apify dataset.

Use Cases

  • Local business discovery -- Find restaurants, cafes, or shops near any address for market research, competitive analysis, or location-based directories.
  • Real estate analysis -- Evaluate neighborhood amenities around a property by searching for schools, hospitals, supermarkets, and banks.
  • Travel planning -- Discover hotels, museums, tourist attractions, and dining options around your destination.
  • Accessibility auditing -- Identify wheelchair-accessible establishments using the wheelchair field in the output.
  • Fleet and logistics -- Map gas stations, parking lots, and EV charging stations along routes or within service areas.
  • Academic research -- Extract geographic data about urban infrastructure and commercial density for spatial analysis.
  • Lead generation -- Collect business contact info (phone, website, email) for local businesses, then enrich with additional tools.

API Usage

Apify API -- Start a Run

curl -X POST "https://api.apify.com/v2/acts/L6wZxGXkk0tE6QnZg/runs?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "latitude": 48.8566,
    "longitude": 2.3522,
    "radiusMeters": 2000,
    "category": "museum",
    "maxResults": 100
  }'

Apify API -- Get Dataset Items

After the run completes, retrieve results from the default dataset:

curl "https://api.apify.com/v2/acts/L6wZxGXkk0tE6QnZg/runs/last/dataset/items?token=YOUR_API_TOKEN"

Integrations

Python

from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")

run_input = {
    "latitude": 40.7128,
    "longitude": -74.0060,
    "radiusMeters": 1500,
    "category": "cafe",
    "maxResults": 50,
}

run = client.actor("L6wZxGXkk0tE6QnZg").call(run_input=run_input)

dataset_items = client.dataset(run["defaultDatasetId"]).list_items().items

for poi in dataset_items:
    print(f"{poi['name']} -- {poi['distanceMeters']}m -- {poi.get('phone', 'N/A')}")

JavaScript / Node.js

import { ApifyClient } from "apify-client";

const client = new ApifyClient({ token: "YOUR_API_TOKEN" });

const run = await client.actor("L6wZxGXkk0tE6QnZg").call({
    latitude: 35.6762,
    longitude: 139.6503,
    radiusMeters: 3000,
    category: "hotel",
    maxResults: 100,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();

items.forEach((poi) => {
    console.log(`${poi.name} -- ${poi.distanceMeters}m -- ${poi.website || "N/A"}`);
});

Advanced Examples

Search with Custom OSM Tag

Find all bicycle shops within 5 km of Amsterdam city center:

{
    "latitude": 52.3676,
    "longitude": 4.9041,
    "radiusMeters": 5000,
    "category": "restaurant",
    "customTag": "shop=bicycle",
    "maxResults": 200
}

When customTag is provided, it completely overrides the category field. The query will search for shop=bicycle regardless of what category is set to.

Search for EV Charging Stations

Find electric vehicle charging stations near downtown San Francisco:

{
    "latitude": 37.7749,
    "longitude": -122.4194,
    "radiusMeters": 3000,
    "customTag": "amenity=charging_station",
    "maxResults": 100
}

Search All Amenities

Use the any category to find every type of amenity within the radius:

{
    "latitude": 51.5074,
    "longitude": -0.1278,
    "radiusMeters": 500,
    "category": "any",
    "maxResults": 500
}

Find Pharmacies Near a Hospital

Search for pharmacies within walking distance of a specific hospital location:

{
    "latitude": 48.8396,
    "longitude": 2.3443,
    "radiusMeters": 800,
    "category": "pharmacy",
    "maxResults": 20
}

Performance and Limits

ParameterValue
Maximum search radius10,000 meters (10 km)
Minimum search radius100 meters
Maximum results per run500
Default results per run50
Overpass API query timeout60 seconds
Retry attempts on error3 (with 10s, 20s, 30s backoff)
Retryable HTTP status codes429, 504, 5xx
Element types queriednode and way
Coordinate source for waysCenter point via out center body
Distance calculation methodHaversine formula (great-circle distance)

Tips for Best Results

  • Start with a moderate radius (1,000--2,000m) and increase if needed. Large radii in dense areas may hit the 500-result cap.
  • Use specific categories over any when possible -- the any category can be noisy in busy areas.
  • Custom tags unlock the full OSM database -- check the OSM Map Features wiki for thousands of tag combinations.
  • Data quality varies by region -- urban areas in Europe and North America have the most complete data.
  • Avoid rapid concurrent searches -- the Overpass API is shared; the actor retries automatically on rate limits.

Overpass QL Query Reference

The actor generates Overpass QL queries in this format:

[out:json][timeout:60];
(
  node["amenity"="restaurant"](around:1000,51.5074,-0.1278);
  way["amenity"="restaurant"](around:1000,51.5074,-0.1278);
);
out center body;

This queries both nodes (single-point features) and ways (area features) matching the tag within the radius. The out center body directive ensures way elements return center coordinates with all tags. For custom tags, the tag filter adapts (e.g., ["shop"="bicycle"] instead of ["amenity"="restaurant"]).


Frequently Asked Questions

Do I need an API key? No. The Overpass API is free and open. No API keys or accounts are needed beyond your Apify account.

How accurate is the distance calculation? The Haversine formula computes great-circle distances accurate to within a few meters for typical POI search ranges.

Why are some POIs missing contact information? OpenStreetMap is community-maintained. Data completeness varies by region -- urban areas tend to have more complete records. The actor returns null for any missing fields.

Can I search for POI types not in the 13 built-in categories? Yes. Use customTag with any valid OSM tag in key=value format. See the OSM Map Features wiki for thousands of available tags.

What happens if the Overpass API is overloaded? The actor retries up to 3 times with exponential backoff (10s, 20s, 30s) on HTTP 429, 504, or 5xx errors.

Why did my search return zero results? No matching POIs exist within the radius. Try increasing radiusMeters, changing the category, or verifying your coordinates.

What is the maximum search area? 10,000 meters (10 km) radius. For larger areas, run multiple searches with different center coordinates.

How much does a run cost? Approximately $0.001 to $0.005 per run. Most searches complete in 5 to 15 seconds using minimal compute. No external paid API costs.


Related Actors

ActorDescription
Nominatim GeocoderConvert addresses to coordinates (and back) to get latitude/longitude for POI searches
Open Charge Map EV StationsDedicated EV charging station finder with detailed connector and network data
Google Maps Lead EnricherEnrich business leads with Google Maps data including ratings and reviews
Website Contact ScraperExtract contact details from POI websites found in search results
IP Geolocation LookupGet geographic coordinates from IP addresses to use as search centers

Changelog

  • 1.0 -- Initial release with 13 built-in categories, custom OSM tag support, Haversine distance calculation, and automatic Overpass API retry logic.

How it works

01

Configure

Set your parameters in the Apify Console or pass them via API.

02

Run

Click Start, trigger via API, webhook, or set up a schedule.

03

Get results

Download as JSON, CSV, or Excel. Integrate with 1,000+ apps.

Use cases

Sales Teams

Build targeted lead lists with verified contact data.

Marketing

Research competitors and identify outreach opportunities.

Data Teams

Automate data collection pipelines with scheduled runs.

Developers

Integrate via REST API or use as an MCP tool in AI workflows.

Ready to try OpenStreetMap POI Search?

Start for free on Apify. No credit card required.

Open on Apify Store