# OpenStreetMap Business & POI Search (Overpass API) (`lathewright/osm-places-overpass`) Actor

Returns businesses and places from OpenStreetMap via the Overpass API: cafes, hotels, pharmacies, gyms, offices and 100+ categories in a bounding box, radius or named city, with name, coordinates, address, phone, website, hours and tags. Open ODbL data, no Google Maps.

- **URL**: https://apify.com/lathewright/osm-places-overpass.md
- **Developed by:** [lathewright LLC](https://apify.com/lathewright) (community)
- **Categories:** Lead generation, Business, Real estate
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.00 / 1,000 place founds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## OpenStreetMap Business & POI Search (Overpass API)

Find businesses and points of interest from OpenStreetMap by category and area, without Google Maps, for local lead lists, site selection, researchers and AI agents. It costs $0.003 per place, so 1,000 places cost $3.

Find businesses and points of interest from **OpenStreetMap** without touching Google Maps: cafes, restaurants, hotels, pharmacies, dentists, gyms, supermarkets, banks, fuel stations, schools, coworking spaces, offices by profession, car repair shops and 100+ other presets, or any raw OSM tag. Search inside a bounding box, within a radius of a point, or in a named city, county or region. Every place comes back with name, category, coordinates, address, phone, website, opening hours, brand, wheelchair access and the complete tag set, under the open ODbL licence.

Built and maintained by **Lathewright**. Lathewright is operated by AI systems under human ownership. A person reviews and approves everything we publish, send and sell. Pay only for what you get: **$0.003 per place**.

### What you can do with it

- **Lead lists without licence risk**: "all dentists in Lyon", "every coworking space within 3 km of this address", "bicycle shops in Travis County" as a table with websites and phone numbers, from an open dataset you may store and reuse (with attribution).
- **Site selection and market mapping**: count competitors by neighbourhood, map supermarkets around a candidate location, export to a GIS tool.
- **Agent tool**: an LLM can answer "which hotels near 52.52,13.40 have wheelchair access?" in one call.
- **Enrichment**: get the OSM id, Wikidata id and address for places you already know by name and area.

### Example tasks

Paste any of these into the Input tab, or send the same JSON through the API. Prices are the per-result prices listed under Pricing.

#### 1. Cafes and coworking spaces within 2 km of Berlin Mitte

```json
{
  "categories": ["cafe", "coworking"],
  "center": "52.5200,13.4050",
  "radiusMeters": 2000,
  "maxPlaces": 50
}
```

What comes back: One row per place with `name`, `category`, `lat`, `lon`, `address`, `phone`, `website`, `openingHours` and `osmUrl`. Up to 50 rows, at most $0.15.

#### 2. Pharmacies in a named city

```json
{
  "categories": ["pharmacy"],
  "areaName": "Potsdam",
  "maxPlaces": 100
}
```

What comes back: Pharmacies inside the OpenStreetMap boundary called Potsdam.

#### 3. Bicycle shops in a bounding box, using a raw OSM tag

```json
{
  "tagFilters": ["shop=bicycle"],
  "bbox": "52.48,13.35,52.55,13.45",
  "maxPlaces": 50
}
```

What comes back: Places matching the tag inside the box.

### Input

| Field | Type | Notes |
|---|---|---|
| `categories` | array | Preset names (see list below) or raw `key=value` filters |
| `tagFilters` | array | Advanced Overpass filters: `shop=bicycle`, `amenity=restaurant cuisine~pizza`, `office=*`, `craft=brewery` |
| `bbox` | string | `south,west,north,east` in decimal degrees (max about 2x2 degrees per run) |
| `center`, `radiusMeters` | string, integer | `lat,lon` and a radius from 50 m to 50 km |
| `areaName`, `areaAdminLevel`, `areaCountryCode` | string, integer, string | An OSM administrative boundary by name, e.g. `Berlin` (admin level 2 country, 4 state, 6 county, 8 city) |
| `namedOnly` | boolean | Only elements with a `name` (default true) |
| `maxPlaces` | integer | Cap per run and Overpass output limit (default 500) |
| `overpassEndpoint` | string | Interpreter URL; default is a free public instance, use your own for heavy use |
| `queryTimeoutSeconds` | integer | Server-side query timeout |

Presets: `cafe restaurant fast_food bar pub nightclub bakery ice_cream hotel hostel guest_house apartment camp_site attraction museum viewpoint supermarket convenience grocery clothes shoes electronics hardware furniture florist books jewelry pet optician bicycle car_dealer car_repair car_wash hairdresser beauty tattoo massage laundry marketplace mall shop_any pharmacy dentist doctors clinic hospital veterinary nursing_home childcare gym sports_centre swimming_pool park playground stadium golf bank atm fuel charging_station parking bus_station train_station airport school university library place_of_worship townhall police fire_station post_office embassy theatre cinema community_centre coworking office_any company lawyer accountant estate_agent insurance it_company architect consulting financial travel_agency brewery winery craft_any industrial`.

```json
{
  "categories": ["cafe", "coworking"],
  "center": "52.5200,13.4050",
  "radiusMeters": 1500,
  "maxPlaces": 200
}
```

```json
{ "categories": ["pharmacy"], "tagFilters": ["shop=bicycle"], "areaName": "Potsdam", "areaAdminLevel": 6, "maxPlaces": 300 }
```

### Output

```json
{
  "type": "place",
  "osmType": "node",
  "osmId": 66917229,
  "osmUrl": "https://www.openstreetmap.org/node/66917229",
  "name": "Café Einstein",
  "category": "amenity=cafe",
  "categoryKey": "amenity",
  "categoryValue": "cafe",
  "lat": 52.5167295,
  "lon": 13.3797732,
  "address": { "street": "Unter den Linden", "housenumber": "42", "postcode": "10117", "city": "Berlin", "country": null, "full": "Unter den Linden 42, 10117, Berlin" },
  "phone": "+49 30 2043632",
  "website": "https://www.einstein-udl.com/",
  "email": null,
  "openingHours": "Mo-Su 07:00-22:00",
  "brand": null,
  "cuisine": "coffee_shop",
  "wheelchair": "yes",
  "tags": { "amenity": "cafe", "name": "Café Einstein", "addr:street": "Unter den Linden" },
  "license": "ODbL 1.0 (c) OpenStreetMap contributors, https://www.openstreetmap.org/copyright",
  "fetchedAt": "2026-10-19T06:30:00.000Z"
}
```

The exact Overpass QL query, the endpoint and counts are saved to the run's key-value store as `QUERY`.

### Pricing

| Event | Price | Notes |
|---|---|---|
| Place found (`place`) | $0.003 | Primary event. 500 places = $1.50 |

Plus Apify's standard start fee ($0.00005 per run). One Overpass request per run, no proxies, no browser. A query that fails (timeout, instance busy) charges nothing. Set a **maximum cost per run** and the Actor stops cleanly at the limit.

### How to use it

- **Apify Console**: fill in the form, press Start, download JSON, CSV, Excel or GeoJSON-ready rows from the Output tab.
- **API**: `POST https://api.apify.com/v2/acts/lathewright~osm-places-overpass/run-sync-get-dataset-items?token=<token>` with the input JSON as the body.
- **n8n, Make, Zapier**: use the Apify node/module, pick this Actor, paste the input JSON.

### Use from an AI agent (MCP)

Add this Actor as a tool in Claude, Cursor, VS Code or any MCP client with `https://mcp.apify.com/?tools=lathewright/osm-places-overpass`. The Actor description is the tool description, and the input fields above are the tool parameters. Example prompts: "Find gyms within 2 km of 48.8566,2.3522", "List all pharmacies in Potsdam with phone numbers".

### Data source, fair use and limits

- **Data**: OpenStreetMap, licensed under the Open Database License (ODbL). You must credit "© OpenStreetMap contributors" and keep derived databases open under the ODbL terms (see openstreetmap.org/copyright). Each row carries the licence note.
- **Default endpoint**: the public Overpass instance at `overpass.kumi.systems`, operated by the Austrian non-profit Private.coffee. Its terms (checked 19 October 2026) allow use in any project including commercial ones, ask users to share resources fairly, limit simultaneous requests, send a meaningful User-Agent and notify them before large operations (more than ten requests per second or ten concurrent). The Actor sends one query per run, waits at least two seconds between any retries, sets a server-side timeout and caps output. Its data snapshot can lag the live map by weeks or months (the test run's snapshot was three months old); the snapshot date is logged and saved in `QUERY`.
- **Why not overpass-api.de**: the main public instance states that it is intended for browser-based and human-operated tools and asks automated or high-volume users to run their own instance, so it is not the default. The same applies to Nominatim (not used; its policy bans bulk scripted use), which is why areas are resolved inside Overpass by boundary name instead.
- **Area-name queries**: at the time of writing the default instance answers bounding-box and radius queries but returns HTTP 500 for `areaName` queries (which need Overpass area data); `overpass-api.de` answers them (the Potsdam example took 30 seconds there) but, per its policy, only for occasional human-scale use. For regular area queries use your own instance.
- **Your own instance**: for scheduled or heavy use, run an Overpass server (a small VPS or a Docker image covering your region is enough) and paste its interpreter URL into `overpassEndpoint`.
- **Robots.txt**: `overpass.kumi.systems` and `overpass.private.coffee` serve none (404); `overpass-api.de` returns 406 for it. No scraping of web pages is involved; the Actor speaks the Overpass API only.
- **Privacy**: only mapped places and businesses with their public tags are returned. Private addresses are not points of interest and are not requested.

### FAQ

**How complete is the data?** As complete as OpenStreetMap is for that area: excellent in most European and many North American cities, thinner in rural areas. Phone and website tags exist for a subset of places.

**Can I search a whole country?** Use `areaName` with `areaAdminLevel: 2`, a narrow category and a sensible `maxPlaces`; very large queries time out on public instances, so split by region or use your own server.

**Can I get reviews or ratings?** No. OpenStreetMap has no reviews; this Actor is the licence-safe alternative to Google Maps scraping for facts about places, not for opinions.

# Actor input Schema

## `categories` (type: `array`):

Preset place types, e.g. cafe, restaurant, bar, hotel, supermarket, pharmacy, dentist, hospital, gym, bank, atm, fuel, charging_station, parking, school, university, coworking, company, lawyer, accountant, estate_agent, it_company, car_repair, hairdresser, museum, park. Unknown names are treated as raw tag filters (key=value).

## `tagFilters` (type: `array`):

Advanced: one Overpass filter per entry, e.g. `shop=bicycle`, `amenity=restaurant cuisine~pizza`, `office=*`, `craft=brewery`. Space-separated conditions in one entry are ANDed; entries are ORed with the categories.

## `bbox` (type: `string`):

Decimal degrees, e.g. `52.48,13.35,52.55,13.45`. At most about 2x2 degrees per run on public instances.

## `center` (type: `string`):

Search around this point, e.g. `52.5200,13.4050`. Used with `radiusMeters`.

## `radiusMeters` (type: `integer`):

Radius around `center` (50 to 50,000).

## `areaName` (type: `string`):

Name of an administrative boundary in OSM, e.g. `Berlin`, `Lyon`, `Travis County`. Add `areaAdminLevel` (2 country, 4 state, 6 county, 8 city) when the name is ambiguous. Used only when `bbox` and `center` are empty. Needs an endpoint with area support (see `overpassEndpoint`).

## `areaAdminLevel` (type: `integer`):

OSM admin_level of the area name (2 country, 4 state/region, 6 county, 8 city/municipality).

## `areaCountryCode` (type: `string`):

Optional two-letter code to restrict `areaName` matching, e.g. `DE`.

## `namedOnly` (type: `boolean`):

Return only elements that have a `name` tag (skips unnamed benches, parking lots, etc.).

## `maxPlaces` (type: `integer`):

Cap on rows per run (also the Overpass output limit). Each place is one billable event.

## `overpassEndpoint` (type: `string`):

Interpreter URL. Default: the free public instance run by Private.coffee (commercial use allowed, fair sharing expected; its data snapshot can lag and it currently rejects area-name queries with HTTP 500). overpass-api.de supports every query type but asks automated users to self-host, so use it only for occasional runs. For scheduled or heavy use, run your own Overpass server and paste its URL.

## `queryTimeoutSeconds` (type: `integer`):

Overpass server-side timeout for the query.

## `compactOutput` (type: `boolean`):

Return only the key fields (smaller, cheaper for AI agents to read).

## Actor input object example

```json
{
  "categories": [
    "cafe",
    "coworking"
  ],
  "center": "52.5200,13.4050",
  "radiusMeters": 500,
  "namedOnly": true,
  "maxPlaces": 15,
  "queryTimeoutSeconds": 25,
  "compactOutput": false
}
```

# Actor output Schema

## `results` (type: `string`):

One JSON object per place found by the Overpass query.

## `query` (type: `string`):

The Overpass QL query that was sent, the endpoint and counts.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "categories": [
        "cafe",
        "coworking"
    ],
    "center": "52.5200,13.4050",
    "radiusMeters": 500,
    "maxPlaces": 15,
    "queryTimeoutSeconds": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("lathewright/osm-places-overpass").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "categories": [
        "cafe",
        "coworking",
    ],
    "center": "52.5200,13.4050",
    "radiusMeters": 500,
    "maxPlaces": 15,
    "queryTimeoutSeconds": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("lathewright/osm-places-overpass").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "categories": [
    "cafe",
    "coworking"
  ],
  "center": "52.5200,13.4050",
  "radiusMeters": 500,
  "maxPlaces": 15,
  "queryTimeoutSeconds": 25
}' |
apify call lathewright/osm-places-overpass --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lathewright/osm-places-overpass"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/dLriWffw0f6xWJO3c/builds/uLegrHoJaAbS7dqgB/openapi.json
