# OpenStreetMap Places & Business Finder (`grit-77/osm-places`) Actor

OpenStreetMap places and business finder using Overpass. Export mapped names, categories, coordinates, addresses and contact fields as JSON where supplied, with attribution.

- **URL**: https://apify.com/grit-77/osm-places.md
- **Developed by:** [Grit](https://apify.com/grit-77) (community)
- **Categories:** Lead generation, Travel
- **Stats:** 3 total users, 2 monthly users, 88.9% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.30 / 1,000 places

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 Places & Business Finder

OpenStreetMap places scraper returns mapped businesses and other places from the Overpass API. OpenStreetMap places API results include names, categories, coordinates, addresses, contact details, and attribution when the source provides them.

### Input example

```json
{
  "bbox": "52.515,13.385,52.522,13.4",
  "tags": [
    "amenity=restaurant"
  ],
  "maxItems": 15
}
```

The input keys and allowed values follow [input_schema.json](.actor/input_schema.json).

### Output fields

| Field | Type | Example or excerpt from sample |
|---|---|---|
| `attribution` | string | `"© OpenStreetMap contributors"` |
| `attribution_url` | string | `"https://www.openstreetmap.org/copyright"` |
| `license` | string | `"ODbL-1.0"` |
| `license_url` | string | `"https://opendatacommons.org/licenses/odbl/1-0/"` |
| `source` | string | `"OpenStreetMap / Overpass API"` |
| `status` | string | `"ok"` |
| `name` | string | `"Bocca di Bacco"` |
| `category` | string | `"amenity=restaurant"` |
| `category_key` | string | `"amenity"` |
| `category_value` | string | `"restaurant"` |
| `address` | string or null | `"167;168, Friedrichstraße, 10117, Berlin, DE"` |
| `lat` | number | `52.5151119` |
| `lon` | number | `13.3889084` |
| `coordinate_source` | string | `"node"` |
| `osm_type` | string | `"node"` |
| `osm_id` | integer | `86001794` |
| `osm_url` | string | `"https://www.openstreetmap.org/node/86001794"` |
| `opening_hours` | string or null | `"Mo-Sa 12:00-24:00"` |
| `query_city` | string or null | `null` |
| `retrieved_at` | string | `"2026-10-05T13:47:20.558187+00:00"` |
| `errors` | array | `[]` |
| `house_number` | string or null | `"167;168"` |
| `street` | string or null | `"Friedrichstraße"` |
| `place` | string or null | `null` |
| `postcode` | string or null | `"10117"` |
| `city` | string or null | `"Berlin"` |
| `suburb` | string or null | `"Mitte"` |
| `district` | string or null | `null` |
| `state` | string or null | `null` |
| `country` | string or null | `"DE"` |
| `phone` | string or null | `"+49 30 20672828"` |
| `website` | string or null | `"http://www.boccadibacco.de/"` |
| `email` | string or null | `"info@boccadibacco.de"` |

### Output example

Trimmed from [sample_output.json](sample_output.json); omitted fields remain available in the dataset.

```json
{
  "attribution": "© OpenStreetMap contributors",
  "attribution_url": "https://www.openstreetmap.org/copyright",
  "license": "ODbL-1.0",
  "license_url": "https://opendatacommons.org/licenses/odbl/1-0/",
  "source": "OpenStreetMap / Overpass API",
  "status": "ok",
  "name": "Bocca di Bacco"
}
```

### Attribution and license

Data: **© OpenStreetMap contributors**, available under the [Open Database License 1.0](https://opendatacommons.org/licenses/odbl/1-0/). Each result and diagnostic row carries attribution and license links. Preserve these fields and display contributor credit when using or sharing results. Derived databases may have share-alike obligations; consult the [OpenStreetMap copyright and license guidance](https://www.openstreetmap.org/copyright) before redistributing data. Actor service charges do not change the data license.

### Limits and responsible use

- `maxItems` defaults to 100 and accepts 1–10,000. It caps all dataset rows, including errors, and is sent as an Overpass output limit. Reaching the cap does not prove a complete area export; there is no pagination or relevance ranking.
- Bounding-box order is **south,west,north,east**. Coordinates must be finite and valid; each axis has a maximum span of 2 degrees. Antimeridian crossing is unsupported. Broad area IDs or expensive filters can still exceed server resources even with a small output cap.
- Concurrency is fixed at 1. The next request waits at least `minDelaySeconds` (default 10, minimum 5) after the previous request completes. One bbox/area query is sent; city lookup adds one preceding query. Up to three attempts use exponential backoff, at least 15 seconds and `Retry-After`. A cooldown exceeding 120 seconds ends the run for a later retry.
- The run uses **one endpoint**, without redirect following, proxy rotation, failover to public mirrors or tiling. The default is `https://overpass-api.de/api/interpreter`; `overpassUrl` supports your supplied HTTP/HTTPS instance and rejects embedded credentials, query parameters and fragments.
- The default public endpoint is for occasional small runs. For recurring, production or many-user use, supply and operate your own Overpass endpoint. Per-run limits do not coordinate traffic across separate runs; schedule those conservatively. Follow the [Overpass usage policy](https://dev.overpass-api.de/overpass-doc/en/preface/commons.html), including its guidance against using public instances as an application's sustained backend. Do not assemble planet-scale exports from boxes.
- A response download is capped at 32 MiB. Server timeout is 10–120 seconds (default 60), with a 128 MiB declared server memory bound. These bound an individual query, not total source coverage. A runtime-error remark or invalid response is treated as incomplete, not as successful places.
- Malformed objects produce uncharged error rows; other valid objects continue. A failed source query produces an attributed error row and fails the run so automation can distinguish failure from a genuinely empty result.
- OSM coverage varies. Missing phone/email/opening hours remain missing; POIs can be outdated, unnamed or repeated as different OSM objects. A matched amenity tag does not necessarily represent a business.

### FAQ

**What are the output limits?** `maxItems` caps places and diagnostics. Coverage depends on mapped features and Overpass availability.

**Do I need a proxy or login?** Public Overpass requests need no login or proxy. Use an endpoint you are permitted to query.

**How is this priced?** Proposed pay per event: $0.0003 for each unique `place` row. Diagnostics and duplicates are uncharged. These are proposals in [PRICING.md](PRICING.md); the owner must configure Store billing.

**How are rate limits handled?** The code uses one concurrent Overpass request and `minDelaySeconds` between attempts; throttled responses use backoff and `Retry-After`.

**How fresh is the data?** OpenStreetMap data is community maintained. `retrieved_at` marks collection time; names, contact details, and opening hours may be missing or outdated. Retain the OSM attribution and follow the ODbL terms when reusing data.

### Use with AI agents / MCP

After the actor is published, connect your agent to the [Apify MCP server](https://docs.apify.com/integrations/mcp) with an Apify API token. Use `call-actor` with the published actor identifier and the JSON input shown above. Read the returned dataset with `get-dataset-items`; the run response itself contains status and storage IDs, not the result rows. Alternatively, use the [Apify API](https://docs.apify.com/api/v2) to start a run and read its default dataset. Keep the actor input bounded with `maxItems`, and inspect source links and any error fields before using results in an answer.

# Actor input Schema

## `city` (type: `string`):

Exact OpenStreetMap administrative boundary name (for example Berlin). Choose exactly one of city, areaId or bbox. Ambiguous names fail clearly; use countryCode or areaId.

## `countryCode` (type: `string`):

Optional two-letter ISO code such as DE or TR. Only use with city. Names are matched exactly; no geocoder is used.

## `areaId` (type: `integer`):

Choose instead of city or bbox. An OSM relation ID plus 3600000000, e.g. Berlin relation 62422 becomes 3600062422. Only existing Overpass areas are supported.

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

Choose instead of city or areaId. Example: 52.515,13.385,52.522,13.4. Maximum span 2 degrees per axis; antimeridian crossing is unsupported.

## `tags` (type: `array`):

Exact key=value filters or key existence. Examples: amenity=restaurant, shop=supermarket, office, healthcare=clinic. Filters are ORed. No raw Overpass code, regex or wildcards. At most 20 filters.

## `maxItems` (type: `integer`):

Hard cap on dataset rows, including diagnostic rows. Also limits the Overpass output. Sorting follows OSM object type and ID; no relevance ranking or pagination.

## `concurrency` (type: `integer`):

Must be 1. Requests and retries are always sequential on the selected endpoint.

## `minDelaySeconds` (type: `integer`):

Completion-to-next-query delay within a run. Retries use at least 15 seconds with exponential backoff. Separate actor runs must also be scheduled conservatively.

## `timeoutSeconds` (type: `integer`):

Declared server query timeout. Use smaller areas if the endpoint rejects resource demand.

## `overpassUrl` (type: `string`):

One endpoint per run; no instance rotation or redirects. For recurring or production workloads supply your own Overpass instance. Credentials, query strings and fragments are rejected. HTTP is supported for your supplied instance; prefer HTTPS.

## `includeTags` (type: `boolean`):

Include the full published tag dictionary. Default output includes only the documented business fields.

## Actor input object example

```json
{
  "city": "Berlin",
  "countryCode": "DE",
  "tags": [
    "amenity",
    "shop",
    "office"
  ],
  "maxItems": 100,
  "concurrency": 1,
  "minDelaySeconds": 10,
  "timeoutSeconds": 60,
  "overpassUrl": "https://overpass-api.de/api/interpreter",
  "includeTags": false
}
```

# Actor output Schema

## `dataset` (type: `string`):

Place records and uncharged diagnostic rows from this run.

# 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 = {
    "city": "Berlin",
    "countryCode": "DE"
};

// Run the Actor and wait for it to finish
const run = await client.actor("grit-77/osm-places").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 = {
    "city": "Berlin",
    "countryCode": "DE",
}

# Run the Actor and wait for it to finish
run = client.actor("grit-77/osm-places").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 '{
  "city": "Berlin",
  "countryCode": "DE"
}' |
apify call grit-77/osm-places --silent --output-dataset

```

## MCP server setup

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

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/U0ClE4ePRgLUJ01t2/builds/1g4EhFSBOKJlywbIo/openapi.json
